FlorianC
FlorianC

Reputation: 23

INSERT INTO View, INSTEAD OF Trigger, Identity, multiple tables?

Here as my tables (Entier = Integer // Caractère long variable = Varchar) :

https://i.sstatic.net/lNjyy.jpg

enter image description here

I created a view V_Enterprise(idContact, phoneNumber, email, name, city, adress)

I tried to create a Trigger on that View to allow users to update the view :

CREATE TRIGGER test
ON V_Entreprise
INSTEAD OF INSERT
AS 
DECLARE @T_ContactId INT
BEGIN
    INSERT INTO T_Contact 
    SELECT i.phoneNumber, i.email
    FROM Inserted i 

    SELECT @T_ContactId = @@IDENTITY

    INSERT INTO T_Entreprise
    SELECT @T_ContactId, i.name, i.city, i.adress
    FROM Inserted i 
END ;

As I expected, it work on simple inserts, but when I add couples of rows at once, it fails because @T_ContactId only contains the first id. Can someone help me to fix it ? I feel like I should use INNER JOIN inserts but I can't figure out how to deal with it.

Upvotes: 2

Views: 3979

Answers (4)

I don't know if this is a good way to do it, but you can do this without relying on unique columns or using a cursor using the OUTPUT clause for INSERT. This approach does make use of an in-memory temporary table that could get big with large inserts.

DECLARE @Table table( NewID BIGINT);


INSERT INTO T_Contact (PhoneNumber) 
    OUTPUT Inserted.ID
    INTO @Table
SELECT PhoneNumber FROM inserted WHERE 
;

INSERT INTO T_Enterprise (Contact_ID)
SELECT NewID FROM @Table;

Upvotes: 1

Joachim Isaksson
Joachim Isaksson

Reputation: 180917

This trigger uses a loop over a cursor and won't require any particular uniqueness in the tables;

CREATE TRIGGER test
ON V_Enterprise
INSTEAD OF INSERT
AS 
BEGIN
   DECLARE @name    VARCHAR(32)
   DECLARE @city    VARCHAR(32)
   DECLARE @address VARCHAR(32)
   DECLARE @pn      VARCHAR(32)
   DECLARE @email   VARCHAR(32)

   DECLARE cursor1 CURSOR FOR
      SELECT name,city,address,phoneNumber,email FROM inserted;

    OPEN cursor1;
    FETCH NEXT FROM cursor1 INTO @name, @city, @address, @pn, @email;
    WHILE @@FETCH_STATUS = 0
    BEGIN
      INSERT INTO T_Contact (phoneNumber,email) VALUES (@pn, @email);
      INSERT INTO T_Enterprise (idcontact,name,city,address) VALUES
         (@@IDENTITY,@name,@city,@address);
      FETCH NEXT FROM cursor1 INTO @name, @city, @address, @pn, @email;
    END
    CLOSE cursor1;
    DEALLOCATE cursor1;
END
GO

Upvotes: 1

Mike Perrenoud
Mike Perrenoud

Reputation: 67898

If phoneNumber and email are a unique key in T_Contact then you could do this:

CREATE TRIGGER test
ON V_Entreprise
INSTEAD OF INSERT
AS 
DECLARE @T_ContactId INT
BEGIN
    INSERT INTO T_Contact 
    SELECT i.phoneNumber, i.email
    FROM Inserted i 

    SELECT @T_ContactId = @@IDENTITY

    INSERT INTO T_Entreprise
    SELECT
        (SELECT idContact FROM T_Contact
            WHERE phoneNumber = i.phoneNumber AND email = i.email),
        i.name, i.city, i.adress
    FROM Inserted i 
END ;

Upvotes: 0

HLGEM
HLGEM

Reputation: 96572

OK you should never set scalar variables to a value in inserted or delted in a trigger.

Use the OUTPUT clause instead to get your id values back.

Upvotes: 2

Related Questions