代码之家  ›  专栏  ›  技术社区  ›  Geoffrey

参数化查询为字符串

  •  0
  • Geoffrey  · 技术社区  · 14 年前

    在我的项目中,我需要记录对我的数据库执行的所有查询。作为一个例子,我们可以使用这里的人员用户数据。在该类中,我有一个函数生成命令,其参数如下:

    Public Function SQLUpdate(ByVal conn As SqlClient.SqlConnection) As SqlClient.SqlCommand Implements IDbConnected.SQLUpdate
        Dim sqlstatement As String = "UPDATE Persons SET Active=@act, Abbreviation=@abbr, FirstName=@first, LastName=@last, " & _
                                     "Birthday=@bday, Email=@email,Tel=@tel, Fax=@fax, Registered=@reg, Admin=@adm"
        sqlstatement &= " WHERE ID=" & Me.ID
        Dim comm As New SqlClient.SqlCommand(sqlstatement, conn)
        With comm.Parameters
            .Add("@act", SqlDbType.Bit).Value = Me.Active
            .Add("@abbr", SqlDbType.VarChar).Value = Me.Abbreviation
            .Add("@first", SqlDbType.VarChar).Value = Me.FirstName
            .Add("@last", SqlDbType.VarChar).Value = Me.LastName
            .Add("@bday", SqlDbType.SmallDateTime).Value = Me.Birthday
            .Add("@email", SqlDbType.VarChar).Value = Me.Email
            .Add("@tel", SqlDbType.VarChar).Value = Me.Telephone
            .Add("@fax", SqlDbType.VarChar).Value = Me.Fax
            .Add("@reg", SqlDbType.Bit).Value = Me.Registered
            .Add("@adm", SqlDbType.Bit).Value = Me.Administrator
        End With
        Return comm
    End Function
    

    当我请求命令文本时

    comm.CommandText
    

    然后我仍然得到parametrizid查询

    更新人员集活动=@act,缩写=@abbr,FirstName=@first,LastName=@last,Birthday=@bday,Email=@Email,Tel=@Tel,Fax=@Fax,Registered=@reg,Admin=@adm WHERE ID=2

    当然,我需要用值替换参数的查询。有什么简单的方法可以做到这一点,还是我需要编写一个函数来替换它自己?

    3 回复  |  直到 14 年前
        1
  •  7
  •   Marc Gravell    14 年前

    查询向下转到服务器 以参数为参数 (这有助于安全性和查询计划的重用)。所以你不需要你存在的东西,所以它不存在。

    就我个人而言 不会 替换它们,即使是在日志记录时;我只需在日志记录时附加名称/值对,即日志如下:

    更新人员集活动=@act,缩写=@abbr,FirstName=@first,LastName=@last,生日=@bday,电子邮件=@Email,电话=@Tel,传真=@Fax,注册=@reg,管理员=@adm其中ID=2 | |@act=1@abbr=mjg@first=Fred。。。

        2
  •  1
  •   Joel Coehoorn    14 年前

    你寻找的字符串不存在。在任何时候,.Net运行时或sql server都不会将您的值直接替换为查询文本。只是没有发生。这是参数化查询的全部要点;将(潜在危险的)数据参数与代码分开。

    如果你想要这个字符串,你必须自己构建它;构建这个字符串的行为应该说明为什么这是错误的:想想要在值中替换的代码是什么样子的,然后想象一个愤怒的用户输入了这个值 ';DROP TABLE Persons;-- 表示缩写或名字。考虑一下您将创建什么字符串,以及如果服务器直接执行该字符串会发生什么情况。

    如果确实要记录查询,则实际的命令使用 sp_executesql 在幕后,但你可以认为它运行的脚本更像这样:

    DECLARE @act bit; Set @act = (value from client)
    DECLARE @abbr VARCHAR(10); Set @abbr = (value from client)
    DECLARE @first VARCHAR(30); Set @first = (value from client)
    --...
    UPDATE Persons SET Active=@act, Abbreviation=@abbr, FirstName=@first
    
        3
  •  0
  •   Schenz    14 年前

    你必须编写自己的函数才能得到你想要的东西。实际发送到服务器的是带参数对象集合的参数化查询,SQL server在其中完成所有工作。

    第二个选项是在服务器上运行SQL Profiler,查看在那里执行的命令。