不允許在觸發器執行的函式上更新或選擇的權限
在同一個 SQL Server 2014 實例上使用兩個數據庫 A 和 B,我編寫了一系列腳本來嘗試執行以下操作(用非常高級的虛擬碼編寫):
- 使用者更新表
A.dbo.Main
A.dbo.Main
有一個UPDATE, DELETE, INSERT
呼叫儲存過程的觸發器A.CallProcInB
A.CallProcInB
然後呼叫 B 中的儲存過程B.RunComponentsUpdate
B.RunComponentsUpdate
然後合併一個視圖和一個名為B.dbo.A_View
and的表B.dbo.B_Table
。問題是我已經讓這一系列腳本在執行 SQL Server 2014 Express 的個人電腦上完美執行,數據庫 A 和 B 的架構設置完全相同,但是當我在公司執行 SQL Server 的主伺服器上設置所有內容時2014 我收到以下錯誤消息:
System.Data.Odbc.OdbcException (0x80131937):
錯誤
$$ 42000 $$ $$ Microsoft $$$$ ODBC SQL Server Driver $$$$ SQL Server $$
對象“B_Table”、數據庫“B”、模式“dbo”的 SELECT 權限被拒絕。錯誤$$ 42000 $$ $$ Microsoft $$$$ ODBC SQL Server Driver $$$$ SQL Server $$
對象“B_Table”、數據庫“B”、模式“dbo”的 UPDATE 權限被拒絕。
我已經嘗試讓使用者啟動初始觸發器 A 和 B 上的所有權限,因為這足以解決我的個人電腦伺服器上的問題。但是,基本上給予“上帝”特權還不足以解決伺服器上的這個錯誤。
事實證明,這個解決方案比預期的要簡單得多。我曾提到有一個指定的使用者開始啟動觸發器,並且我已授予該使用者“上帝”特權。
事實證明,在我缺乏經驗的情況下,我給了那個使用者
db_denywrite
anddb_denyread
,認為這些實際上是賦予使用者拒絕其他人讀取或寫入 B的能力的特權。然而,情況恰恰相反,因為這些“權限”實際上拒絕了我的上帝使用者讀取或寫入 B。取消選中這些框,現在一切正常。
當您沒有啟用跨數據庫所有權連結和 TRUSTWORTHY 等功能並且沒有以
sa
;-) 身份登錄時,會出現權限錯誤。這與我在 DBA.SE 上對另一個問題的回答中描述(並已解決)的問題非常相似:
但是,在那種情況下,數據庫 B 中有一個觸發器,而這裡的情況並非如此。儘管如此,這應該很容易解決,並且將使用類似於其他答案中描述的設置。
以下是您需要針對特定問題執行的步驟(所有這些都顯示在其他答案中):
- 在數據庫 A 中創建證書。
A.dbo.CallProcInB
使用該證書籤署儲存過程。- 將證書備份到文件或臨時表中(如鍊接答案所示)。
- 在數據庫 B 中創建相同的證書(通過從備份文件或臨時表中獲取它來完成,如鍊接的答案所示)。
- 從該證書創建使用者。
EXECUTE
將儲存過程授予B.dbo.RunComponentsUpdate
新的基於證書的使用者。這應該就是你所需要的。
請注意,對儲存過程的任何更改
A.dbo.CallProcInB
都會導致其失去簽名。在這些情況下,只需ADD SIGNATURE
再次執行。