我在下面写了这个触发器。它在COUNT(*) From
生成错误。我希望当任何行插入表'Users'时,此触发器当前存在,Assignments中的文件夹应分配给User。
例如:我向表Users
添加新行,假设userD
。然后,在此触发器的帮助下,默认情况下,folderA, folderB, folderC
之类的文件夹应分配给userD
文件夹权限Visible
。我在下面写了这个触发器,但它是Count(*) From
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
你能帮我解决这个问题。
答案 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(*)
只应用作SELECT
或HAVING
声明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)