2017-02-18 17 views
0

Доброго утра,SQL триггера, чтобы избежать дубликатов с несколькими идентификаторами

Я нашел решение моей проблемы, но я думал, что я разделю его так или иначе, как это могло бы быть полезным для будущих проектов/задач. У меня есть простая таблица SQL, ниже которой будет внешний ключ моей гораздо более крупной таблицы рыночных данных о ценах на акции.

CREATE TABLE [StockMarket] 
(
[ID] INT NOT NULL IDENTITY(1,1) PRIMARY KEY, 
[ReutersRIC] VARCHAR(50), 
[BloombergTicker] VARCHAR(50), 
[YahooSymbol] VARCHAR(50) 
/* other irrelevant columns here*/ 
) 

Имея это в виду, я пытаюсь добавить устойчивость к структуре, как я буду добавлять из различных источников данных. Для каждого базового временного ряда на финансовых рынках существует несколько имен в зависимости от того, какой поставщик данных вы используете. Я хотел избегать нескольких строк с разными источниками данных, представляющими одни и те же временные ряды. Мне нужен триггер, который:

1) Если вставленные значения еще не указаны в таблице, они просто вставлены.

2) если я вставляю строку, для которой уже существует хотя бы один [ReutersRIC], [BloombergTicker], [YahooSymbol], [ISIN], я обновляю эту конкретную строку.

2.1) Обновление должно происходить только на ненулевых блюдах

Мой вопроса было, как это может быть достигнуто наилучшим образом? Мне потребовалось некоторое время, но я хотел бы рассказать об этом ниже для дальнейшего использования.

ответ

0

Вот мое решение:

CREATE TRIGGER UniqueStockMarketInserts ON [dbo].[StockMarket] 
INSTEAD OF INSERT 
AS 
BEGIN 
    DECLARE @StockId int 
    SELECT @StockId = S.ID 
     FROM [StockMarket] S INNER JOIN [INSERTED] I 
     ON 
     S.YahooSymbol = I.YahooSymbol OR 
     S.ReutersRIC = I.ReutersRIC OR 
     S.BloombergTicker = I.BloombergTicker OR 
     S.ISIN = I.ISIN 
    IF @StockId IS NULL 
    BEGIN 
     INSERT INTO [StockMarket] (YahooSymbol,ReutersRIC,BloombergTicker,ISIN) 
     SELECT I.YahooSymbol, I.ReutersRIC, I.BloombergTicker, I.ISIN 
     FROM [INSERTED] I 
    END 
    ELSE 
    BEGIN 
    UPDATE S SET 
     S.ISIN = ISNULL(S.ISIN,I.ISIN), 
     S.YahooSymbol = ISNULL(S.YahooSymbol,I.YahooSymbol), 
     S.ReutersRIC = ISNULL(S.ReutersRIC,I.ReutersRIC), 
     S.BloombergTicker = ISNULL(S.BloombergTicker,I.BloombergTicker) 
     FROM INSERTED I, StockMarket S 
     WHERE S.ID = @StockId 
    END 
END 
GO 

Вот тест я побежал на него с примерами из реальной жизни (за исключением ISIN, который я сделал):

/*-----------TESTING THE TRIGGER--------*/ 
INSERT INTO StockMarket (ReutersRIC, BloombergTicker) VALUES ('G.TO', 'GG US Equity'); 
INSERT INTO StockMarket (YahooSymbol, BloombergTicker, ISIN) VALUES ('GOOG', 'GOOG US Equity','US123454321'); 
INSERT INTO StockMarket (YahooSymbol, ISIN) VALUES ('RDSA','NL111112222') 
INSERT INTO StockMarket (YahooSymbol, ReutersRIC) VALUES ('GG', 'G.TO');  /*this should update as per trigger*/ 
INSERT INTO StockMarket (ReutersRIC, ISIN) Values ('GOOG.OQ','US123454321'); /*this should update as per trigger*/ 
INSERT INTO StockMarket (YahooSymbol, ReutersRIC) Values ('RDSA', 'RDSa.L'); /*this should update as per trigger*/ 

И результаты:

enter image description here

Надеется, что это может помочь кому-то в будущем. Счастливое кодирование