【问题标题】:Parametrized query as String参数化查询为字符串
【发布时间】:2010-11-15 15:07:31
【问题描述】:

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

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

然后我仍然得到参数查询

UPDATE Persons SET Active=@act, Abbreviation=@abbr, FirstName=@first, LastName=@last, Birthday=@bday, Email=@email,Tel=@tel, Fax=@fax, Registered=@reg , 管理员=@adm WHERE ID=2

当然,我需要将参数替换为值的查询。有没有一种简单的方法可以做到这一点,还是我需要编写一个自行替换的函数?

【问题讨论】:

    标签: .net sql vb.net


    【解决方案1】:

    查询下到服务器将参数作为参数(这有助于安全性和查询计划的重用)。所以你要求的东西没有必要存在 - 因此它没有。

    我个人不会替换它们,即使在记录时也是如此;我会在记录时简单地附加名称/值对,即记录如下内容:

    UPDATE Persons SET Active=@act, Abbreviation=@abbr, FirstName=@first, LastName=@last, Birthday=@bday, Email=@email,Tel=@tel, Fax=@fax, Registered=@reg , 管理员=@adm 其中 ID=2 || @act=1 @abbr=mjg @first=Fred ...

    【讨论】:

    • +1 绝对保持参数化。补充一点,将输出以读取运行的形式用于 SSMS 会很方便 - 所以我之前刚刚编写了一个方法,该方法将使用每个参数的 DECLARE 语句(正确键入)适当地序列化命令,并且然后在实际命令文本之前设置这些变量。意味着您可以将其从日志文件中直接复制粘贴到 SSMS 中
    • 因为这个问题纯粹是为了记录目的,我将接受你的建议,将它们附加到字符串中。我想我让事情变得比他们应该做的更困难。谢谢!
    【解决方案2】:

    您要查找的字符串不存在。 .Net 运行时或 sql 服务器绝不会将您的值直接替换为查询文本。它只是不会发生。这是参数化查询的重点;将(潜在危险的)数据参数与代码分开。

    如果你想要这个字符串,你必须自己构建它;构建字符串的行为应该说明为什么这是错误的:想想在值中替换的代码是什么样的,然后想象一个愤怒的用户输入值';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】:

    您必须编写自己的函数才能获得所需的内容。实际发送到服务器的是带有参数对象集合的参数化查询,SQL Server 在那里完成所有工作。

    第二种选择是在服务器上运行 SQL Profiler 以查看那里正在执行的命令。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多