向查询添加参数的语法

时间:2017-11-03 09:30:24

标签: c# oledb

我在提醒自己参数化查询的语法(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注意到:

  

OLE DB.NET框架数据提供程序使用标有问号(?)而不是命名参数的位置参数。

这强化了我的观点,即参数名称/语法并不重要并被忽略。但是,即使这是正确的,是否有一个良好的习惯,为其他框架等提供更强大的稳健性?

2 个答案:

答案 0 :(得分:1)

显然,参数化查询对于帮助防止sql注入非常重要。不同的数据库使用不同的构造来使用参数。例如,SQL-Server使用“@”作为参数的占位符,但是DOES允许命名参数......同样,其他人也可以使用“:”作为命名占位符。但是,使用OleDB,它使用单个“?”作为占位符而未命名。因此,您必须按照查询命令中的确切顺序添加参数。

此外,我在使用NAMED参数时找到了实例,如果您有一个列和参数相同,它可能无法按预期工作,因为数据库可能由列自行解析 - 这不是预期的目的。使用一些前缀(或后缀)重命名参数以帮助澄清。这样的例子可能是..

sqlCommand.CommandText = "update MyCustomerTable set email = @email where customerID = @customerID";

sqlCommand.Parameters.AddWithValue("email", "someValue@anywhere.com");
sqlCommand.Parameters.AddWithValue("customerID", someIDValue );

另请注意..您实际上并未在命名参数中包含“@”或“:”。引擎将知道如何处理它们。

一切看起来都不错,但是如果找不到“参数”并且它落在列名上,为了防止出现歧义,请尝试..

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值,但它必须位于查询中的相同序号位置才能执行。

答案 1 :(得分:0)

  

这加强了我的观点,即参数名称/语法并不重要并被忽略。

这当然不是真的。您正在使用的参数前缀很重要,但ODBC更加放松,因为它必须支持许多平台。永远不要假设你可以扔掉任何垃圾,因为它会咬你。

您确实必须在OLE DB中使用?参数。您在提供参数时给出的名称将被忽略,顺序就是重要的。