Member of the LearnItFirst.com Video Training Network | LearnSqlServer.com | SQL SSIS Training | SQL Programming Tutorials |
LearnSqlServer.com Forums LearnSqlServer.com
Welcome Guest Search | New Posts | Members | Log In | Register

Instead of Triggers for Data Validation - How to Prevent a Primary Key Error Options
Scott Whigham
Posted: Monday, August 28, 2006 11:38:09 AM


Rank: Super Mod

Joined: 3/20/2006
Posts: 345
Points: 748
Location: Dallas, TX
Code:
/*
    Author: Scott Whigham from http://www.LearnSqlServer.com/

    Description: This script demos how to use triggers to for data validation. Since it uses INSTEAD OF triggers, it will
        only run on SQL Server 2000 and above. You'll need the Northwind database to work with this script.

    Misc Notes: This is neat for debugging/development since it shows you the problems in your SQL. It isn't a recommended
        solution for production work.
   
    Versions: SQL Server 2005, 2000
   
    Creation Date: August 28, 2006

    For more scripts like this one, visit http://forums.learnsqlserver.com/codesamples.aspx
*/
USE Northwind
GO
SET NOCOUNT ON
GO
--CREATE the OrderDetailsLog table
CREATE TABLE OrderDetailsLog (
    LogID INT NOT NULL IDENTITY PRIMARY KEY,
    LogDate datetime NOT NULL DEFAULT GETDATE(),
    Login sysname NOT NULL DEFAULT SUSER_SNAME(),
    Host sysname NOT NULL DEFAULT HOST_NAME(),
    App sysname NOT NULL DEFAULT APP_NAME(),
    OrderID INT NOT NULL,
    ProductID INT NOT NULL,
    Quantity INT NOT NULL,
    Remarks VARCHAR(100)
)
GO
CREATE TRIGGER tr_OrderDetails_iofi_validate ON OrderDetails
  INSTEAD OF INSERT
AS
--INSTEAD OF Trigger Logs Invalid Rows and Accepts Only Valid Rows
IF @@rowcount = 0 RETURN

-- Violation of PRIMARY KEY
IF EXISTS(SELECT *
          FROM inserted AS I JOIN OrderDetails AS OD
            ON I.OrderID = OD.OrderID AND I.ProductID = OD.ProductID)
  INSERT INTO OrderDetailsLog(OrderID, ProductID, Quantity, Remarks)
    SELECT I.*, 'Violation of PRIMARY KEY' AS Remarks
    FROM inserted AS I JOIN OrderDetails AS OD
      ON I.OrderID = OD.OrderID AND I.ProductID = OD.ProductID

-- Violation of FOREIGN KEY to Orders
IF EXISTS(SELECT * FROM inserted AS I
          WHERE NOT EXISTS(SELECT * FROM Orders AS O
                           WHERE O.OrderID = I.OrderID))
  INSERT INTO OrderDetailsLog(OrderID, ProductID, Quantity, Remarks)
    SELECT *, 'Violation of FOREIGN KEY to Orders' AS Remarks
    FROM inserted AS I
    WHERE NOT EXISTS(SELECT * FROM Orders AS O
                     WHERE O.OrderID = I.OrderID)

-- Violation of FOREIGN KEY to Products
IF EXISTS(SELECT * FROM inserted AS I
          WHERE NOT EXISTS(SELECT * FROM Products AS P
                           WHERE P.ProductID = I.ProductID))
  INSERT INTO OrderDetailsLog(OrderID, ProductID, Quantity, Remarks)
    SELECT *, 'Violation of FOREIGN KEY to Products' AS Remarks
    FROM inserted AS I
    WHERE NOT EXISTS(SELECT * FROM Products AS P
                     WHERE P.ProductID = I.ProductID)

-- Violation of CHECK (Quantity > 0
IF EXISTS(SELECT * FROM inserted
          WHERE Quantity <= 0)
  INSERT INTO OrderDetailsLog(OrderID, ProductID, Quantity, Remarks)
    SELECT *, 'Violation of CHECK (Quantity > 0)' AS Remarks
    FROM inserted
    WHERE Quantity <= 0

-- Insert only valid rows to the OrderDetails table
INSERT INTO OrderDetails
  SELECT * FROM Inserted AS I
  WHERE
    NOT EXISTS(SELECT * FROM OrderDetails AS OD
               WHERE OD.OrderID = I.OrderID
                 AND OD.ProductID = I.ProductID)
   AND
    EXISTS(SELECT * FROM Orders AS O WHERE O.OrderID = I.OrderID)
   AND
    EXISTS(SELECT * FROM Products AS P WHERE P.ProductID = I.ProductID)
   AND
    Quantity > 0
GO

--Test Inserts into the OrderDetails Table. After each INSERT, look in the OrderDetailsLog table

INSERT INTO OrderDetails VALUES(10248, 1, 10) -- Successful
INSERT INTO OrderDetails VALUES(10248, 1, 10) -- Violates PK
INSERT INTO OrderDetails VALUES(10247, 1, 10) -- Violates FK to Orders
INSERT INTO OrderDetails VALUES(10248, 0, 10) -- Violates FK to Products
INSERT INTO OrderDetails VALUES(10248, 2, -1) -- Violates CHECK
INSERT INTO OrderDetails VALUES(10247, 0, -1) -- Violates both FKs and also CHECK

--Script to Add Rows to the OrderDetails Table

INSERT INTO OrderDetails VALUES(10248, 2, 20)
INSERT INTO OrderDetails VALUES(10248, 3, 30)
INSERT INTO OrderDetails VALUES(10249, 1, 5)
INSERT INTO OrderDetails VALUES(10249, 2, 10)
INSERT INTO OrderDetails VALUES(10249, 3, 15)
INSERT INTO OrderDetails VALUES(10250, 1, 20)
INSERT INTO OrderDetails VALUES(10250, 2, 20)
INSERT INTO OrderDetails VALUES(10250, 3, 20)

select * from OrderDetailsLog table
Users browsing this topic
Guest


Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.
     
Don't Forget!
LearnItFirst.com
Don't Forget!
LearnSqlServe.com
 
Home | About Us | Support | Contact Us | Privacy | Site Map | Blogs Blogs Refer a Friend and Get a Free Subscription!
© Copyright 2004-2007 LearnItFirst.com LLC. All rights reserved. All trademarks remain the property of their respective owners.
This site is not affiliated in any way with the Microsoft Corporation.