刚刚碰到一个在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上也会出现相同的情况)。
如果有人有解释,我将非常感谢分享!
答案 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