SQL Serverを使用して、トリガー内からトリガーするSQLを監査する方法はありますか?
プロファイラーなしでデータベースに対してトリガーを起動するSQLクエリを知る必要があります。
ありがとう
これを実行するトリガーがいくつかあり、DBCC INPUTBUFFER
は一般的にそれを行うための最良の方法です。注意:出力は4000文字に制限されています。非常に長いクエリは切り捨てられます。
DECLARE @sql nvarchar(max)
SET @sql = 'DBCC INPUTBUFFER(' + CAST(@@SPID AS nvarchar(100)) + ')'
CREATE TABLE #SQL (
EventType varchar(100),
Parameters int,
EventInfo nvarchar(max)
)
INSERT INTO #SQL
EXEC sp_executesql @sql
SELECT @sql = EventInfo FROM #SQL
DROP TABLE #SQL
この最後に、@sql
には、現在のリクエストのクエリが含まれます。また、一時テーブルの代わりにテーブル変数を簡単に使用することもできます。
SQLクエリもキャプチャするDDLトリガーのサンプルを次に示します。
CREATE TRIGGER Audit_DDL
ON DATABASE
FOR CREATE_TABLE, ALTER_TABLE, DROP_TABLE
AS
DECLARE
@event xml;
SET
@event = EVENTDATA();
INSERT INTO Audit_DDL_Events
VALUES
(
REPLACE(CONVERT(varchar(50),
@event.query('data(/EVENT_INSTANCE/PostTime)')), 'T', ' ')
,
CONVERT(varchar(150),
@event.query('data(/EVENT_INSTANCE/LoginName)'))
,
CONVERT(varchar(150),
@event.query('data(/EVENT_INSTANCE/UserName)'))
,
CONVERT(varchar(150),
@event.query('data(/EVENT_INSTANCE/DatabaseName)'))
,
CONVERT(varchar(150),
@event.query('data(/EVENT_INSTANCE/SchemaName)'))
,
CONVERT(varchar(150),
@event.query('data(/EVENT_INSTANCE/ObjectName)'))
,
CONVERT(varchar(150),
@event.query('data(/EVENT_INSTANCE/ObjectType)'))
,
CONVERT(varchar(max),
@event.query('data(/EVENT_INSTANCE/TSQLCommand/CommandText)'))
);
適切な表の結果:
CREATE TABLE Audit_DDL_Events
(
DDL_Event_Time datetime
,
DDL_Login_Name varchar(150)
,
DDL_User_Name varchar(150)
,
DDL_Database_Name varchar(150)
,
DDL_Schema_Name varchar(150)
,
DDL_Object_Name varchar(150)
,
DDL_Object_Type varchar(150)
,
DDL_Command varchar(max)
);
次のようになります:
以下は、現在のバッチ/ステートメントを取得するトリックを行うようです:
SELECT current_batch = dest.text
, current_statement = SUBSTRING(dest.text, dem.statement_start_offset/2, CASE WHEN dem.statement_end_offset=-1 THEN 8000 ELSE (dem.statement_end_offset-dem.statement_start_offset)/2 END)
FROM sys.dm_exec_requests dem CROSS APPLY sys.dm_exec_sql_text(dem.sql_handle) dest
WHERE session_id = @@SPID
iIRCが呼び出しがストアドプロシージャに対するものである場合、要求の送信方法(アドホックSQL、準備されたプロシージャ呼び出しなど)によっては、呼び出しのテキストではなく、プロシージャのコードが返される場合があります。トリガーで、探しているものではなくトリガーのコードを取得することになるかどうかは不明なので、テストする必要があります。
バッチとステートメントの違いを確認するには、次のように実行します。
DECLARE @current_batch NVARCHAR(MAX), @current_statement NVARCHAR(MAX)
-- start of statement that will be returned by itself
SELECT @current_batch = dest.text
, @current_statement = SUBSTRING(dest.text, dem.statement_start_offset/2, CASE WHEN dem.statement_end_offset=-1 THEN 8000 ELSE (dem.statement_end_offset-dem.statement_start_offset)/2 END)
FROM sys.dm_exec_requests dem CROSS APPLY sys.dm_exec_sql_text(dem.sql_handle) dest
WHERE session_id = @@SPID
-- end of statement that will be returned by itself
-- results:
PRINT '---- BATCH --------------------------------------------'
PRINT @current_batch
PRINT '---- STATEMENT ----------------------------------------'
PRINT @current_statement
sQL Server Management Studioなどを使用します。