SQL游标问题 - 保持返回NULL

时间:2016-09-09 11:50:22

标签: sql-server triggers cursor

我有一个游标,用于迭代另一个表中的多行。

这是通过将光标添加到触发器中,并迭代从另一个表中作为批量插入的行来完成的。

例如:在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  

1 个答案:

答案 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