向查询添加参数的语法
Posted
技术标签:
【中文标题】向查询添加参数的语法【英文标题】:Syntax for adding parameters to a query 【发布时间】:2017-11-03 09:30:23 【问题描述】:我在提醒自己参数化查询的语法(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 Framework 数据提供程序使用标有问号 (?) 的位置参数,而不是命名参数。
这强化了我的观点,即参数名称/语法无关紧要并且被忽略。但是,即使这是正确的,是否有一个好习惯可以为其他框架等提供更多的健壮性?
【问题讨论】:
在 OLEDB 中,参数的印记无关紧要(只要不使用保留字符),它只是定义了使用参数的样式。在查询中提供参数名称是个好主意,但实际上所有查询参数仍然从第一个声明的参数开始处理。 【参考方案1】:显然,参数化查询对于帮助防止 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 );
另请注意..您实际上并未将“@”或“:”用于命名参数。引擎会知道如何处理它们。
一切看起来都不错,但如果“参数”未找到并且它依赖于列名,为了防止出现歧义,请尝试..
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 值,但它必须位于查询中的相同序号位置才能执行。
【讨论】:
【参考方案2】:这强化了我的观点,即参数名称/语法无关紧要并被忽略。
这当然不是真的。您使用的参数前缀确实很重要,但 ODBC 在这方面稍微宽松一些,因为它必须支持很多平台。永远不要假设你可以随便扔垃圾,因为它会咬你。
您确实必须将?
用于OLE DB 中的参数。您在提供参数时给出的名称将被忽略,顺序才是最重要的。
【讨论】:
谢谢 - 您能否澄清“您确实必须使用?
用于 OLE DB 中的参数”的意思?我见过一些?
语法,但从未使用过。以上是关于向查询添加参数的语法的主要内容,如果未能解决你的问题,请参考以下文章