为什么与SSMS相比,SQL Server对.net程序的响应不同(错误)

本文关键字:响应 错误 程序 net 相比 SSMS SQL Server 为什么 | 更新日期: 2023-09-27 18:06:58

刚才碰到一条在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上使用唯一索引,而不使用额外的计算列。最近我意识到这种方法可以同时允许"管理员"answers"管理员"。为了把事情做好,我添加了s_Role。但是我的安装引擎(用c#编写)在这个语句上令人惊讶地卡住了,显示一个SqlException:

CREATE TABLE失败,因为下列SET选项设置错误:'QUOTED_IDENTIFIER'。验证SET选项在使用计算列上的索引视图和/或索引和/或过滤索引和/或查询通知和/或XML数据类型方法和/或空间索引操作时是否正确。不能产生约束。见前面的错误。

如果我注释掉s_Role列(和xu_Role约束)install完美地执行脚本,那么错误是由该列定义触发的。

我有两个问题:

1) SSMS也是一个。net应用程序-和我的安装引擎一样。为什么行为不同?不能使用分析器,因为它是Express Edition.

如果差异是关于默认连接属性(特别是QUOTED_IDENTIFIER), SSMS默认设置为ON(在Tools|Options|QueryExecution|SQLServer|ANSI中确认),MSDN表示此选项默认为ON[对于新连接]。
我从来没有修改过我使用的SqlConnection对象中的任何选项,那么会发生什么呢?

2)在列定义中没有带引号的标识符,那么抱怨什么呢?是的,我明白了。"但是我只是尝试将整个CREATE TABLE包装在SSMS中的SET QUOTED_IDENTIFIER on |OFF中,然后翻转它们- OFF| on。两种情况都在SSMS中执行,没有任何差异或错误!所以,即使我显式地关闭它,SSMS也会成功地执行这个CREATE .

接下来要尝试的是将相同的wrap添加到安装脚本中。我马上添加结果。我的环境:VS2010, . net 4(同样的代码将在2.0上运行),SQL 2008 Express(肯定在R2上也会发生)。

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

为什么与SSMS相比,SQL Server对.net程序的响应不同(错误)

你误解了SET QUOTED_IDENTIFIER ON

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

当你创建表时,你是在SSMS中显式地运行SET QUOTED_IDENTIFIER OFF还是通过菜单运行?您可能只对新连接设置为关闭。

从。net运行Profiler或执行DBCC USEROPTIONS来查看实际发出的SET语句。你没有使用DSN或类似的东西,是吗?

错误消息是关键:

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

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

你连接到SQL Server与不同的设置为SSMS和。net程序。它们的默认值必须不同。

尝试同时使用以下设置:

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

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

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
    ..
)