I have a trigger on a sql azure table I am trying to set up. Bear with me as this is one of my first triggers. This trigger is supposed to track all changes to the table in an audit table.
- As I understand, you can only use temporary tables in SQL azure if you specifically create them. Documented here
- Also, as I understand, the inserted and deleted tables that are available within a trigger match the schema of the table the trigger is set up on. documented here
So I created a trigger on my table and in that trigger I create two temp tables, one for the inserted and dleted tables, with matching schemas.
When I try to insert into those temp tables from the inserted or deleted tables I get the following error:
The data in row 3 was not commited
Error Source: Microsfoft.SqlServer.Management.DataTools
Error Message: The row values(s) updated or deleted either do not make the row unique or they alter multimple rows (4 rows).
This error occurs on these lines:
INSERT INTO #tempIns SELECT * FROM inserted
INSERT INTO #tempDel SELECT * FROM deleted
Here is my full tirgger:
ALTER TRIGGER [dbo].[tr_KrisisShifts_ShiftTrade] ON [dbo].[KrisisShifts_ShiftTrade] FOR INSERT, UPDATE, DELETE
AS
DECLARE @bit INT ,
@field INT ,
@maxfield INT ,
@char INT ,
@fieldname VARCHAR(128) ,
@TableName VARCHAR(128) ,
@PKCols VARCHAR(1000) ,
@sql VARCHAR(2000),
@UpdateDate VARCHAR(21) ,
@UserName VARCHAR(128) ,
@Type CHAR(1) ,
@PKSelect VARCHAR(1000),
@RecordId VARCHAR(128),
@UserId VARCHAR(128)
--You will need to change @TableName to match the table to be audited
SELECT @TableName = 'KrisisShifts_ShiftTrade'
-- date and user
SELECT @UserName = SYSTEM_USER ,
@UpdateDate = CONVERT(VARCHAR(8), GETDATE(), 112)
+ ' ' + CONVERT(VARCHAR(12), GETDATE(), 114)
---- Action
IF EXISTS (SELECT * FROM inserted)
IF EXISTS (SELECT * FROM deleted)
SELECT @Type = 'U'
ELSE
SELECT @Type = 'I'
ELSE
SELECT @Type = 'D'
---- get list of columns
CREATE TABLE #tempIns (
[ShiftID] [int] PRIMARY KEY NOT NULL,
[ShiftGUID] [uniqueidentifier] NOT NULL,
[PortalID] [int] NULL,
[DepartmentID] [int] NULL,
[PlatoonID] [int] NULL,
[BranchID] [int] NULL,
[TradeDate] [date] NULL,
[StatusID] [int] NULL,
[LastActionDate] [datetime] NULL,
[AllowedRankID] [nvarchar](20) NULL,
[OwnerUserID] [int] NULL,
[OwnerEmail] [nvarchar](50) NULL,
[OwnerLocationID] [int] NULL,
[OwnerRankID] [int] NULL,
[OwnerPlatoonID] [int] NULL,
[OwnerEmployeeID] [nvarchar](50) NULL,
[WorkerUserID] [int] NULL,
[WorkerEmail] [nvarchar](50) NULL,
[WorkerLocationID] [int] NULL,
[WorkerRankID] [int] NULL,
[WorkerPlatoonID] [int] NULL,
[WorkerEmployeeID] [nvarchar](50) NULL,
[SupervisorEmail] [nvarchar](50) NULL,
[SupervisorRankID] [int] NULL,
[SupervisorUserID] [int] NULL,
[SupervisorEmployeeID] [nvarchar](50) NULL,
[SupervisorApproval] [bit] NULL,
[Detail] [nvarchar](max) NULL,
[IsPartialShift] [bit] NULL,
[LastModifiedByUserID] [int] NULL,
[confirmationGUID] [uniqueidentifier] NULL,
[Archived] [bit] NULL,
[CreatedDate] [datetime] NULL,
[UpdatedDate] [datetime] NULL);
CREATE TABLE #tempDel (
[ShiftID] [int] PRIMARY KEY NOT NULL,
[ShiftGUID] [uniqueidentifier] NOT NULL,
[PortalID] [int] NULL,
[DepartmentID] [int] NULL,
[PlatoonID] [int] NULL,
[BranchID] [int] NULL,
[TradeDate] [date] NULL,
[StatusID] [int] NULL,
[LastActionDate] [datetime] NULL,
[AllowedRankID] [nvarchar](20) NULL,
[OwnerUserID] [int] NULL,
[OwnerEmail] [nvarchar](50) NULL,
[OwnerLocationID] [int] NULL,
[OwnerRankID] [int] NULL,
[OwnerPlatoonID] [int] NULL,
[OwnerEmployeeID] [nvarchar](50) NULL,
[WorkerUserID] [int] NULL,
[WorkerEmail] [nvarchar](50) NULL,
[WorkerLocationID] [int] NULL,
[WorkerRankID] [int] NULL,
[WorkerPlatoonID] [int] NULL,
[WorkerEmployeeID] [nvarchar](50) NULL,
[SupervisorEmail] [nvarchar](50) NULL,
[SupervisorRankID] [int] NULL,
[SupervisorUserID] [int] NULL,
[SupervisorEmployeeID] [nvarchar](50) NULL,
[SupervisorApproval] [bit] NULL,
[Detail] [nvarchar](max) NULL,
[IsPartialShift] [bit] NULL,
[LastModifiedByUserID] [int] NULL,
[confirmationGUID] [uniqueidentifier] NULL,
[Archived] [bit] NULL,
[CreatedDate] [datetime] NULL,
[UpdatedDate] [datetime] NULL);
INSERT INTO #tempIns SELECT * FROM inserted
INSERT INTO #tempDel SELECT * FROM deleted
-- Get primary key columns for full outer join
SELECT @PKCols = COALESCE(@PKCols + ' and', ' on')
+ ' i.' + c.COLUMN_NAME + ' = d.' + c.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE pk.TABLE_NAME = @TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
-- Get primary key select for insert
SELECT @PKSelect = COALESCE(@PKSelect+'+','')
+ '''<' + COLUMN_NAME
+ '=''+convert(varchar(100),
coalesce(i.' + COLUMN_NAME +',d.' + COLUMN_NAME + '))+''>'''
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE pk.TABLE_NAME = @TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
-- Get primary Key value for record
SELECT @RecordId = '+convert(varchar(100),
coalesce(i.' + COLUMN_NAME +',d.' + COLUMN_NAME + '))'
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE pk.TABLE_NAME = @TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
-- Get User Id value for record
SELECT @UserId = '+convert(varchar(100),
coalesce(i.LastModifiedByUserID,d.LastModifiedByUserID,0))'
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE pk.TABLE_NAME = @TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
IF @PKCols IS NULL
BEGIN
RAISERROR('no PK on table %s', 16, -1, @TableName)
RETURN
END
SELECT @field = 0,
@maxfield = MAX(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName
WHILE @field < @maxfield
BEGIN
SELECT @field = MIN(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableName
AND ORDINAL_POSITION > @field
SELECT @bit = (@field - 1 )% 8 + 1
SELECT @bit = POWER(2,@bit - 1)
SELECT @char = ((@field - 1) / 8) + 1
IF SUBSTRING(COLUMNS_UPDATED(),@char, 1) & @bit > 0 OR @Type IN ('I','D')
BEGIN
SELECT @fieldname = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableName
AND ORDINAL_POSITION = @field
SELECT @sql = '
insert krisisShifts_Audit ( Type,
TableName,
PK,
FieldName,
OldValue,
NewValue,
UpdateDate,
UserName,
RecordId,
UserId)
select ''' + @Type
+ ''',''' + @TableName
+ ''',' + @PKSelect
+ ',''' + @fieldname + ''''
+ ',convert(varchar(1000),d.' + @fieldname + ')'
+ ',convert(varchar(1000),i.' + @fieldname + ')'
+ ',''' + @UpdateDate + ''''
+ ',''' + @UserName
+ ''',' + @RecordId
+ ',' + @UserId
+ ' from #tempIns i full outer join #tempDel d'
+ @PKCols
+ ' where i.' + @fieldname + ' <> d.' + @fieldname
+ ' or (i.' + @fieldname + ' is null and d.'
+ @fieldname
+ ' is not null)'
+ ' or (i.' + @fieldname + ' is not null and d.'
+ @fieldname
+ ' is null)'
EXEC (@sql)
END
END
QUESTION
Can someone help me figure out why I can not insert into my temp tables inside this trigger
thanks in advance