如何将用户提供的输入添加到SQL语句中?

时间:2016-02-02 20:39:32

标签: c# sql vb.net ado.net sql-injection

我正在尝试使用用户提供的数据创建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注入"。

我该怎么做?#34;正确的方式"?

2 个答案:

答案 0 :(得分:50)

使用参数化SQL。

<强>实施例

(这些示例在C#中,see below用于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.
}

提醒一句:AddWithValue是一个很好的起点,在大多数情况下都可以正常使用。但是,传入的值需要与相应数据库字段的数据类型完全匹配。否则,您最终可能会遇到转换阻止您using an index查询的情况。请注意,某些SQL Server数据类型(如char / varchar(不包含&#34; n&#34;)或日期)没有相应的.NET数据类型。在这些情况下,Add with the correct data type should be used instead

我为什么要这样做?

其他数据库访问库

答案 1 :(得分:2)

VB.NET示例代码

这是wiki answer的示例代码,假设Option Strict OnOption 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