关键字 'with' 附近有语法错误。

来源:互联网 发布:澳洲足球甲级联赛数据 编辑:程序博客网 时间:2024/03/29 18:45

最近我在开发中遇到个挺棘手的问题,一段T-SQL语句在开发环境中明明跑得好好的,发布到生产环境却报错敲打

经过排查,只有WinXP下才会出现,即使是在干净的虚拟机环境中。客户端不管是用C#还是Delphi来调用这段T-SQL语句都报错,但在SQL Server Management Studio(SSMS)中运行却正常惊恐

排除开发语言的原因,会不会是SQL Server的版本问题呢疑问又测了一下,不管是SQL Server 2008 R2还是SQL Server 2012都一样尴尬

按报错信息来推断,只可能是SQL Server数据库引擎 的问题,SSMS用的是SQL Server Native Client ,我们的客户端用的是OLEDB,虽然性能上有差别,但不至于报错吧。最近一次更新使用了新的with ... as ...语法,难道是这个引起的发火

代码比较长,举个简单例子:

with m as (select * from test)select id from m

with也就是公用表表达式 (Common Table Expression, CTE),SQL Server 从2005开始支持,符合ANSI SQL 标准,OLEDB作为通用的数据库引擎应该能支持。

查了下万能的Stack Overflow,有救了大笑,->>传送门。那位仁兄用VBScript通过OLEDB方式调用也出过类似的问题,解决办法是在with语句之前加个分号“;”。

看来真的是WinXP中的OLEDB引擎的Bug引起,现在维保过了微软估计也不打算更新,这Bug肯定永无修复之日再见

大家感受下:


1、建个临时表Test,数据库随便建一个,然后在WinXP中测下。

private void button1_Click(object sender, EventArgs e)        {            OleDbConnection conn = new OleDbConnection("Provider=SQLOLEDB.1;Password=12345;Persist Security Info=True;User ID=sa;Initial Catalog=Test;Data Source=localhost");            conn.Open();            OleDbCommand cmd=conn.CreateCommand();            cmd.CommandText = " with m as (select * from test)"; //CTE            cmd.CommandText+=" select * from m";            OleDbTransaction ts = conn.BeginTransaction();            cmd.Transaction = ts;            cmd.ExecuteNonQuery();            ts.Commit();            MessageBox.Show("Done!");        }

2、把cmd.CommandText = " with m as (select * from test)"; //CTE 这句改成 cmd.CommandText = ";with m as (select * from test)"; //CTE


其实彻底的解决办法,就是不用OLEDB,改成SQL Server Native Client,但旧代码改起来得费不少时间抓狂

0 0