1

SQL Server 2008 R2 の CLR Update トリガーを作成しています。トリガーは、更新された値を、同じ SQL Server インスタンスでホストされている別のデータベースのテーブルに書き込む必要があります。トリガー内から次の接続文字列で作成された接続を開こうとすると、「SecurityException」が発生します。

...new SqlConnection("データ ソース=(ローカル);初期カタログ=[マイ データベース];統合セキュリティ=True")

アセンブリのアクセス許可レベルを のままにしておくことが強く望まれSAFEます。リモート データベースに接続するには、アセンブリのアクセス許可レベルを に設定する必要があると確信していEXTERNAL_ACCESSますが、そのアクセス許可レベルで同じ SQL Server インスタンス内の別のデータベースに接続することは可能SAFEですか?

ありがとう。

4

2 に答える 2

2

はい、 としてマークされた Assembly 内に存在する SQLCLR トリガーで別のデータベースを参照することは間違いなく可能SAFEです。質問で発生したエラーは、単に通常の/外部接続文字列を使用したことが原因であり、これには of が必要PERMISSION_SETですEXTERNAL_ACCESS。ただし、インプロセス/内部接続文字列を"Context Connection = true;"使用すると、3 部構成のオブジェクト名を介して別のデータベースを参照するクエリを含め、任意のクエリを実行できます。

次のコードでこれを行うことができました。

メイン テーブル (TestDB1 内):

CREATE TABLE dbo.Stuff
(
    [Id] INT IDENTITY(1, 1) NOT NULL PRIMARY KEY, 
    [Something] NVARCHAR(50) NOT NULL
);

監査テーブル (TestDB2 内):

CREATE TABLE dbo.AuditLog
(
    AuditLogID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY, 
    EventTime DATETIME NOT NULL DEFAULT (GETDATE()),
    BeforeValue NVARCHAR(50) NULL,
    AfterValue NVARCHAR(50) NULL
);

メイン テーブルの SQLCLR トリガー (部分的なコード):

string _AuditSQL = @"
    INSERT INTO TestDB2.dbo.AuditLog (BeforeValue, AfterValue)
        SELECT del.Something, ins.Something
        FROM   INSERTED ins
        FULL OUTER JOIN DELETED del
                     ON del.Id = ins.Id;
";

SqlConnection _Connection = new SqlConnection("Context Connection = true");
SqlCommand _Command = _Connection.CreateCommand();
_Command.CommandText = _AuditSQL;

try
{
    _Connection.Open();
    _Command.ExecuteNonQuery();
}
finally
{
    _Command.Dispose();
    _Connection.Dispose();
}

テスト クエリ:

USE [TestDB1];
SELECT * FROM dbo.Stuff;
---
INSERT INTO dbo.Stuff (Something) VALUES ('qwerty');
INSERT INTO dbo.Stuff (Something) VALUES ('asdf');

SELECT * FROM dbo.Stuff;
SELECT * FROM TestDB2.dbo.AuditLog;
---
UPDATE  tab
SET     tab.Something = 'dfgdfgdfgdfgdfgdfgd'
FROM    dbo.Stuff tab
WHERE   tab.Id = 2;

SELECT * FROM dbo.Stuff;
SELECT * FROM TestDB2.dbo.AuditLog;
于 2015-06-25T17:27:06.643 に答える
0

それは不可能のようです。ただし、T-SQL ステートメントは、[DatabaseName].[dbo].[TableName] を使用して、同じインスタンス内の別のデータベースを参照できます。CLR トリガーで複雑なロジックを実行してから、単純な T-SQL ストアド プロシージャを呼び出してパラメーターを渡すことで、2 番目のデータベースに最終的な挿入を行うことができます。

于 2012-09-14T05:40:11.387 に答える