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

最近我在开发中遇到个挺棘手的问题,一段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肯定永无修复之日。

大家感受下:

关键字 'with' 附近有语法错误。_第1张图片

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,但旧代码改起来得费不少时间。

你可能感兴趣的:(SQL,Server)