Search code examples
sqlsql-servertriggerslinked-server

Using Trigger to keep data integrity


I have scoured the internet for a solution (mostly scouring stack overflow) and I cannot come up with anything.

Here is my goal: I have a local database and I have set up a linked server to another database. I am creating a trigger on one of my local tables. One of the column values is a Hotel ID. In the linked server there is a table called "Hotel". The point of this trigger is to check and make sure that the HotelID I am trying to insert into my local table is a value that exists in the linked server's Hotel table.

Example: If I want to insert a new row into my "Store Table" from local, I want to make sure that the HotelID I am trying to insert exists in the "Hotel" table in my linked server. If it does not exist, I want to rollback the transaction and display a message.

Below is the code I have been playing with. I feel like I could be close, but I am open to the idea that I am extremely far away.

FYI: The code inside of the IF NOT EXISTS statement is incorrect. I am just confused as to what needs to go in there.

CREATE TRIGGER tr_trigger ON Store
AFTER Insert
AS
DECLARE @HotelID smallint = (SELECT HotelID FROM inserted)

DECLARE @query NVARCHAR(MAX) = N'SELECT   * FROM OPENQUERY (test,''               
SELECT HotelID FROM test.dbo.Hotel WHERE HotelID = ''''' +   
CONVERT(nvarchar(15),@HotelID) +''''''')'
DECLARE @StoredResult Nvarchar(20)
BEGIN
EXEC sp_executesql @query, N'@StoredResult NVARCHAR(MAX) OUTPUT', @StoredResult =  
@StoredResult OUTPUT
SELECT @StoredResult

IF NOT EXISTS (SELECT * FROM OPENQUERY (test,' SELECT HotelID FROM test.dbo.Hotel'))
BEGIN
    PRINT'That HotelID does not exist. Please try again.'

    ROLLBACK TRANSACTION
END

END
GO

EDIT: This has been solved thanks to a couple of suggestions from marc_s. Below is my new code that works how I need it to.

CREATE TRIGGER tr_trigger ON Store
AFTER Update, Insert
AS
BEGIN
    IF NOT EXISTS (SELECT A.* FROM OPENQUERY (test, 'SELECT HotelID  FROM test.dbo.hotel') A
        INNER JOIN inserted i
        ON A.HotelID = i.HotelID)
    BEGIN
        PRINT'Please enter a valid HotelID'     
        ROLLBACK TRANSACTION
    END 
END
GO

Solution

  • How about:

    CREATE TRIGGER tr_DataIntegrity ON Store
    AFTER Update, Insert
    AS
    BEGIN
        IF EXISTS (
            SELECT * FROM inserted i 
            WHERE NOT EXISTS (
                   SELECT A.*
                   FROM OPENQUERY (TITAN_Prescott_Store, 'SELECT HotelID  FROM FARMS_Prescott.dbo.hotel') A
                    WHERE A.HotelID = i.HotelID))
             BEGIN
                 PRINT'Please do not enter an invalid HotelID'     
                 ROLLBACK TRANSACTION
             END 
    END
    GO