Sql-Server
為過程引用的所有表生成 GRANT
我的數據庫中有幾個儲存過程,每個儲存過程都從幾個表中選擇。我需要構造一個語句,我可以在其中給它一個儲存過程,並為該儲存過程使用的所有表獲取授權選擇語句。我需要這個,因為我的過程使用 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,它無法解析文本以查找所有表引用,或探索所有可能的排列。