如何防止ADO改变我的SQL命令文本



我正在对SQL Server 2008 R2数据库运行MERGE语句(在2008兼容模式下)

确切的合并语句SQL是不相关的,但这里有一个合并语句的例子:

MERGE Users
USING (VALUES 
('{77410DC5-7A3E-4F1A-82C6-8EFB3068DE66}')
) AS rows(UserGUID)
ON Users.UserName = rows.UserName
WHEN NOT MATCHED BY SOURCE THEN
DELETE; --always end MERGE with semi-colon

当从SSMS或从运行Windows 7的客户端PC执行此语句时,它执行正确。

但是当我的软件在客户端PC上运行时,Windows XP或Windows Server 2003 R2, sql CommandText在到达服务器之前被更改。在SQL Server Profiler中,我可以看到正在执行的SQL是:

exec MERGE Users
USING (VALUES 
('{77410DC5-7A3E-4F1A-82C6-8EFB3068DE66}')
) AS rows(UserGUID)
ON Users.UserName = rows.UserName
WHEN NOT MATCHED BY SOURCE THEN
DELETE; --always end MERGE with semi-colon

是无效的SQL, SQL Server抛出错误:

Incorrect syntax near the keyword 'MERGE'

您可以通过尝试在SQL Server 2008 R2数据库上执行它来确认它是无效的SQL。

Peter Boulton在微软论坛上报告了同样的问题:

SQL MERGE语法适用于Win7 SP1客户端,但不适用于早期平台

我相信ADO在将SQL发送到服务器之前会解析SQL。在Win7 SP1和WinServer 2008 R2中更新了数据访问组件。然而,我相信XP SP3的数据访问组件早于SQL Server 2008。

这就是为什么SQL可以在Win7 SP1中工作而不能在XP中工作。

我的'解决方案'是将SQL封装在EXEC中,以便ADO允许它通过,如:

EXEC(合并等。)

他的hack确实有效,更改:

MERGE Users ...

EXEC('MERGE Users' ...)

但我想提出真正的解决方案。我不知道是谁修改了我的命令文本:

ADO -> OLEDB -> SQLOLEDB -> SQL Server

但我想让他们停下来。

我如何,通过ADO,指定我的命令文本,并有SQLOLEDB不修改它?

现在我的代码是1:
String sqlCommandText = "MERGE Users" //snip;
int recordsAffected;
connection.Execute(
    sqlCommandText, 
    out recordsAffected, 
    adCmdText | adExecuteNoRecords);

我没有看到任何ExecuteOptionEnumCommandTypeEnum来告诉ADO和底层提供者将文本视为原始


目前修复hack是:

sql = "MERGE Users" ...
ExecuteNoRecords(connection, sql);

和修改后的帮助器:

int ExecuteNoRecords(Connection connection, String sql)
{
   //20130611: Fix bug in ADO that mangles/breaks SQL it doesn't understand (e.g. MERGE on Windows XP)
   String obfuscatedCommandText = 'EXEC(' + QuotedStr(sql)+ ')';
   int recordsAffected;
   connection.Execute(obfuscatedCommandText, out recordsAffected, adCmdText | adExecuteNoRecords);
   return recordsAffected;
}

更新:一个更好的变通方法

比起在EXEC(...)中包装整个语句,我发现一个更安全的打败ADO的技巧是在语句之前加上注释。即使是空注释也可以:
--
MERGE Users
USING (VALUES ...

在现实中,您将需要一些文本来解释空注释行对于使查询工作至关重要的:

--Leading comment to thwart ADO from mangling MERGE on Windows XP/2003R2
MERGE Users
USING (VALUES ...

由于没有解决方案,并且ADO(虽然不是死亡)已经完成,因此破解的答案。

永远不要在没有注释行的情况下发出MERGE语句:

--Dummy leading comment line to thwart ADO from mangling MERGE on Windows XP/2003R2
MERGE Users
USING (VALUES ...

相关内容

  • 没有找到相关文章

最新更新