我正在针对SQL Server 2008 R2数据库(处于2008兼容模式)运行MERGE
语句。
确切的合并语句SQL是无关紧要的,但这里是一个MERGE语句的例子:
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执行此语句时,它会正确执行。
但是当我的软件在Windows XP或Windows Server 2003 R2的客户端PC上运行时,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 syntax works with Win7 SP1 client but fails with earlier platforms
我相信ADO会在将SQL发送到服务器之前对其进行解析。针对Win7 SP1和WinServer 2008 R2更新了数据访问组件。但是,我相信XP SP3的数据访问组件早于SQL Server 2008。
这就是为什么SQL可以从Win7 SP1运行而不是从XP运行。
我的'解决方案'是将SQL包装在
EXEC
中,以便ADO允许它通过,如:EXEC( 'MERGE ....等。')
他的黑客当然有效,改变:
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);
我没有看到任何ExecuteOptionEnum
或CommandTypeEnum
告诉ADO和基础提供商将文本视为 raw 。
目前修正黑客是:
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 ...
答案 0 :(得分:2)
由于没有解决方案,并且ADO(虽然不是死)已完成,黑客 答案。
在没有前导评论专栏的情况下,永远不要发出MERGE
语句:
--Dummy leading comment line to thwart ADO from mangling MERGE on Windows XP/2003R2
MERGE Users
USING (VALUES ...