如何将用户提供的输入添加到 SQL 语句? [英] How can I add user-supplied input to an SQL statement?

查看:38
本文介绍了如何将用户提供的输入添加到 SQL 语句?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用用户提供的数据创建 SQL 语句.我在 C# 中使用了类似的代码:

I am trying to create an SQL statement using user-supplied data. I use code similar to this in C#:

var sql = "INSERT INTO myTable (myField1, myField2) " +
          "VALUES ('" + someVariable + "', '" + someTextBox.Text + "');";

var cmd = new SqlCommand(sql, myDbConnection);
cmd.ExecuteNonQuery();

在 VB.NET 中:

and this in VB.NET:

Dim sql = "INSERT INTO myTable (myField1, myField2) " &
          "VALUES ('" & someVariable & "', '" & someTextBox.Text & "');"

Dim cmd As New SqlCommand(sql, myDbConnection)
cmd.ExecuteNonQuery()

然而,

  • 当用户输入包含单引号时失败(例如 O'Brien),
  • 在插入 DateTime 值时我似乎无法正确获取格式
  • 人们一直告诉我,我不应该因为SQL 注入"而这样做.

我如何以正确的方式"做到这一点?

How do I do it "the right way"?

推荐答案

使用参数化 SQL.

示例

(这些示例在 C# 中,见下文对于 VB.NET 版本.)

(These examples are in C#, see below for the VB.NET version.)

@... 占位符替换您的字符串连接,然后将值添加到您的 SqlCommand.您可以自由选择占位符的名称,只需确保它们以 @ 符号开头.您的示例如下所示:

Replace your string concatenations with @... placeholders and, afterwards, add the values to your SqlCommand. You can choose the name of the placeholders freely, just make sure that they start with the @ sign. Your example would look like this:

var sql = "INSERT INTO myTable (myField1, myField2) " +
          "VALUES (@someValue, @someOtherValue);";

using (var cmd = new SqlCommand(sql, myDbConnection))
{
    cmd.Parameters.AddWithValue("@someValue", someVariable);
    cmd.Parameters.AddWithValue("@someOtherValue", someTextBox.Text);
    cmd.ExecuteNonQuery();
}

同样的模式用于其他类型的 SQL 语句:

The same pattern is used for other kinds of SQL statements:

var sql = "UPDATE myTable SET myField1 = @newValue WHERE myField2 = @someValue;";

// see above, same as INSERT

var sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = @someValue;";

using (var cmd = new SqlCommand(sql, myDbConnection))
{
    cmd.Parameters.AddWithValue("@someValue", someVariable);
    using (var reader = cmd.ExecuteReader())
    {
        ...
    }
    // Alternatively: object result = cmd.ExecuteScalar();
    // if you are only interested in one value of one row.
}

注意事项:AddWithValue 是一个很好的起点,并且在大多数情况下都能正常工作.但是,您传入的值需要与相应数据库字段的数据类型完全匹配.否则,您最终可能会遇到转换阻止您的查询使用索引的情况.请注意,某些 SQL Server 数据类型,例如 char/varchar(没有前面的n")或日期,没有相应的 .NET 数据类型.在这些情况下,<应使用具有正确数据类型的代码>添加.

A word of caution: AddWithValue is a good starting point and works fine in most cases. However, the value you pass in needs to exactly match the data type of the corresponding database field. Otherwise, you might end up in a situation where the conversion prevents your query from using an index. Note that some SQL Server data types, such as char/varchar (without preceding "n") or date do not have a corresponding .NET data type. In those cases, Add with the correct data type should be used instead.

我为什么要这样做?

  • It's more secure: It stops SQL injection. (Bobby Tables won't delete your student records.)

更简单:无需摆弄单引号和双引号,也无需查找日期文字的正确字符串表示形式.

It's easier: No need to fiddle around with single and double quotes or to look up the correct string representation of date literals.

它更稳定:O'Brien 不会因为他坚持保留他陌生的名字而使您的应用程序崩溃.

It's more stable: O'Brien won't crash your application just because he insists on keeping his strange name.

其他数据库访问库

  • 如果您使用 OleDbCommand 而不是 SqlCommand(例如,如果您使用的是 MS Access 数据库),请使用 ? 而不是 @...作为 SQL 中的占位符.在这种情况下,AddWithValue 的第一个参数是无关紧要的;相反,您需要以正确的顺序添加参数.OdbcCommand 也是如此.

  • If you use an OleDbCommand instead of an SqlCommand (e.g., if you are using an MS Access database), use ? instead of @... as the placeholder in the SQL. In that case, the first parameter of AddWithValue is irrelevant; instead, you need to add the parameters in the correct order. The same is true for OdbcCommand.

实体框架还支持参数化查询.

这篇关于如何将用户提供的输入添加到 SQL 语句?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆