【发布时间】:2016-09-13 08:20:20
【问题描述】:
我有一个触发器,用于管理来自另一个表的批量加载。将大量行插入到 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;
【问题讨论】:
-
CURSOR在Trigger内。看起来是个坏主意 -
我发现它是在跳跳虎中遍历插入表中的新行的唯一方法。现在唯一的问题是 if 条件
标签: sql-server if-statement triggers cursor