当前位置:  开发笔记 > 编程语言 > 正文

如何创建参数化SQL查询?我为什么要?

如何解决《如何创建参数化SQL查询?我为什么要?》经验,为你挑选了3个好方法。

我听说"每个人"都在使用参数化SQL查询来防止SQL注入攻击,而不必为每一条用户输入进行操作.

你怎么做到这一点?使用存储过程时是否自动获得此信息?

所以我理解这是非参数化的:

cmdText = String.Format("SELECT foo FROM bar WHERE baz = '{0}'", fuz)

这会参数化吗?

cmdText = String.Format("EXEC foo_from_baz '{0}'", fuz)

或者我是否需要做更广泛的事情以保护自己免受SQL注入?

With command
    .Parameters.Count = 1
    .Parameters.Item(0).ParameterName = "@baz"
    .Parameters.Item(0).Value = fuz
End With

除安全考虑因素外,使用参数化查询还有其他优点吗?

更新:这篇伟大的文章与格罗托克的一个问题相关联. http://www.sommarskog.se/dynamic_sql.html



1> Joel Coehoor..:

您的EXEC示例不会参数化.您需要参数化查询(在某些圈子中准备好的语句)以防止这样的输入造成损害:

'; DROP TABLE栏; -

试着把它放在你的fuz变量中(或者,如果你重视吧台,那就不要).更加微妙和有害的查询也是可能的.

以下是如何使用Sql Server执行参数的示例:

Public Function GetBarFooByBaz(ByVal Baz As String) As String
    Dim sql As String = "SELECT foo FROM bar WHERE baz= @Baz"

    Using cn As New SqlConnection("Your connection string here"), _
        cmd As New SqlCommand(sql, cn)

        cmd.Parameters.Add("@Baz", SqlDbType.VarChar, 50).Value = Baz
        Return cmd.ExecuteScalar().ToString()
    End Using
End Function

存储过程有时会被用于防止SQL注入.但是,大多数情况下,您仍然需要使用查询参数调用它们,否则它们无法帮助您.如果您专门使用存储过程,那么您可以为应用程序用户帐户关闭SELECT,UPDATE,ALTER,CREATE,DELETE等权限(除了EXEC之外的所有内容),并以此方式获得一些保护.


@GavinPerkins假设你的意思是'AddWithValue("@ Baz",Baz)`,你_could_那样做,[但你不应该] [http://blogs.msmvps.com/jcoehoorn/blog/2014/05/12// can-we-stop-using-addwithvalue-already /),特别是因为将默认映射到`nvarchar`的字符串值转换为实际的`varchar`类型是可以触发该链接中提到的效果的最常见位置之一.

2> Tamas Czineg..:

绝对是最后一个,即

或者我是否需要做更广泛的......?(是cmd.Parameters.Add())

参数化查询有两个主要优点:

安全性:这是避免SQL注入漏洞的好方法

性能:如果您经常使用不同的参数调用相同的查询,则参数化查询可能允许数据库缓存您的查询,这是性能增益的重要来源.

额外:您不必担心数据库代码中的日期和时间格式问题.同样,如果您的代码将在具有非英语语言环境的计算机上运行,​​则不会出现小数点/小数点逗号的问题.



3> Andrew Hare..:

您想要使用最后一个示例,因为这是唯一真正参数化的示例.除了安全问题(这可能比您想象的要普遍得多)之外,最好让ADO.NET处理参数化,因为您无法确定传入的值是否需要单引号而不检查Type每个参数.

[编辑]这是一个例子:

SqlCommand command = new SqlCommand(
    "select foo from bar where baz = @baz",
    yourSqlConnection
);

SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "@baz";
parameter.Value = "xyz";

command.Parameters.Add(parameter);


对此非常熟悉:.Net字符串是unicode,因此默认情况下该参数将采用NVarChar.如果它真的是一个VarChar列,这可能会导致严重的性能问题.
推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有