与SSMS相比,为什么SQL Server对.NET程序的回复不同(错误输出)?

时间:2011-08-30 18:21:02

标签: c# sql-server sql-server-2008

刚刚碰到一个在SSMS中有效的语句,但是从C#执行时会产生错误:

create table    dbo.tb_Role
(
    idRole  smallint not null identity( 1, 1 )
        constraint xp_Role primary key clustered,
    sRole   varchar( 16 ) not null,
    s_Role  as lower( sRole )           -- automatic lower-case
        constraint  xu_Role unique,     -- enforce name uniqueness
    ..
)

在类似情况的早期,我总是在sRole上使用唯一索引而没有额外的计算列。最近我意识到这种方法将允许“管理员”和“管理员”。想要正确地做事,我添加了s_Role。但是我的安装引擎(用C#编写)令人惊讶地在该语句中窒息,显示出一个SqlException:

  

CREATE TABLE失败,因为以下SET选项的设置不正确:'QUOTED_IDENTIFIER'。验证SET选项是否正确,以便与计算列和/或筛选索引和/或查询通知和/或XML数据类型方法和/或空间索引操作的索引视图和/或索引一起使用。无法创建约束。查看以前的错误。

如果我注释掉s_Role列(和xu_Role约束),则install会完美地执行脚本,因此该列定义会触发错误。

我有两个问题:

1)SSMS也是一个.NET应用程序 - 与我的安装引擎相同。为什么行为不同?不能使用profiler,因为它是Express Edition ..

如果区别于默认连接属性(特别是QUOTED_IDENTIFIER),则SSMS的默认设置为ON(在工具|选项|查询执行| SQLServer | ANSI中确认),MSDN表示此选项为ON默认[用于新连接]。
我从不修改我使用的SqlConnection对象中的任何选项,所以给出了什么?

2)该列定义中没有带引号的标识符,那么投诉是什么?是的,我看到“..indexes on calculated columns”,但我只是尝试在SSMS中将整个CREATE TABLE包装在SET QUOTED_IDENTIFIER ON | OFF中,然后将它们翻转 - OFF | ON。两种情况都在SSMS中执行,没有任何差异或错误! 所以,即使我明确转为OFF,SSMS也会成功执行此CREATE。

接下来要尝试的是在安装脚本中添加相同的包装。我会快速添加结果。我的环境:VS2010,.NET4(相同的代码将在2.0上运行),SQL 2008 Express(确保在R2上也会出现相同的情况)。

如果有人有解释,我将非常感谢分享!

3 个答案:

答案 0 :(得分:1)

你误解了SET QUOTED_IDENTIFIER ON

对于计算列的索引,此(和其他选项)应为ON。唯一约束索引。它与ANSI标准和可预测的行为有关

当您创建表格时,您是否在SSMS中明确运行SET QUOTED_IDENTIFIER OFF或者删除菜单?您可能只是将其关闭以获取新连接。

从.net运行Profiler或执行DBCC USEROPTIONS以查看实际发出的SET语句。您没有使用DSN,或者您使用的是什么?

答案 1 :(得分:0)

您的语法看起来缺少逗号和唯一约束的列名:

create table    dbo.tb_Role
(
    idRole  smallint not null identity( 1, 1 ) PRIMARY KEY,
    sRole   varchar( 16 ) not null,
    s_Role  as lower( sRole ),           -- automatic lower-case
        constraint  xu_Role unique (s_Role),     -- enforce name uniqueness
    ..
)

答案 2 :(得分:0)

错误信息是关键:

  

CREATE TABLE失败,因为以下SET选项不正确   设置:'QUOTED_IDENTIFIER'。验证SET选项是否正确   与计算列和/或的索引视图和/或索引一起使用   过滤的索引和/或查询通知和/或XML数据类型   方法和/或空间索引操作。无法创建约束。   查看以前的错误。

当尝试索引计算列时,SQL Server对你的连接设置很挑剔。

您正在使用SSMS和.NET程序的不同设置连接到SQL Server。他们的默认值必须不同。

尝试将这些设置用于:

SET ANSI_NULLS ON 
SET CURSOR_CLOSE_ON_COMMIT ON 
SET ANSI_NULL_DFLT_ON ON 
SET ANSI_PADDING ON 
SET QUOTED_IDENTIFIER ON 
SET ANSI_WARNINGS ON 
SET ARITHABORT ON 
SET CONCAT_NULL_YIELDS_NULL ON 
SET NUMERIC_ROUNDABORT OFF