同じSQL Server 2014インスタンス上に2つのデータベースAとBを使用して、以下を実行しようとする一連のスクリプトを記述しました(非常に高レベルの疑似コードで記述)。
ユーザー更新テーブルA.dbo.Main
A.dbo.Main
には、ストアドプロシージャを呼び出すUPDATE, DELETE, INSERT
に対するトリガーがありますA.CallProcInB
A.CallProcInB
次に、B.RunComponentsUpdate
というBのストアドプロシージャを呼び出します。
次に、B.RunComponentsUpdate
は、ビューとB.dbo.A_View
およびB.dbo.B_Table
というテーブルをマージします。
問題は、SQL Server 2014 Expressを実行しているパーソナルコンピューターでこれらの一連のスクリプトを完全に機能させることです。データベースAとBのスキーマ設定はまったく同じですが、SQL Serverを実行している会社のメインサーバーにすべてをセットアップすると、 2014次のエラーメッセージが表示されます。
System.Data.Odbc.OdbcException(0x80131937):
エラー[42000] [Microsoft] [ODBC SQL Serverドライバー] [SQL Server]
オブジェクト 'B_Table'、データベース 'B'、スキーマ 'dbo'に対するSELECT権限が拒否されました。エラー[42000] [Microsoft] [ODBC SQL Server Driver] [SQL Server]
オブジェクト 'B_Table'、データベース 'B'、スキーマ 'dbo'に対するUPDATE権限が拒否されました。
これで私のパーソナルコンピュータサーバーの問題を修正するには十分だったので、AとBの両方ですべての特権を初期トリガーをアクティブにするユーザーに与えようとしました。ただし、基本的に「神」の特権を与えるだけでは、サーバーでこのエラーを解決するのに十分ではありません。
このソリューションは予想よりもはるかに単純であることがわかりました。最初にトリガーをアクティブにする特定のユーザーがいること、およびそのユーザーに「神」の特権を与えたと述べました。
結局のところ、私の経験から、そのユーザーにdb_denywrite
およびdb_denyread
、それらを実際にユーザーにBへの読み取りまたは書き込みからdeny他のユーザーに権限を与える特権であると考えました。
ただし、これらの「許可」によって実際に私の神のユーザーがBへの読み取りまたは書き込みを拒否したため、これはケースの逆です。ボックスをオフにすると、すべてが機能します。
データベース間の所有権の連鎖やTRUSTWORTHYが有効になっておらず、sa
;-)としてログインしていない場合は、権限エラーが予想されます。
これは、DBA.SEの別の質問に対する私の回答で説明されている(そして解決されている)問題と非常に似ています。
ただし、その場合、データベースBにトリガーがあり、それはここの状況ではありません。それでも、これはかなり簡単に解決できるはずであり、他の回答で説明されているものと同様の設定を使用します。
特定の問題に必要な手順は次のとおりです(すべて他の回答に示されています)。
A.dbo.CallProcInB
ストアドプロシージャに署名します。B.dbo.RunComponentsUpdate
ストアドプロシージャのEXECUTE
を付与します。それで十分です。
anyA.dbo.CallProcInB
ストアドプロシージャへの変更により、署名が失われることに注意してください。このような場合は、もう一度ADD SIGNATURE
を実行してください。