Add extra column in insert with instead of trigger

749 views Asked by At

EDIT 1:Basically I want to do INSERT INTO Users(col1, col2, col3) when Users only have col1 and col2 , col3 doesn't exist.

I have a table UsersAddresses with two int fields "User" and "Addresses" which that binds my table Users to another table Addresses. I need to audit any change made to my user so I have a trigger on my Users that works fine, any changes made to my Users table creates a line in the audit table.

The problem is that I also need to trigger the same trigger if I add an addresses to my user. So I create a trigger on my UsersAddresses that will do an update of the Users table. But I need to have the modifierId aswell (to know who wanted to make this change) So I figure out I should alter the way I insert in UsersAddresses to add this Id. I've tried the following, adding a fake "ModifierId" but as expected I get "invalid column name" when I try to add this trigger. Do you know what I should do ?

Thankfully

CREATE TRIGGER UpdateUser 
ON [dbo].[UsersAddresses] 
INSTEAD OF INSERT 
AS
DECLARE @User INT;
DECLARE @Address INT;
DECLARE @ModifierId INT;

SELECT @User = [User] FROM inserted;
SELECT @Address = [Address] FROM inserted;
SELECT @ModifierId = [ModifierId] FROM inserted;

INSERT INTO [UsersAddresses]([User], [Address])
VALUES (@User, @Address);

UPDATE [Users]
SET [CreatorId] = @ModifierId
WHERE [Id] = @User;

Edit Solution: Credits to Michael use context_info with a procedure.:

CREATE TABLE [dbo].[UsersAddresses] (
    [User]    INT NOT NULL,
    [Address] INT NOT NULL,
    CONSTRAINT [PK_UsersAddresses] PRIMARY KEY CLUSTERED ([User] ASC, [Address] ASC),
    CONSTRAINT [FK_ToUser] FOREIGN KEY ([User]) REFERENCES [dbo].[Users] ([Id]),
    CONSTRAINT [FK_ToAddress] FOREIGN KEY ([Address]) REFERENCES [dbo].[Addresses] ([Id])
);



GO
CREATE TRIGGER [ChangeToUsersAddresses]
    ON [dbo].[UsersAddresses]
    FOR DELETE, INSERT, UPDATE
    AS
    BEGIN
    IF ( (SELECT COUNT(*) FROM inserted) > 1)
      THROW 51000, 'To many records', 1

     DECLARE @UserId INT;
     IF (SELECT [User] FROM inserted) IS NOT NULL
     SELECT @UserId = [User] FROM inserted
     ELSE 
     SELECT @UserId = [User] FROM deleted
     INSERT INTO [Audit_Users](UserId,ActiveDirectory,FirstName,LastName,Type,Status,ModifierId,Date)
     SELECT [Id], [ActiveDirectory], [FirstName], [LastName], [Type], [Status], [dbo].GetUserContext(), GETDATE()
      FROM [dbo].[Users] WHERE [Id] = @UserId

  INSERT INTO [Audit_UsersAddresses]([User], [Address])
  SELECT @@IDENTITY, [Address]
  FROM [UsersAddresses]
  WHERE [User] = @UserId;

END;

GetUserContext() that is used in the insert :

CREATE FUNCTION [dbo].[GetUserContext] ()
RETURNS INT
AS
BEGIN
    RETURN COALESCE(CONVERT(INT, CONTEXT_INFO()), 0)
END

And Finally the procedure to set the context.

CREATE PROCEDURE [dbo].[SetUserContext]
    @userId INT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @context VARBINARY(128)
    SET @context = CONVERT(BINARY(128), @userId)

    SET CONTEXT_INFO @context
END
0

There are 0 answers