Почему SQL Server по-разному (с ошибками) отвечает программе .NET по сравнению с SSMS? - PullRequest
0 голосов
/ 30 августа 2011

Просто наткнулся на оператор, который работает в 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), установка прекрасно выполнит сценарий, поэтому ошибка вызвана определением этого столбца.

У меня два вопроса:

1) SSMS также является приложением .NET - так же, как и мой механизм установки.Почему поведение отличается?Невозможно использовать профилировщик, так как это Express Edition.

Если различие заключается в свойствах соединения по умолчанию (в частности, QUOTED_IDENTIFIER), для SSMS по умолчанию установлено значение ON (подтверждено в Tools | Options | QueryExecution | SQLServer |ANSI) и MSDN говорит, что эта опция включена по умолчанию [для новых подключений].
Я никогда не изменяю какие-либо параметры в используемых мной объектах SqlConnection, так что же дает?

2) В определении этого столбца нет указанных в кавычках идентификаторов, так в чем же претензия?Да, я вижу "..indexes для вычисляемых столбцов", но я только что попытался обернуть весь этот CREATE TABLE в SET QUOTED_IDENTIFIER ON | OFF в SSMS, а затем перевернул их - OFF | ON.Оба случая выполняются в SSMS без каких-либо различий или ошибок!Итак, , даже если я явно выключу, если ВЫКЛ, SSMS успешно выполнит это СОЗДАНИЕ.

Следующая попытка - добавить такую ​​же перенос в скрипт установки.Я добавлю результаты в один миг.Моя среда: VS2010, .NET4 (хотя тот же код будет работать на 2.0), SQL 2008 Express (уверен, что то же самое произойдет на R2).

Если у кого-нибудь есть объяснение, я буду очень признателен за обмен!

Ответы [ 3 ]

1 голос
/ 30 августа 2011

Вы неправильно поняли SET QUOTED_IDENTIFIER ON

Этот (и другие параметры) должен быть включен для индексов вычисляемых столбцов. Уникальное ограничение является индексом. Это связано со стандартами ANSI и предсказуемым поведением

Когда вы CREATE TABLE явно запускаете SET QUOTED_IDENTIFIER OFF в SSMS или через меню? Вы можете отключить его только для новых подключений.

Из .net запустите Profiler или выполните команду DBCC USEROPTIONS, чтобы увидеть, какие операторы SET действительно выполняются. Вы не используете DSN или что-то подобное?

0 голосов
/ 30 августа 2011

сообщение об ошибке является ключом:

СОЗДАТЬ ТАБЛИЦУ не удалось, потому что следующие параметры 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
0 голосов
/ 30 августа 2011

Ваш синтаксис выглядит так, как будто отсутствует запятая и имя столбца для уникального ограничения:

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
    ..
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...