sql-server - 带有子查询错误的 ADO 参数化查询
问题描述
我有一个使用 SQL Server 2012 运行的旧版经典 ASP 应用程序(也使用 2016 进行了测试),我正在尝试切换到使用参数化查询。该站点的所有查询都通过一个函数运行,该函数期望将 sql 语句作为一个字符串,其中包含由问号表示的参数以及这些参数的数组。该函数当前过滤参数以使其 sql 安全,并在执行语句之前将它们放入 sql 字符串中。
鉴于此,我认为将其切换为参数化查询会非常简单。最初的测试看起来不错,一切似乎都正常工作,直到我在子查询中点击带有参数的 sql 语句。
这是一个有效的测试样本:
Const connectionString = "Provider=SQLNCLI11; Server=********; Database=********; UID=*******; PWD=*******"
Dim sql, productId, parameters
sql = "SELECT SKU FROM Products WHERE ProductId = ?"
productId = 3
parameters = Array(productId)
Dim conn
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open connectionString
Dim cmd
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandText = sql
cmd.Parameters.Refresh
Dim rs
Set rs = cmd.Execute(, parameters)
Response.Write("SKU: " & rs("SKU"))
没问题,这会按预期返回 SKU。但是,如果我使用子查询:
Const connectionString = "Provider=SQLNCLI11; Server=********; Database=********; UID=*******; PWD=*******"
Dim sql, productId, parameters
'contrived subquery for demonstration purposes
sql = "SELECT SKU FROM ( SELECT SKU FROM Products WHERE ProductId = ? ) AS P"
productId = 3
parameters = Array(productId)
Dim conn
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open connectionString
Dim cmd
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandText = sql
cmd.Parameters.Refresh
Dim rs
Set rs = cmd.Execute(, parameters)
Response.Write("SKU: " & rs("SKU"))
它在 cmd.Parameters.Refresh 行上引发错误:
Microsoft VBScript 运行时错误“0x80004005”Microsoft SQL Server Native Client 11.0 语法错误、权限冲突或其他非特定错误
如果我在第一个示例中检查 cmd.Parameters.Count,我正确地得到 1。在错误的示例中,它会引发相同的错误。
关于为什么将参数放入子查询会导致参数集合出现问题,是否有任何解释?我确实尝试手动将参数添加到参数集合中,效果很好,但这意味着修改数百个现有的 sql 调用,所以目前 cmd.Parameters.Refresh 往返是值得的。
解决方案
你可以给cmd.execute你想要的,但是我很久没用了。
cmd.execute("SELECT SKU FROM (SELECT SKU FROM Products WHERE ProductId = ?) AS P", Array(productId))
推荐阅读
- julia - 如何在 Julia 中传递 struct 的字段,然后对其进行变异而不是分配它?
- r - 如何按具有所有因素水平的受试者进行过滤?
- flutter - 颤动的新Web项目未在Android模拟器中显示
- python - OpenCV 需要 Android SDK 工具版本 14 或更新版本
- python - Pandas:根据不同数据帧的多列中的匹配值在一个数据帧中创建一列
- linux - 如何运行心跳功能
- java - 此 PDF 的幻数之前的字节顺序标记是什么?
- android - 如何在我的 Samsung A51 Android 10 的“内部存储”文件夹(主要外部存储)中创建文件?
- rust - 打印结构的值 - 出现错误,预期为 `,` 或 `}` 之一
- java - Gson 将 List 字段序列化为字符串并保留 SerializedName