向查询添加参数的语法
Syntax for adding parameters to a query
我提醒自己参数化查询的语法(C# OleDB 库),我偶然发现的前几个示例很简单,但我注意到了一些语法:
sqlCommand.CommandText = "SELECT * FROM Customer WHERE Name LIKE @Name;";
sqlCommand.Parameters.AddWithValue("@Name", "%" + searchString + "%");
我注意到 SQL 用于标识将用参数替换的内容的格式与我通常使用的格式不同。我通常使用冒号和方括号:
sqlCommand.CommandText = "SELECT * FROM Customer WHERE [Name] LIKE :Name;";
sqlCommand.Parameters.AddWithValue(":Name", "%" + searchString + "%");
现在,我看到的带有“@”的两个示例来自 sql-server 示例,我通常只使用 Access 和 Oracle。但我也看到了其他使用“@”的访问示例。
它真的有什么不同,还是只是一种风格?我记得(至少使用访问)引擎忽略了参数名称,只是按照列出的顺序插入参数。
我从 MSDN 中注意到:
The OLE DB.NET Framework Data Provider uses positional parameters that are marked with a question mark (?) instead of named parameters.
这强化了我的观点,即参数名称/语法无关紧要并被忽略。然而,即使这是正确的,是否有一个好的习惯可以为其他框架等提供更多的健壮性?
This reinforces my view that the parameter name / syntax doesn't matter and is ignored.
这当然不是真的。您使用的参数前缀确实很重要,但 ODBC 在这方面要宽松一些,因为它必须支持很多平台。永远不要假设你可以随便扔垃圾,因为它会咬你。
您确实必须使用 ?
作为 OLE DB 中的参数。您在提供参数时给出的名称将被忽略,顺序才是最重要的。
显然,参数化查询对于帮助防止 sql 注入很重要。不同的数据库使用不同的结构来使用参数。例如 SQL-Server 使用“@”作为参数的占位符,但确实允许命名参数...同样,其他人也可以使用“:”作为命名占位符。但是,对于 OleDB,它使用单个“?”作为占位符并且未命名。因此,您必须按照它们在查询命令中表示的准确顺序添加参数。
此外,我发现使用 NAMED 参数时的实例,如果您有一个列和相同的参数,它可能无法按预期工作,因为数据库可能会按列自行解析 -- 这不是预期的目的。使用一些前缀(或后缀)重命名参数以帮助阐明。这样的例子可能是..
sqlCommand.CommandText = "update MyCustomerTable set email = @email where customerID = @customerID";
sqlCommand.Parameters.AddWithValue("email", "someValue@anywhere.com");
sqlCommand.Parameters.AddWithValue("customerID", someIDValue );
另请注意.. 您实际上并没有为命名参数包含“@”或“:”。引擎将知道如何处理它们。
一切看起来都不错,但是为了防止在找不到 "parameter" 时出现歧义并且它返回到列名,请尝试..
sqlCommand.CommandText = "update MyCustomerTable set email = @parmEmail where customerID = @parmCustomerID";
sqlCommand.Parameters.AddWithValue("parmEmail", "someValue@anywhere.com");
sqlCommand.Parameters.AddWithValue("parmCustomerID", someIDValue );
这样就不会混淆了。
现在,回到“?”占位符。如果您有一个多次应用的参数值,则需要为每个实例添加该参数。如果允许命名参数,你可能会逃脱..
sqlCommand.CommandText =
@"update SomeTable
set Rate1 = Rate1 * @newRateFactor,
Rate2 = Rate2 * @newRateFactor";
sqlCommand.Parameters.AddWithValue("newRateFactor", 1.15);
请注意,只需要一个命名参数...但是对于“?”,您必须每次都添加它
sqlCommand.CommandText =
@"update SomeTable
set Rate1 = Rate1 * ?,
Rate2 = Rate2 * ?";
sqlCommand.Parameters.AddWithValue("ratePlaceHolder1", 1.15);
sqlCommand.Parameters.AddWithValue("ratePlaceHolder2", 1.15);
当所有列名都有一堆参数时,执行 sql 插入和更新之类的操作也会变得棘手。您仍然可以给参数 NAME 值,但它必须在执行的查询中处于相同的顺序位置。
我提醒自己参数化查询的语法(C# OleDB 库),我偶然发现的前几个示例很简单,但我注意到了一些语法:
sqlCommand.CommandText = "SELECT * FROM Customer WHERE Name LIKE @Name;";
sqlCommand.Parameters.AddWithValue("@Name", "%" + searchString + "%");
我注意到 SQL 用于标识将用参数替换的内容的格式与我通常使用的格式不同。我通常使用冒号和方括号:
sqlCommand.CommandText = "SELECT * FROM Customer WHERE [Name] LIKE :Name;";
sqlCommand.Parameters.AddWithValue(":Name", "%" + searchString + "%");
现在,我看到的带有“@”的两个示例来自 sql-server 示例,我通常只使用 Access 和 Oracle。但我也看到了其他使用“@”的访问示例。
它真的有什么不同,还是只是一种风格?我记得(至少使用访问)引擎忽略了参数名称,只是按照列出的顺序插入参数。
我从 MSDN 中注意到:
The OLE DB.NET Framework Data Provider uses positional parameters that are marked with a question mark (?) instead of named parameters.
这强化了我的观点,即参数名称/语法无关紧要并被忽略。然而,即使这是正确的,是否有一个好的习惯可以为其他框架等提供更多的健壮性?
This reinforces my view that the parameter name / syntax doesn't matter and is ignored.
这当然不是真的。您使用的参数前缀确实很重要,但 ODBC 在这方面要宽松一些,因为它必须支持很多平台。永远不要假设你可以随便扔垃圾,因为它会咬你。
您确实必须使用 ?
作为 OLE DB 中的参数。您在提供参数时给出的名称将被忽略,顺序才是最重要的。
显然,参数化查询对于帮助防止 sql 注入很重要。不同的数据库使用不同的结构来使用参数。例如 SQL-Server 使用“@”作为参数的占位符,但确实允许命名参数...同样,其他人也可以使用“:”作为命名占位符。但是,对于 OleDB,它使用单个“?”作为占位符并且未命名。因此,您必须按照它们在查询命令中表示的准确顺序添加参数。
此外,我发现使用 NAMED 参数时的实例,如果您有一个列和相同的参数,它可能无法按预期工作,因为数据库可能会按列自行解析 -- 这不是预期的目的。使用一些前缀(或后缀)重命名参数以帮助阐明。这样的例子可能是..
sqlCommand.CommandText = "update MyCustomerTable set email = @email where customerID = @customerID";
sqlCommand.Parameters.AddWithValue("email", "someValue@anywhere.com");
sqlCommand.Parameters.AddWithValue("customerID", someIDValue );
另请注意.. 您实际上并没有为命名参数包含“@”或“:”。引擎将知道如何处理它们。
一切看起来都不错,但是为了防止在找不到 "parameter" 时出现歧义并且它返回到列名,请尝试..
sqlCommand.CommandText = "update MyCustomerTable set email = @parmEmail where customerID = @parmCustomerID";
sqlCommand.Parameters.AddWithValue("parmEmail", "someValue@anywhere.com");
sqlCommand.Parameters.AddWithValue("parmCustomerID", someIDValue );
这样就不会混淆了。
现在,回到“?”占位符。如果您有一个多次应用的参数值,则需要为每个实例添加该参数。如果允许命名参数,你可能会逃脱..
sqlCommand.CommandText =
@"update SomeTable
set Rate1 = Rate1 * @newRateFactor,
Rate2 = Rate2 * @newRateFactor";
sqlCommand.Parameters.AddWithValue("newRateFactor", 1.15);
请注意,只需要一个命名参数...但是对于“?”,您必须每次都添加它
sqlCommand.CommandText =
@"update SomeTable
set Rate1 = Rate1 * ?,
Rate2 = Rate2 * ?";
sqlCommand.Parameters.AddWithValue("ratePlaceHolder1", 1.15);
sqlCommand.Parameters.AddWithValue("ratePlaceHolder2", 1.15);
当所有列名都有一堆参数时,执行 sql 插入和更新之类的操作也会变得棘手。您仍然可以给参数 NAME 值,但它必须在执行的查询中处于相同的顺序位置。