SQL Server: способы навязывания уникальности столбцам из двух разных таблиц - PullRequest
0 голосов
/ 04 октября 2018

Примеры таблиц:

  • dbo.TransactionHeader (HeaderID, BillID, FileID) - здесь HeaderID - это PK
  • dbo.TransactionGroup (FileID, SurityID) -- Все это делает составной PK

Я хочу наложить уникальность на BillID из таблицы dbo.TransactionHeader и другой столбец (SurityID) из другой таблицы dbo.TransactionGroup.SurityID недоступно в таблице dbo.TransactionHeader.

Я хочу добавить уникальность в таблицу dbo.TransactionHeader, чтобы не вставлять дубликаты с комбинацией (BillID, SurityID).

Я не могу добавить новый физический столбец (скажем, SurityID) вdbo.TransactionHeader как устаревшая база данных с большим количеством данных, и это будет большое изменение.

Options tried: Попытка создать вычисляемый столбец и попытка использовать функцию для получения SurityID на основе FileID,Но не может создать уникальное ограничение для вычисляемого столбца, так как функция возвращает недетерминированное значение

Любая помощь / идеи будут оценены.

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

После дополнительных исследований выяснилось, что мы также можем использовать ограничение CHECK для достижения этой цели.

Шаги:

Создайте user defined function, который вернет 0 или 1, после проверки наличия дубликатов, как показано ниже:

CREATE FUNCTION [dbo].[udf_TransactionHeader_Bill_ID_Surity_ID](@File_ID INT,@Bill_ID VARCHAR(10))
RETURNS BIT
AS
BEGIN

    IF(SELECT COUNT(*) FROM [dbo].[TransactionHeader] AS th
            WHERE th.Bill_ID = @Bill_ID) > 0
            BEGIN            
            DECLARE @Surity_ID SMALLINT = (SELECT Surity_ID FROM [dbo].[TransactionGroup] WHERE File_ID = @File_ID)

            IF (SELECT COUNT(*)
                FROM [dbo].[TransactionHeader] AS th 
                INNER JOIN [dbo].[TransactionGroup] AS tg ON tg.File_ID = th.File_ID 
                WHERE th.Bill_ID = @Bill_ID
                AND  tg.Surity_ID = @Surity_ID) > 1
                BEGIN
                    RETURN 1
                END
          END
RETURN 0
END
GO

Теперь добавьте ограничение CHECK к столбцу dbo.TransactionHeader (Bill_ID)

и вставьте указанную выше функцию в выражение ограничения CHECK, как показано ниже:

ALTER TABLE [dbo].[TransactionHeader]  WITH NOCHECK
ADD CONSTRAINT CK_TransactionHeader_Bill_ID 
CHECK (dbo.udf_TransactionHeader_Bill_ID_Surity_ID(SurityID,Bill_ID) = 0);

Это должно достичь этого.

0 голосов
/ 05 октября 2018

Вы можете сделать это с индексированным представлением.Пример:

CREATE VIEW dbo.v1 WITH SCHEMABINDING AS
SELECT H.HeaderID, H.BillID, H.FileId, G.SurityID
FROM dbo.TransactionHeader H
JOIN dbo.TransactionGroup G
ON H.FileID = G.FileID;
GO

CREATE UNIQUE CLUSTERED INDEX v1idx ON dbo.v1 (BillID, SurityID) ;
...