Sql-Server

不允許在觸發器執行的函式上更新或選擇的權限

  • March 7, 2017

在同一個 SQL Server 2014 實例上使用兩個數據庫 A 和 B,我編寫了一系列腳本來嘗試執行以下操作(用非常高級的虛擬碼編寫):

  1. 使用者更新表A.dbo.Main
  2. A.dbo.Main有一個UPDATE, DELETE, INSERT呼叫儲存過程的觸發器A.CallProcInB
  3. A.CallProcInB然後呼叫 B 中的儲存過程B.RunComponentsUpdate
  4. B.RunComponentsUpdate然後合併一個視圖和一個名為B.dbo.A_Viewand的表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_denywriteand db_denyread,認為這些實際上是賦予使用者拒絕其他人讀取或寫入 B的能力的特權。

然而,情況恰恰相反,因為這些“權限”實際上拒絕了我的上帝使用者讀取或寫入 B。取消選中這些框,現在一切正常。

當您沒有啟用跨數據庫所有權連結和 TRUSTWORTHY 等功能並且沒有以sa;-) 身份登錄時,會出現權限錯誤。

這與我在 DBA.SE 上對另一個問題的回答中描述(並已解決)的問題非常相似:

使用跨數據庫證書時觸發器中的權限

但是,在那種情況下,數據庫 B 中有一個觸發器,而這裡的情況並非如此。儘管如此,這應該很容易解決,並且將使用類似於其他答案中描述的設置。

以下是您需要針對特定問題執行的步驟(所有這些都顯示在其他答案中):

  1. 在數據庫 A 中創建證書。
  2. A.dbo.CallProcInB使用該證書籤署儲存過程。
  3. 將證書備份到文件或臨時表中(如鍊接答案所示)。
  4. 在數據庫 B 中創建相同的證書(通過從備份文件或臨時表中獲取它來完成,如鍊接的答案所示)。
  5. 從該證書創建使用者。
  6. EXECUTE將儲存過程授予B.dbo.RunComponentsUpdate新的基於證書的使用者。

應該就是你所需要的。

請注意,對儲存過程的任何更改A.dbo.CallProcInB都會導致其失去簽名。在這些情況下,只需ADD SIGNATURE再次執行。

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