带有子查询错误的 ADO 参数化查询
ADO Parameterized Queries with Subqueries Error
我有一个传统的经典 ASP 应用程序 运行 SQL Server 2012(也在 2016 中测试过),我正在尝试切换到使用参数化查询。该站点的所有查询 运行 都通过一个函数进行,该函数需要一个 sql 语句作为一个字符串,其参数由问号以及这些参数的数组表示。该函数目前过滤参数使它们sql安全并在执行语句之前将它们放入sql字符串
鉴于此,我认为将其切换为参数化查询会非常简单。初始测试看起来不错,并且一切似乎都正常工作,直到我在子查询中使用带参数的 sql 语句。
这是有效的测试示例:
Const connectionString = "Provider=SQLNCLI11; DataTypeCompatibility=80; 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"))
没问题,这个 returns SKU 符合预期。但是,如果我使用子查询:
Const connectionString = "Provider=SQLNCLI11; DataTypeCompatibility=80; Server=********; Database=********; UID=*******; PWD=*******"
Dim sql, productId, parameters
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”
微软 SQL 服务器本机客户端 11.0
语法错误、权限违规或其他非特定错误
如果我在第一个样本中检查 cmd.Parameters.Count,我会正确地得到 1。在错误的样本中它会抛出同样的错误。
是否有任何解释为什么将参数放入子查询会导致参数集合出现问题?我确实尝试手动将参数添加到 Parameters 集合中,效果很好,但这意味着修改数百个现有的 sql 调用,所以目前 cmd.Parameters.Refresh 往返是值得的。
你给cmd.execute你想要的,我好久没用了
cmd.execute("SELECT SKU FROM ( SELECT SKU FROM Products WHERE ProductId = ? ) AS P", Array(productId))
对于可能偶然发现此问题的任何人,感谢 co-worker,我终于解决了这个问题。事实证明代码没有问题,而是连接字符串出了问题。我以某种方式将其排除在示例代码之外,但我的连接字符串包含“DataTypeCompatability=80”。如果存在,代码将抛出错误。但是,如果我删除它,错误将不再发生,并且我得到了怀疑的结果。
我对 this KB article on using ADO with the native client 的理解是应该包含 DataTypeCompatability 以确保更新的数据类型正常工作,但到目前为止我没有发现删除它有任何问题。
我有一个传统的经典 ASP 应用程序 运行 SQL Server 2012(也在 2016 中测试过),我正在尝试切换到使用参数化查询。该站点的所有查询 运行 都通过一个函数进行,该函数需要一个 sql 语句作为一个字符串,其参数由问号以及这些参数的数组表示。该函数目前过滤参数使它们sql安全并在执行语句之前将它们放入sql字符串
鉴于此,我认为将其切换为参数化查询会非常简单。初始测试看起来不错,并且一切似乎都正常工作,直到我在子查询中使用带参数的 sql 语句。
这是有效的测试示例:
Const connectionString = "Provider=SQLNCLI11; DataTypeCompatibility=80; 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"))
没问题,这个 returns SKU 符合预期。但是,如果我使用子查询:
Const connectionString = "Provider=SQLNCLI11; DataTypeCompatibility=80; Server=********; Database=********; UID=*******; PWD=*******"
Dim sql, productId, parameters
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” 微软 SQL 服务器本机客户端 11.0 语法错误、权限违规或其他非特定错误
如果我在第一个样本中检查 cmd.Parameters.Count,我会正确地得到 1。在错误的样本中它会抛出同样的错误。
是否有任何解释为什么将参数放入子查询会导致参数集合出现问题?我确实尝试手动将参数添加到 Parameters 集合中,效果很好,但这意味着修改数百个现有的 sql 调用,所以目前 cmd.Parameters.Refresh 往返是值得的。
你给cmd.execute你想要的,我好久没用了
cmd.execute("SELECT SKU FROM ( SELECT SKU FROM Products WHERE ProductId = ? ) AS P", Array(productId))
对于可能偶然发现此问题的任何人,感谢 co-worker,我终于解决了这个问题。事实证明代码没有问题,而是连接字符串出了问题。我以某种方式将其排除在示例代码之外,但我的连接字符串包含“DataTypeCompatability=80”。如果存在,代码将抛出错误。但是,如果我删除它,错误将不再发生,并且我得到了怀疑的结果。
我对 this KB article on using ADO with the native client 的理解是应该包含 DataTypeCompatability 以确保更新的数据类型正常工作,但到目前为止我没有发现删除它有任何问题。