Sql-Server

為過程引用的所有表生成 GRANT

  • April 23, 2020

我的數據庫中有幾個儲存過程,每個儲存過程都從幾個表中選擇。我需要構造一個語句,我可以在其中給它一個儲存過程,並為該儲存過程使用的所有表獲取授權選擇語句。我需要這個,因為我的過程使用 sp_executesql,因此使用者需要對錶的顯式權限,因為 sp_executesql 使得對儲存過程的執行權限不夠(您可能知道使用者也需要對該 SP 使用的表的選擇權限)。

到目前為止,我已經完成了以下動態 SQL 語句,但是,它僅在儲存過程僅從一個表中選擇時才有效。我完全理解,由於 where 子句中的子查詢,它不再適用。

select 'GRANT SELECT ON [' + schema_name(schema_id) + '].[' + name + '] TO [User1]'
from sys.tables 
where name like (SELECT distinct t.name
FROM sys.sql_dependencies d 
INNER JOIN sys.procedures p ON p.object_id = d.object_id
INNER JOIN sys.tables     t ON t.object_id = d.referenced_major_id
where P.NAME LIKE 'myproc')

SP 使用超過 1 個表時出錯:

子查詢返回超過 1 個值。當子查詢跟隨 =、!=、<、<=、>、>= 或子查詢用作表達式時,這是不允許的。

儲存過程使用的每個表所需的輸出:

GRANT SELECT ON [dbo].[table1] TO [User1]

還有另一種方法可以實現這一目標嗎?

錯誤資訊是正確的。您不能LIKE反對查詢的輸出,除非您以某種方式明確將該輸出限制為一行(這不是您想要做的)。只需執行連接…您可以清除重複項,但沒有理由(如果可能,兩次授予同一張表不會傷害任何東西)。也請使用QUOTENAME()而不是手動添加[]自己。

DECLARE @sql nvarchar(max) = N'';

SELECT @sql += CHAR(13) + CHAR(10) + N'GRANT SELECT ON ' 
 + QUOTENAME(s.name) + N'.' + QUOTENAME(t.name) + N'] TO [User1];'
FROM sys.tables AS t
INNER JOIN sys.schemas AS s
ON t.schema_id = s.schema_id
INNER JOIN sys.sql_dependencies AS d
ON d.referenced_major_id = t.object_id
INNER JOIN sys.procedures AS p
ON p.[object_id] = d.[object_id]
WHERE p.name = N'myproc';

PRINT @sql;
-- EXEC sys.sp_executesql @sql;

請記住,sys.sql_dependencies不一定會擷取所有內容,例如,如果儲存過程使用動態 SQL,它無法解析文本以查找所有表引用,或探索所有可能的排列。

引用自:https://dba.stackexchange.com/questions/265712