Простое ограничение проверки не отображается должным образом в INFORMATION_SCHEMA.CHECK_CONSTRAINTS - PullRequest
2 голосов
/ 15 марта 2012

У меня довольно простое проверочное ограничение, в котором я хочу, чтобы два столбца были либо NULL, либо оба NOT NULL. Однако INFORMATION_SCHEMA.CHECK_CONSTRAINTS неправильно отображает это ограничение.

Я в основном хочу это ограничение:

 ((Col1 IS NULL AND Col2 IS NULL) OR (Col1 IS NOT NULL AND Col2 IS NOT NULL))

но INFORMATION_SCHEMA.CHECK_CONSTRAINTS.CHECK_CLAUSE показывает это:

 ([Col1] IS NULL AND [Col2] IS NULL OR [Col1] IS NOT NULL AND [Col2] IS NOT NULL)
--^                                ^  ^                                        ^
--missing parenthesis 

, который не совпадает и который является неправильным.

Вы можете легко воспроизвести это ...

создать таблицу и проверить ограничение:

CREATE TABLE dbo.MyTest (RowID int identity(1,1) primary key, Col1 int NULL, Col2 int NULL)
ALTER TABLE dbo.MyTest ADD CONSTRAINT CK_MyTest_Cols CHECK ((Col1 IS NULL AND Col2 IS NULL) OR (Col1 IS NOT NULL AND Col2 IS NOT NULL))

неверное отображение INFORMATION_SCHEMA.CHECK_CONSTRAINTS.CHECK_CLAUSE:

SELECT
     c.ORDINAL_POSITION
        ,cc.CONSTRAINT_NAME
        ,cc.CHECK_CLAUSE
    FROM INFORMATION_SCHEMA.COLUMNS                                  c
        LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE   cu ON c.TABLE_CATALOG=cu.TABLE_CATALOG AND c.TABLE_SCHEMA=cu.TABLE_SCHEMA AND c.TABLE_NAME=cu.TABLE_NAME AND c.COLUMN_NAME=cu.COLUMN_NAME
        LEFT OUTER JOIN INFORMATION_SCHEMA.CHECK_CONSTRAINTS         cc ON cu.TABLE_CATALOG=cc.CONSTRAINT_CATALOG AND cu.TABLE_SCHEMA=cc.CONSTRAINT_SCHEMA AND cu.CONSTRAINT_NAME=cc.CONSTRAINT_NAME
    WHERE c.TABLE_SCHEMA='dbo' AND c.TABLE_Name='MyTest' AND cc.CONSTRAINT_SCHEMA IS NOT NULL

убедитесь, что проверочное ограничение действительно работает как нужно:

INSERT INTO dbo.MyTest (Col1, Col2) VALUES (NULL,NULL)
INSERT INTO dbo.MyTest (Col1, Col2) VALUES (5,5)
INSERT INTO dbo.MyTest (Col1, Col2) VALUES (5,NULL)

что случилось с INFORMATION_SCHEMA.CHECK_CONSTRAINTS? и есть ли что-то, что я делаю неправильно или какой-то обходной путь для этого?

SSMS также показывает это некорректно, когда используется диалоговое окно проверки ограничений (при проектировании таблицы). Это также будет писать сценарий неправильно. Тем не менее, когда я использую сценарий SSMS с этим ограничением, три вставки в моем тесте (см. Выше) все еще работают как нужно (первые две вставки работают, третья не работает)? Кажется, это противоречит всему, что я узнал о AND, OR и parenthesis. Что происходит?

1 Ответ

2 голосов
/ 15 марта 2012

Они одинаковы. См. Приоритет логического оператора

Если в выражении используется более одного логического оператора, NOT сначала оценивается, затем И и, наконец, ИЛИ.

And имеет более высокий приоритет, чем OR, поэтому скобки являются необязательными - так же, как умножение имеет более высокий приоритет, чем сложение, поэтому

SELECT 1 * 1 + 3 * 3 

совпадает с

SELECT (1 * 1) + (3 * 3)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...