はい、 としてマークされた 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;