Могу ли я использовать оператор SELECT для определения ограничения CHECK? - PullRequest
3 голосов
/ 05 января 2011

Могу ли я использовать оператор SELECT для определения ограничения CHECK на сервере MS SQL?Скажем, мне нужно работать с двумя таблицами «Customer Master» и «Indian Customer», в идеальной ситуации обе таблицы совершенно разные и никак не связаны между собой.однако они совместно используют одну и ту же базу данных

Content of "Customer Master":
CustomerName (colomn): a, b, c, d, e
Branchlocation (colomn): IN, AU, IN, IN, UK

Content of "Indian Customer":
customerID (colomn): 1, 2, 3
CustomerName  (colomn): a, c, d
customer details (colomn): details1, details, details
.
.
.

. В таблице «Индийский клиент» я хочу установить ограничение, чтобы пользователи, вводящие данные в эту таблицу, не могли иметь возможность вводить клиентов, которых нет в «Основном клиенте»."или чье местоположение филиала не IN.также таблицы находятся в одном проекте, но НЕ имеют прямого отношения .Другими словами, вы можете сказать, что в таблице «Индийский клиент» должен быть только индийский клиент из «Customer Master».

select CustomerName from "Customer Master"
where Branchlocation = 'IN'

вывод вышеуказанного запроса должен быть разрешен только в ["Индийский клиент"]. [CustomerName]

Ответы [ 3 ]

5 голосов
/ 05 января 2011

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

CREATE TABLE CustomerMaster (
     CustomerName varchar(100) not null,
     LocationCode char(2) not null,
     constraint PK_CustomerMaster PRIMARY KEY (CustomerName),
     constraint UQ_CustomerMaster_Location UNIQUE (CustomerName,LocationCode), /* <-- Superkey here */
     constraint CK_CustomerMaster_Locations CHECK (
         LocationCode in ('IN','UK','AU')
)

CREATE TABLE IndianCustomer (
     CustomerID int not null,
     CustomerName varchar(100) not null,
     CustomerDetails varchar(max) not null,
     LocationCode as 'IN' persisted,
     constraint FK_IndianCustomer_CustomerMaster FOREIGN KEY (CustomerName,LocationCode) references CustomerMaster (CustomerName,LocationCode)
)

Имея LocationCode в качестве вычисляемого столбца в IndianCustomer и имея внешний ключ для суперключа, вы гарантируетеданные совпадают.

Вы можете определить дополнительное ограничение FK только для CustomerName -> CustomerName, это может оказаться полезным в некоторых обстоятельствах.


Или, другими словами - тамэто one , очень стилизованный способ построения ограничения на основе оператора "select" - и это FOREIGN KEY.Но иногда вам нужно добавить дополнительную информацию (например, супер-ключи, вычисляемые столбцы), чтобы удовлетворить дополнительные требования к фильтрации.

1 голос
/ 05 января 2011

Обычно 3 способа

Первый способ, лучше всего, используя DRI

  • определить дополнительный столбец Branchlocation в "Индийском клиенте"
  • добавить КОНТРОЛЬ ПРОВЕРКИ, чтобы ограничить его значением "IN"
  • добавить уникальное ограничение на «Customer Master» для CustomerName / ID, Branchlocation
  • внешний ключ для обоих CustomerName / ID, Branchlocation от "Индийского клиента" до "Master Master"

Работает чисто без кода и триггеров

Редактировать: согласно Damien_The_Unbeliever's answer

Второй способ, ОК, триггеры

  • При вставке или обновлении «Индийский клиент», проверьте Customer Master

Третий способ, не очень хороший, используйте функцию

  • Проверочное ограничение для "индийского клиента" использует функцию, чтобы скрыть SELECT

Это не безопасно для параллелизма и не гарантирует работу

0 голосов
/ 05 января 2011

ПРИМЕЧАНИЕ : - Насколько я знаю, нет никакого способа проверить ограничение с помощью оператора select.Однако для вашего случая вы можете использовать простой запрос выбора с предложением where, как указано ниже

select * from A 
where somecolumn not in 
( select somecolumn from B where <condition for B> )

Для вашего запроса, предполагая, что у вас есть sno в качестве внешней клавиши в B -

select somedata from A
where someforeignKey = ( select sno from B where sno = 55 ) 
...