将 SQL Server SQL 语句注入 C# 代码的语法

Syntax for injecting SQL Server SQL statements into c# code

我有这个 c# 代码来从 SQL 服务器数据库检索数据 ADO.NET:

//Define ADO.NET objects
    string selectSQL;
    selectSQL = "SELECT * FROM slip ";
    selectSQL += "WHERE slip_id='" + txtSlipID_srch + "'";

我在一本书上读过语法,在大学里也学过语法,但除了"it's the syntax",我还没有得到解释。我说的是以下语法:

'" + txtSlipID_srch + "'

即字段名称 txtSlipID_srch 由单引号、双引号和加号绑定。

有人可以帮我解读一下吗?非常感谢。

因为您希望结果 SQL 看起来像这样:

SELECT * FROM slip WHERE slip_id='somevalue'

结果 SQL 语句中需要单引号。

双引号是在C#代码中定义字符串。 单引号用于定义 SQL 语句中的字符串。

教你这个语法的人真的教错了。
如您所料,此语法将字符串 txtSlipID_srch 的内容连接到您的 SQL 文本,从固定文本和可变部分形成完整的指令。然后将整个事情传递给数据库引擎执行。

但是允许用户在文本框中键入内容然后使用该输入来构建您的 SQL 查询确实是错误的事情

用户可以键入任何内容,并且任何内容也可能是精心伪造的字符串,它会改变您的意图并破坏您的数据库或获取您不想让他看到的信息(密码或信用卡号)。它被称为 Sql Injection and there are thousands of articles on how to implement this hacking technique. I don't want to repeat anything, you could simply look at this well known comics+question+answers 并阅读下面的解释

除此之外。存在正确解析字符串的问题。字符串变量中存在单引号会使查询无效,因为单引号用于分隔传递给数据库的字符串值。应使用转换过程将小数和日期转换为字符串也是如此。同样在这里,您应该为数据库创建正确的文本(它喜欢逗号还是小数点?日期格式是 'dd/MM/yyyy' 或 'MM/dd/yyyy' 或什么?等等)

唯一有效的方法是使用参数化查询,以这种方式编写命令文本

selectSQL = "SELECT * FROM slip WHERE slip_id=@id";

现在不再有两个字符串的串联,也没有将字符串值用单引号括起来 'escape' 它们,只有一个名为 @id 的参数占位符。

ADO.NET 库将提供适当的 类 来处理该参数,将值传递给数据库引擎,在那里它会被正确处理。

SqlCommand cmd = new SqlCommand(selectSQL, connection);
cmd.Parameters.Add("@id", SqlDbType.NVarChar).Value = txtSlipID_srch;
SqlDataReader reader = cmd.ExecuteReader();
...... 

使用单引号的原因是 SQL 期望字符串值用单引号括起来。 (如其他答案中所述)

但是 不使用字符串连接来创建 SQL 查询。您的输入可能来自用户,任何恶意用户都可以利用它。阅读 SQL Injection

你可以用更好的方式做到这一点:

使用参数

using (SqlConnection conn = new SqlConnection("connection string"))
using (SqlCommand cmd = new SqlCommand("SELECT * FROM slip WHERE slip_id=@slipID", conn))
{
    cmd.Parameters.AddWithValue("@slipID", txtSlipID_srch);//Even use .Add and specify data type
    //open connection 
    //execute command
}

using statement执行完命令后释放资源

(另外,如果你的书没有提到稍后使用 parameters,那么你最好不要那本书,从其他地方阅读)

在这种情况下,+ 是连​​接运算符。在示例中,txtSlipID_srch 是一个包含值的变量,您将该值连接到另一个字符串(即,您的 SQL 语句)。就像我想说 Hello Maarten 你今天好吗?我会写string greeting = "Hello " + yourNameVariable + " how are you today?";。因此,当 Maarten 存储在 yourNameVariable 中时,它会获取该信息并将其与其他两个字符串连接起来。请注意我还必须如何包含空格以确保正确显示字符串?但是正如每个人都指出的那样,在构建 sql 语句(它们本身只是字符串)时永远不要使用它,因为这使用户能够传入一个字符串,使他们能够对数据库执行更具破坏性的语句.