code_junkie

Using SQL to search for a set in a one-to-many relationship

Nov 14th, 2011
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.14 KB | None | 0 0
  1. select r.roleid
  2. from role r
  3. where not exists (select * from role_permissions rp where rp.roleid = r.roleid and rp.permissionid not in (1,2,3,4)) -- id of permissions
  4. and (select count(*) from role_permissions rp where rp.roleid = r.roleid) = 4 -- number of permissions
  5.  
  6. SELECT roleid FROM role_permission t1
  7. WHERE NOT EXISTS (
  8. (SELECT permissionid FROM role_permission t2 WHERE t2.roleid = t1.roleid
  9. MINUS
  10. SELECT permissionid FROM role_permission WHERE roleid = 'Admin')
  11. UNION
  12. (SELECT permissionid FROM role_permission t2 WHERE roleid = 'Admin'
  13. MINUS
  14. SELECT permissionid FROM role_permsission t2 WHERE t2.roleid = t1.roleid)
  15. )
  16.  
  17. CREATE PROC get_roles_for_permissions (@list nvarchar(max)) -- @list is a comma separated list of your permission ids
  18. AS
  19. SET NOCOUNT ON
  20.  
  21. BEGIN
  22.  
  23. DECLARE @index INT, @start_index INT, @id INT
  24. DECLARE @permission_ids TABLE (id INT)
  25.  
  26. SELECT @index = 1
  27. SELECT @start_index = 1
  28. WHILE @index <= DATALENGTH(@list)
  29. BEGIN
  30.  
  31. IF SUBSTRING(@list,@index,1) = ','
  32. BEGIN
  33. SELECT @id = CAST(SUBSTRING(@list, @start_index, @index - @start_index ) AS INT)
  34. INSERT INTO @permission_ids ([id]) VALUES (@id)
  35. SELECT @start_index = @index + 1
  36. END
  37. SELECT @index = @index + 1
  38. END
  39. SELECT @id = CAST(SUBSTRING(@list, @start_index, @index - @start_index ) AS INT)
  40. INSERT INTO @permission_ids ([id]) VALUES (@id)
  41.  
  42. SELECT
  43. r.roleid
  44. FROM
  45. role r
  46. INNER JOIN
  47. role_permission rp
  48. ON r.roleid = rp.roleid
  49. INNER JOIN
  50. @permission_ids ids
  51. ON
  52. rp.permissionid = ids.id
  53. GROUP BY r.roleid
  54. HAVING(SELECT COUNT(*)
  55. FROM role_permission
  56. WHERE roleid = r.roleid) = (SELECT COUNT(*) FROM @permission_ids)
  57.  
  58. END
  59.  
  60. CREATE TABLE [dbo].[role](
  61. [roleid] [int] IDENTITY(1,1) NOT NULL,
  62. [name] [nvarchar](50)
  63. )
  64.  
  65. CREATE TABLE [dbo].[permission](
  66. [permissionid] [int] IDENTITY(1,1) NOT NULL,
  67. [name] [nvarchar](50)
  68. )
  69.  
  70. CREATE TABLE [dbo].[role_permission](
  71. [roleid] [int],
  72. [permissionid] [int]
  73. )
  74.  
  75. INSERT INTO role(name) VALUES ('Role1')
  76. INSERT INTO role(name) VALUES ('Role2')
  77. INSERT INTO role(name) VALUES ('Role3')
  78. INSERT INTO role(name) VALUES ('Role4')
  79.  
  80. INSERT INTO permission(name) VALUES ('Permission1')
  81. INSERT INTO permission(name) VALUES ('Permission2')
  82. INSERT INTO permission(name) VALUES ('Permission3')
  83. INSERT INTO permission(name) VALUES ('Permission4')
  84.  
  85. INSERT INTO role_permission(roleid, permissionid) VALUES (1, 1)
  86. INSERT INTO role_permission(roleid, permissionid) VALUES (1, 2)
  87. INSERT INTO role_permission(roleid, permissionid) VALUES (1, 3)
  88. INSERT INTO role_permission(roleid, permissionid) VALUES (1, 4)
  89. INSERT INTO role_permission(roleid, permissionid) VALUES (2, 2)
  90. INSERT INTO role_permission(roleid, permissionid) VALUES (2, 3)
  91. INSERT INTO role_permission(roleid, permissionid) VALUES (2, 4)
  92. INSERT INTO role_permission(roleid, permissionid) VALUES (3, 3)
  93. INSERT INTO role_permission(roleid, permissionid) VALUES (3, 4)
  94. INSERT INTO role_permission(roleid, permissionid) VALUES (4, 4)
  95.  
  96. EXEC get_roles_for_permissions '3,4' -- RETURNS roleid 3
  97.  
  98. id int(10)
  99. name varchar(45)
  100. value int(10)
  101.  
  102. Permission: Role Role_Permission
  103. id name value id name roleid permissionid
  104. -- ---- ----- -- ---- ------ ------------
  105. 1 Read 8 1 Admin 1 1
  106. 2 Write 16 2 DataAdmin 1 2
  107. 3 Update 32 3 User 1 3
  108. 4 Delete 64 1 4
  109. 2 1
  110. 2 3
  111. 2 4
  112.  
  113. SELECT x.roleid, sum(value) FROM role_permission x
  114. inner join permission p
  115. on x.permissionid = p.id
  116. Group by x.roleid
  117.  
  118. roleid sum(value)
  119. ------ ----------
  120. 1 120 (the sum of permissions 1+2+3+4 = 120)
  121. 2 104 (the sum of permissions 1+3+4 = 104)
  122.  
  123. SELECT * FROM role r
  124. WHERE r.rolid = (SELECT x.roledid
  125. FROM role_permission
  126. WHERE x.permissionid in (1,2,3,4);
Add Comment
Please, Sign In to add comment