我有一个游标,用于迭代另一个表中的多行。
这是通过将光标添加到触发器中,并迭代从另一个表中作为批量插入的行来完成的。
例如:在atsproject表中添加了许多项目,然后触发下面的add触发器添加到vatmatrixtable中。
我遇到的问题是光标将通过并将所有行值添加为null。
有没有办法进一步诊断?
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[UPDATE_VATMATRIX] ON [dbo].[atsproject]
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 @ROW_NUM VARCHAR (25)
DECLARE @sequence_no AS INT
--DECLARE @TrigTempUpdate_Cursor CURSOR
--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));
DECLARE Tbl_Cursor CURSOR FOR
SELECT project,
client,
dim2,
period_from,
period_to,
status,
user_id,
unit_id
FROM inserted
OPEN Tbl_Cursor;
FETCH NEXT FROM Tbl_Cursor;
WHILE @@FETCH_STATUS = 0
BEGIN
--SELECT TOP 1 * FROM inserted
IF EXISTS (SELECT TOP 1 * FROM inserted) AND NOT EXISTS (SELECT TOP 1 * FROM deleted)
INSERT INTO [dbo].[agldefmatdet]
(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
RETURN;
IF EXISTS (select * from inserted) AND EXISTS (select * from deleted)
UPDATE agldefmatdet
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'
RETURN;
FETCH NEXT FROM Tbl_Cursor;
END;
CLOSE Tbl_Cursor;
DEALLOCATE Tbl_Cursor;
GO
答案 0 :(得分:0)
虽然不支持该方法或调试其余代码,但您的直接问题是fetch next语句,它们应该将游标声明中的列映射到您在循环中使用的变量;
FETCH NEXT FROM Tbl_Cursor
INTO @project,@client,@dim2,@period_from,@period_to,@status,@user_id,@unit_id;
编辑:作为基于设置的解决方案;
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[UPDATE_VATMATRIX] ON [dbo].[atsproject]
FOR UPDATE, INSERT
AS
DECLARE @sequence_no AS INT
--DECLARE @TrigTempUpdate_Cursor CURSOR
--FIND MAXIMUM VALUE FOR A MATRIX 11 SEQUENCE NUMBER
/* replaced with select below
SET @sequence_no = (SELECT MAX(v) FROM (SELECT sequence_no FROM agldefmatdet WHERE matrix_id = 11) AS value(v));
*/
SELECT @sequence_no = max(sequence_no) FROM agldefmatdet WHERE matrix_id = 11; /* NB, hard coding IDs isn't a good idea */
INSERT INTO [dbo].[agldefmatdet]
(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 + row_number() over (order by project), /* order doesn't appear important so column listed here shouldn't matter */
status,
user_id
from inserted
UPDATE a
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 agldefmatdet a
inner join inserted i /* replaces previous where statement */
on i.project = a.att_val_from_1
and '11' = a.matrix_id
and 'LU' = a.client
RETURN;
GO