簡體   English   中英

檢查約束引用另一個表上的唯一列

[英]Check Constraint Referencing Unique Column on another Table

我想限制可以在列中輸入的可用值,但是我想使用的值在另一個表中,這不是該表的主鍵; 該表的主鍵未包含在我的表中。

例如,假設我創建了一個用於報告客戶的表(列:Id,名稱,標題),該表引用了現有的客戶標題表(列:Id,標簽)。兩個表在ID上都有主鍵。 我希望客戶表以文字顯示客戶的標題,而不是與客戶關聯的title.Id。 我知道客戶標題欄應僅包含標題表中的值。 我無法更改標題表的結構。

這是我考慮過的三個選項,但我不太喜歡:

1.我不能用外鍵引用title.label列,因為它不是主鍵。

2.我可以創建一個檢查約束並制作一個動態腳本,以在使用標題標簽更新customers表之前使用titles表中的值對其進行更新,但這感覺很手工。

DECLARE @TableName VARCHAR(50) = 'Customers'
DECLARE @FieldName VARCHAR(50) = 'Title'
DECLARE @SQL VARCHAR(MAX) = ''

SELECT @SQL = @SQL + '
OR ' + @FieldName + ' = ''' + Label + ''''
FROM dbo.Titles
ORDER BY Label

SELECT @SQL = 'ALTER TABLE dbo.' + @TableName + ' DROP CONSTRAINT chk_Customer' + @FieldName + '
ALTER TABLE dbo.' + @TableName + ' ADD CONSTRAINT chk_Customer_' + @FieldName + ' CHECK
  (' + SUBSTRING(@SQL,6,LEN(@SQL)) + ')'

PRINT @SQL

3.我可以保留它,而根本不用約束列,但是我寧願在可能的地方添加約束,以使所有內容盡可能地減少,並提高查詢性能。

因此,問題是這樣的:是否有一種內置的方法通過引用另一張表來引用一列(以限制或枚舉值),而不必以某種方式編寫值; 一旦創建,某些東西將始終保持最新狀態,就像外鍵關系一樣,但不必引用主鍵。

首先,像GordonLinoff注釋一樣,更好的方法是在Customer表中包括TitleID 如果您無法更改Customer表的布局,則可以使用以下選項。 foreign key絕對比使用動態T-SQL保持check約束最新更好。

我不能用外鍵引用title.label列,因為它不是主鍵。

外鍵可以引用任何候選鍵。 它不必引用主鍵。

要告訴數據庫候選密鑰,您可以創建一個唯一索引:

create table title (
    id int primary key, 
    label varchar(50));
create table customer (
    id int primary key, 
    title varchar(50));
create unique index ux_title_label on title(label);
alter table customer add constraint fk_customer_title 
    foreign key (title) references title(label);

告訴數據庫候選密鑰的另一種方法是唯一約束:

alter table title add constraint uc_title_label unique (label);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM