Question : Multi row trigger join

The attached trigger works fine for a single row update but not for multi rows. The reason I think is the @roleid var is taking the last record from the deleted table when joined to the testusers table.

The 'AND' condition first looks for a value in gl_security_users for securityid 281, if it is null then it looks to the next table gl_security_roles for a security value for securityid 281, and finally if neither tale hold a value then it looks for the default value in gl_security.

The roleid is kept in the testusers table and testusers  can be joined to gl_security_users by userid and gl_security _roles by roleid.

As I'm not passing a value for userid or roleid as you might in a function I only have the inserted/deleted tables of affected ids.

I've read cursors are bad for performance so I don't get how each affected userid can join to testusers to use the roleid in the 'iscounted' column update.

I'm reading how I shouldn't think row based but rather set based, but I'm from a PHP background and have a mind set where I want to get every row and process the updates one by one. How should I be thinking about this?

Code Snippet:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
ALTER TRIGGER [dbo].[gl_courselog_iscounted_update]
   ON  [dbo].[testcourselog]
   AFTER INSERT,UPDATE
AS 
 
DECLARE @roleid int 
select @roleid = testusers.roleid FROM testusers,deleted d where testusers.userid=d.userid
 
print @roleid
 
DECLARE @r int 
select @r = count(*) from inserted 
 
IF UPDATE(grade) and @r > 0
BEGIN
 
IF @r = 1 
BEGIN
	SET NOCOUNT ON;
	UPDATE testcourselog SET iscounted=1 FROM testcourselog t JOIN deleted d ON t.courselogid = d.courselogid
	AND (
 
		SELECT ISNULL(
			(SELECT value FROM gl_security_users where gl_security_users.userid=d.userid 
				AND gl_security_users.securityid=281),
					(isnull((SELECT value FROM gl_security_roles where gl_security_roles.roleid=@roleid 
						AND gl_security_roles.securityid=281),
						(SELECT defaultvalue from gl_security where securityid=281)))
			)
		)=1
END
ELSE 
BEGIN
	UPDATE testcourselog SET iscounted=1 FROM testcourselog t JOIN deleted d ON t.courselogid = d.courselogid
	AND (
 
		SELECT ISNULL(
			(SELECT value FROM gl_security_users where gl_security_users.userid=d.userid 
				AND gl_security_users.securityid=281),
					(isnull((SELECT value FROM gl_security_roles where gl_security_roles.roleid=@roleid 
						AND gl_security_roles.securityid=281),
						(SELECT defaultvalue from gl_security where securityid=281)))
			)
		)=1
END
END
Open in New Window Select All

Answer : Multi row trigger join

Sorry - really not my day !!! :(
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
	UPDATE testcourselog 
	SET iscounted=1 
	FROM testcourselog t 
	JOIN 
		(SELECT 
			 courselogid = d.courselogid
			,[value] = COALESCE(u.value,r.value,s.defaultvalue,0)
		FROM deleted d
		JOIN testusers tu
			ON tu.userid=d.userid
		LEFT JOIN	gl_security_users u
			ON u.userid=d.userid 
			AND u.securityid=281
		LEFT JOIN	gl_security_roles r
			ON r.roleid=tu.roleid 
			AND r.securityid=281
		LEFT JOIN	gl_security s
			ON s.securityid=281
		) b
	ON t.courselogid = b.courselogid
	WHERE b.[value] = 1
Open in New Window Select All
Random Solutions  
 
programming4us programming4us