我有一个触发器来管理来自另一个表的批量加载。将批量加载的行插入Projects表时。触发器被触发,但是当插入的表中已存在行时,条件不起作用。
此触发器的目的是将插入到项目表中的新行插入到vat_matrix表中。如果vat_matrix表中存在行,则使用项目表中的新值更新它们。
我尝试了一些选项,发现光标是迭代插入行的唯一解决方案。这有效,但是我无法使if条件更新现有行。
有什么建议吗?
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[update_vat] ON [dbo].[projects]
FOR UPDATE, INSERT
AS
DECLARE @project AS VARCHAR(25)
DECLARE @client AS VARCHAR(25)
DECLARE @dim2 AS VARCHAR(25)
DECLARE @period_from AS INT
DECLARE @period_to AS INT
DECLARE @status AS CHAR(1)
DECLARE @user_id AS VARCHAR(25)
DECLARE @unit_id AS VARCHAR(25)
DECLARE @sequence_no AS INT
SELECT @project = project,
@client = client,
@dim2 = dim2,
@period_from = period_from,
@period_to = period_to,
@status = status,
@user_id = user_id,
@unit_id = unit_id
FROM inserted
--FIND MAXIMUM VALUE FOR SEQUENCE NUMBER
SET @sequence_no = (SELECT MAX(v) FROM (SELECT sequence_no FROM agldefmatdet WHERE matrix_id = 11) AS value(v));
BEGIN
DECLARE tbl_cursor CURSOR LOCAL FOR
SELECT project, client, dim2, period_from, period_to, status, user_id, unit_id FROM inserted
SET NOCOUNT ON;
IF EXISTS (SELECT * FROM inserted WHERE inserted.project = @project) AND NOT EXISTS (SELECT * FROM deleted WHERE deleted.project = @project)
BEGIN
OPEN tbl_cursor
FETCH NEXT FROM tbl_cursor INTO @project, @client, @dim2, @period_from, @period_to, @status, @user_id, @unit_id
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO [dbo].[vat_matrix]
(att_val_from_1,
att_val_from_2,
att_val_from_3,
att_val_from_4,
att_val_to_1,
att_val_to_2,
att_val_to_3,
att_val_to_4,
att_value_1,
att_value_2,
att_value_3,
att_value_4,
client,
dim_value,
last_update,
matrix_id,
period_from,
period_to,
sequence_no,
status,
user_id)
SELECT @project,
'',
'',
'',
@project,
'',
'',
'',
@project,
'',
'',
'',
@client,
@dim2,
GETDATE(),
'11',
'0',
'0',
@sequence_no + 1,
@status,
@user_id
FETCH NEXT FROM tbl_cursor INTO @project, @client, @dim2, @period_from, @period_to, @status, @user_id, @unit_id
--RETURN;
END
CLOSE tbl_cursor
DEALLOCATE tbl_cursor
END
IF EXISTS (SELECT * FROM inserted WHERE inserted.project = @project) AND EXISTS (SELECT * FROM deleted WHERE deleted.project = @project)
BEGIN
OPEN tbl_cursor
FETCH NEXT FROM tbl_cursor INTO @project, @client, @dim2, @period_from, @period_to, @status, @user_id, @unit_id
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE vat_matrix
SET dim_value = @dim2,
last_update = GETDATE(),
period_from = @period_from,
period_to = @period_to,
status = @status,
user_id = @user_id
WHERE att_val_from_1 = @project
AND matrix_id = '11'
AND client = 'LU'
FETCH NEXT FROM tbl_cursor INTO @project, @client, @dim2, @period_from, @period_to, @status, @user_id, @unit_id
END
CLOSE tbl_cursor
DEALLOCATE tbl_cursor
--RETURN;
END
END;
答案 0 :(得分:0)
正如您所说,只有在一次插入一行时,您的触发器才会起作用。尝试使用此触发器
ALTER TRIGGER [dbo].[update_vat]
ON [dbo].[projects]
FOR UPDATE, INSERT
AS
BEGIN
DECLARE @sequence_no AS INT
--FIND MAXIMUM VALUE FOR SEQUENCE NUMBER
SET @sequence_no = (SELECT Max(sequence_no)
FROM agldefmatdet
WHERE matrix_id = 11));
IF EXISTS (SELECT *
FROM inserted)
AND NOT EXISTS (SELECT *
FROM deleted)
BEGIN
INSERT INTO [dbo].[vat_matrix]
(att_val_from_1,
att_val_from_2,
att_val_from_3,
att_val_from_4,
.....
user_id)
SELECT project,
'',
'',
'',
.....
user_id
FROM inserted
END
IF EXISTS (SELECT *
FROM inserted)
AND EXISTS (SELECT *
FROM deleted)
BEGIN
UPDATE V
SET dim_value = i.dim2,
last_update = Getdate(),
period_from = i.period_from,
period_to = i.period_to,
status = i.status,
user_id = i.user_id
FROM vat_matrix V
JOIN inserted i
ON v.att_val_from_1 = i.project
WHERE matrix_id = '11'
AND client = 'LU'
--RETURN;
END
END