當 sp_executesql 或 EXECUTE 語句執行字元串時,字元串將作為它的自包含批處理執行。SQL Server 會將字元串中的一個或多個 Transact-SQL 語句編譯為獨立於批處理(包含 sp_executesql 或 EXECUTE 語句)執行計劃的執行計劃。 跟許可權有什麼關係 ...
當 sp_executesql 或 EXECUTE 語句執行字元串時,字元串將作為它的自包含批處理執行。
SQL Server 會將字元串中的一個或多個 Transact-SQL 語句編譯為獨立於批處理(包含 sp_executesql 或 EXECUTE 語句)執行計劃的執行計劃。
跟許可權有什麼關係?也就是說通過 sp_executesql 或 EXECUTE執行的sql被編譯為獨立的批處理,並不是當前用戶可以直接執行的,還是通過問題來說明吧。
創建用戶
直接上例子,創建一個用戶,通過一個用戶執行非動態sql的存儲過程和動態sql的存儲過程看這其中的許可權問題
以新創建用戶的身份執行非動態sql和動態sql的存儲過程
創建一個非動態sql的存儲過程,授權給ReadWriteUser執行這個存儲過程的許可權
以ReadWriteUser這個用戶的身份執行存儲過程TestPrivilege_NoDynamic,沒有問題
新創建一個以sp_executesql執行動態sql的存儲過程,同樣授權給ReadWriteUser這個存儲過程的執行許可權
以ReadWriteUser這個用戶的身份執行存儲過程TestPrivilege_WithDynamic,此時是執行失敗的,即便是ReadWriteUser具有執TestPrivilege_WithDynamic這個存儲過程的許可權
此時如果給ReadWriteUser授權表上的讀的許可權:grant select on T1 to ReadWriteUser,再次執行TestPrivilege_WithDynamic
然後再執行存儲過程,是沒有問題的
用戶雖然有執行存儲過程的許可權,因為給User授予了執行存儲過程的許可權(grant execute on TestPrivilege_WithDynamic to ReadWriteUser)
但是如果存儲過程中有動態sql,就會出現“The SELECT(或者Insert,Update,Delete)permission was denied on the object '***'”
此時就需要給User授予具體的表上的對應的SELECT(或者Insert,Update,Delete)許可權,然後才能正常地執行包含動態sql的存儲過程
另外一種方式是在存儲過程中WITH EXECUTE AS OWNER,
WITH EXECUTE AS OWNER只需授予用戶對模塊自身的許可權,而無需授予用戶對被引用對象的顯式許可權。
也就是說,在存儲過程中加上了WITH EXECUTE AS OWNER,就不用再授予給用戶具體對象的許可權
也即如下