提问人:Heinzi 提问时间:2/3/2016 最后编辑:Heinzi 更新时间:7/7/2021 访问量:10770
如何将用户提供的输入添加到 SQL 语句中?
How can I add user-supplied input to an SQL statement?
问:
我正在尝试使用用户提供的数据创建 SQL 语句。我在 C# 中使用与此类似的代码:
var sql = "INSERT INTO myTable (myField1, myField2) " +
"VALUES ('" + someVariable + "', '" + someTextBox.Text + "');";
var cmd = new SqlCommand(sql, myDbConnection);
cmd.ExecuteNonQuery();
这在 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注入”而这样做。
我如何“以正确的方式”做到这一点?
答:
使用参数化 SQL。
例子
(这些示例是用 C# 编写的,请参阅下面的 VB.NET 版本。
将字符串连接替换为占位符,然后将值添加到 SqlCommand。您可以自由选择占位符的名称,只需确保它们以符号开头即可。您的示例如下所示:@...
@
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 语句也使用相同的模式:
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.
}
注意:这是一个很好的起点,在大多数情况下效果很好。但是,传入的值需要与相应数据库字段的数据类型完全匹配。否则,您最终可能会遇到转换阻止查询使用索引的情况。请注意,某些 SQL Server 数据类型(如 char/varchar(前面不带“n”)或 date)没有相应的 .NET 数据类型。在这些情况下,应改用具有正确数据类型的 Add
。AddWithValue
我为什么要这样做?
这更简单:无需摆弄单引号和双引号,也无需查找日期文字的正确字符串表示形式。
它更稳定:不会因为他坚持保留他奇怪的名字而使您的应用程序崩溃。
O'Brien
其他数据库访问库
如果使用 OleDbCommand 而不是 SqlCommand(例如,如果您使用的是 MS Access 数据库),请在 SQL 中用作占位符。在这种情况下,第一个参数是无关紧要的;相反,您需要按正确的顺序添加参数。OdbcCommand 也是如此。
?
@...
AddWithValue
评论
cmd.ExecuteNonQuery()
VB.NET 示例代码
这是 vb.net 中 wiki 答案的示例代码,假设 和 。Option Strict On
Option Infer On
插入
Dim sql = "INSERT INTO myTable (myField1, myField2) " &
"VALUES (@someValue, @someOtherValue);"
Using cmd As New SqlCommand(sql, myDbConnection)
cmd.Parameters.AddWithValue("@someValue", someVariable)
cmd.Parameters.AddWithValue("@someOtherValue", someTextBox.Text)
cmd.ExecuteNonQuery()
End Using
更新
Dim sql = "UPDATE myTable SET myField1 = @newValue WHERE myField2 = @someValue;"
' see above, same as INSERT
选择
Dim sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = @someValue;"
Using cmd As New SqlCommand(sql, myDbConnection)
cmd.Parameters.AddWithValue("@someValue", someVariable)
Using reader = cmd.ExecuteReader()
' ...
End Using
' Alternatively: Dim result = cmd.ExecuteScalar()
' if you are only interested in one value of one row.
End Using
评论