计算触发器中的行错误

时间:2013-08-29 12:45:28

标签: sql database sql-server-2008

我在下面写了这个触发器。它在COUNT(*) From生成错误。我希望当任何行插入表'Users'时,此触发器当前存在,Assignments中的文件夹应分配给User。enter image description here

例如:我向表Users添加新行,假设userD。然后,在此触发器的帮助下,默认情况下,folderA, folderB, folderC之类的文件夹应分配给userD文件夹权限Visible。我在下面写了这个触发器,但它是Count(*) From

的givig错误
CREATE TRIGGER Trigger_Insert ON Users
FOR INSERT
AS
    declare @userid int;
    declare @username nvarchar(50);
    declare @useremail nvarchar(50);
    declare @userpassword nvarchar(50);

    select @userid=i.user_id from inserted i;   
    select @username=i.user_name from inserted i;   
    select @useremail=i.user_email from inserted i; 
    select @userpassword=i.user_password from inserted i;
    DECLARE @intFlag INT
    SET @intFlag =1
    WHILE (@intFlag <=COUNT(*) FROM Assignments;)  // Error Here
    BEGIN
       insert into UAssignment_Rights(
       ua_rights_id,ua_rights_name,assignment_id,user_id) 
       values(@userid,'Visible','','');
       SET @intFlag = @intFlag + 1
       PRINT 'AFTER INSERT trigger fired.'
    END 
GO

你能帮我解决这个问题。

2 个答案:

答案 0 :(得分:3)

更新的答案是为了遵守评论中的信息。

我的观点是,大多数时候你不需要在Sql Server中使用循环或游标。通常基于集合的方法更简单,更快捷。在这种情况下,您可以使用insert的表单,该表单不会插入固定值,而是select的结果。

CREATE TRIGGER Trigger_Insert ON Users
FOR INSERT
AS
-- this is mandatory in trigger - you do not want @@rowcount reported to applications
-- to change as a result of statement in trigger (all of them, including set and select)

    set nocount on

-- You can simply take assignment_id directly from Assignments table
    insert into UAssignment_Rights(ua_rights_name, assignment_id, user_id)
    select 'Visible', a.assignment_id, i.user_id
      from Inserted i
     cross join dbo.Assignments a

    PRINT 'AFTER INSERT trigger fired.'
GO

P.S。 cartesian product是没有连接条件的连接结果。返回行的含义是左表中每行与右表中每行的所有可能组合。

答案 1 :(得分:2)

COUNT(*)只应用作SELECTHAVING声明see MSDN for more information on aggregate functions的一部分。

如果Assignments不会在WHILE循环中发生变化,请尝试替换...

WHILE (@intFlag <=COUNT(*) FROM Assignments;)  // Error Here

使用...

DECLARE @AssignmentsCount INT
SELECT @AssignmentsCount = COUNT(*) FROM Assignments
WHILE @intFlag <= @AssignmentsCount

这意味着COUNT(*)只进行一次。

但是,如果Assignments 的数量在循环期间发生变化,请将其替换为...

WHILE @intFlag <= (SELECT COUNT(*) FROM Assignments)