230 lines
No EOL
8.7 KiB
Transact-SQL
230 lines
No EOL
8.7 KiB
Transact-SQL
DROP PROCEDURE IF EXISTS dev.sp_Global_GenerateAsyncAuditTrigger
|
|
GO
|
|
|
|
CREATE PROCEDURE dev.sp_Global_GenerateAsyncAuditTrigger
|
|
@tableName nvarchar(50)
|
|
,@disabled bit = 0
|
|
AS
|
|
DECLARE
|
|
@newColumnList nvarchar(max)
|
|
,@oldColumnList nvarchar(max)
|
|
,@SQL nvarchar(max)
|
|
,@ColumnIntezmenyId nvarchar(1000) = '0'
|
|
,@ColumnTanevId nvarchar(1000) = '0'
|
|
,@JoinKeys nvarchar(4000);
|
|
|
|
SELECT @newColumnList = ISNULL(@newColumnList + ', ', '') + 'i.' + COLUMN_NAME + N' AS ''new.' + COLUMN_NAME + '''',
|
|
@oldColumnList = ISNULL(@oldColumnList + ', ', '') + 'd.' + COLUMN_NAME + N' AS ''old.' + COLUMN_NAME + ''''
|
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
WHERE TABLE_NAME = @tableName
|
|
AND TABLE_SCHEMA = 'dbo'
|
|
AND DATA_TYPE NOT IN ('varbinary', 'binary')
|
|
AND COLUMN_NAME NOT IN ('SERIAL', 'LASTCHANGED', 'CREATED', 'ID', 'C_INTEZMENYID', 'C_ALINTEZMENYID', 'C_TANEVID', 'C_ALTANEVID');
|
|
|
|
SELECT @ColumnIntezmenyId = CASE WHEN TABLE_NAME = 'T_INTEZMENY' THEN 'i.ID' ELSE 'i.' + COLUMN_NAME END
|
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
WHERE TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo' AND COLUMN_NAME IN ('C_INTEZMENYID', 'C_ALINTEZMENYID');
|
|
|
|
SELECT @ColumnTanevId = CASE WHEN TABLE_NAME = 'T_TANEV' THEN 'i.ID' ELSE 'i.' + COLUMN_NAME END
|
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
WHERE TABLE_NAME = @tableName AND TABLE_SCHEMA = 'dbo' AND COLUMN_NAME IN ('C_TANEVID', 'C_ALTANEVID');
|
|
|
|
SELECT @JoinKeys = COALESCE(@JoinKeys + ' AND ', '') + 'i.' + c.name + ' = d.' + c.name
|
|
FROM sys.key_constraints kc
|
|
INNER JOIN sys.index_columns ic ON ic.index_id = kc.unique_index_id AND ic.object_id = kc.parent_object_id
|
|
INNER JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
|
|
WHERE kc.parent_object_id = object_id('dbo.' + @tableName)
|
|
and kc.type = 'PK'
|
|
ORDER BY ic.index_column_id ASC;
|
|
|
|
SET @SQL = '
|
|
CREATE OR ALTER TRIGGER [tr_AsyncAudit' + UPPER(SUBSTRING(@tableName, 3, 100)) + '] ON [' + @tableName + ']
|
|
WITH EXECUTE AS ''kreta_tech_user''
|
|
FOR INSERT, UPDATE, DELETE
|
|
AS
|
|
DECLARE @rowcount INT = @@ROWCOUNT;
|
|
DECLARE @json NVARCHAR(MAX);
|
|
DECLARE @key INT = 0;
|
|
DECLARE @limit INT = 1000;
|
|
DECLARE @action TINYINT = 0;
|
|
DECLARE @now NVARCHAR(20) = CONVERT(NVARCHAR(20), GETDATE(), 120);
|
|
DECLARE @handle UNIQUEIDENTIFIER;
|
|
DECLARE @userid INT;
|
|
|
|
SET NOCOUNT ON;
|
|
|
|
SET @action += CASE WHEN EXISTS(SELECT * FROM inserted) THEN 1 ELSE 0 END;
|
|
SET @action += CASE WHEN EXISTS(SELECT * FROM deleted) THEN 2 ELSE 0 END;
|
|
|
|
IF @rowcount = 0 SET @rowcount = (SELECT COUNT(*) FROM inserted);
|
|
IF @rowcount = 0 SET @rowcount = (SELECT COUNT(*) FROM deleted);
|
|
|
|
IF @rowcount = 0 RETURN;
|
|
|
|
SET @userid = TRY_CAST(SESSION_CONTEXT(N''USERID'') AS INT);
|
|
' + IIF(EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = 'MODIFIER'), 'IF ISNULL(@userid, 0) = 0 AND (UPDATE(MODIFIER) OR UPDATE(CREATOR)) SET @userid = (SELECT TOP 1 NULLIF(ISNULL(MODIFIER, CREATOR), 0) FROM inserted);', '') + '
|
|
|
|
IF @rowcount > @limit
|
|
BEGIN
|
|
|
|
SELECT TOP 0 * INTO #audit_trigger_inserted FROM inserted UNION ALL SELECT TOP 0 * FROM inserted;
|
|
SELECT TOP 0 * INTO #audit_trigger_deleted FROM deleted UNION ALL SELECT TOP 0 * FROM deleted;
|
|
|
|
ALTER TABLE #audit_trigger_inserted ADD TRIGGER_ADDED_KEY INT NOT NULL IDENTITY(1, 1);
|
|
ALTER TABLE #audit_trigger_deleted ADD TRIGGER_ADDED_KEY INT NOT NULL IDENTITY(1, 1);
|
|
|
|
INSERT INTO #audit_trigger_inserted SELECT * FROM inserted;
|
|
INSERT INTO #audit_trigger_deleted SELECT * FROM deleted;
|
|
|
|
ALTER TABLE #audit_trigger_inserted ADD PRIMARY KEY CLUSTERED(TRIGGER_ADDED_KEY);
|
|
ALTER TABLE #audit_trigger_deleted ADD PRIMARY KEY CLUSTERED(TRIGGER_ADDED_KEY);
|
|
|
|
-- ALTER TABLE #audit_trigger_inserted ADD UNIQUE NONCLUSTERED (TRIGGER_ADDED_KEY);
|
|
-- ALTER TABLE #audit_trigger_deleted ADD UNIQUE NONCLUSTERED (TRIGGER_ADDED_KEY);
|
|
|
|
END
|
|
|
|
BEGIN DIALOG CONVERSATION @handle
|
|
FROM SERVICE AuditService
|
|
TO SERVICE ''AuditService''
|
|
ON CONTRACT AuditContract
|
|
WITH ENCRYPTION = OFF, LIFETIME = 10000;
|
|
|
|
WHILE (1 = 1)
|
|
BEGIN
|
|
|
|
IF @action = 1 -- INSERT
|
|
IF @rowcount > @limit
|
|
BEGIN
|
|
|
|
SET @json = (
|
|
SELECT TOP (@limit)
|
|
i.ID AS ID,
|
|
' + @ColumnTanevId + ' AS TID,
|
|
' + @ColumnIntezmenyId + ' AS IID,
|
|
ISNULL(i.MODIFIER, i.CREATOR) AS [UID],
|
|
' + @newColumnList + '
|
|
FROM #audit_trigger_inserted i
|
|
WHERE i.TRIGGER_ADDED_KEY > @key
|
|
ORDER BY i.TRIGGER_ADDED_KEY ASC
|
|
FOR JSON PATH, INCLUDE_NULL_VALUES
|
|
)
|
|
|
|
SELECT TOP (@limit) @key = TRIGGER_ADDED_KEY FROM #audit_trigger_inserted WHERE TRIGGER_ADDED_KEY > @key ORDER BY TRIGGER_ADDED_KEY;
|
|
|
|
END
|
|
ELSE
|
|
SET @json = (
|
|
SELECT
|
|
i.ID AS ID,
|
|
' + @ColumnTanevId + ' AS TID,
|
|
' + @ColumnIntezmenyId + ' AS IID,
|
|
ISNULL(i.MODIFIER, i.CREATOR) AS [UID],
|
|
' + @newColumnList + '
|
|
FROM inserted i
|
|
FOR JSON PATH, INCLUDE_NULL_VALUES
|
|
)
|
|
|
|
IF @action = 2 -- DELETE
|
|
IF @rowcount > @limit
|
|
BEGIN
|
|
|
|
SET @json = (
|
|
SELECT TOP (@limit)
|
|
d.ID AS ID,
|
|
' + replace(@ColumnTanevId, 'i.', 'd.') + ' AS TID,
|
|
' + replace(@ColumnIntezmenyId, 'i.', 'd.') + ' AS IID,
|
|
ISNULL(d.MODIFIER, d.CREATOR) AS [UID],
|
|
' + @oldColumnList + '
|
|
FROM #audit_trigger_deleted d
|
|
WHERE d.TRIGGER_ADDED_KEY > @key
|
|
ORDER BY d.TRIGGER_ADDED_KEY ASC
|
|
FOR JSON PATH, INCLUDE_NULL_VALUES
|
|
)
|
|
|
|
SELECT TOP (@limit) @key = TRIGGER_ADDED_KEY FROM #audit_trigger_deleted WHERE TRIGGER_ADDED_KEY > @key ORDER BY TRIGGER_ADDED_KEY;
|
|
|
|
END
|
|
ELSE
|
|
SET @json = (
|
|
SELECT
|
|
d.ID AS ID,
|
|
' + replace(@ColumnTanevId, 'i.', 'd.') + ' AS TID,
|
|
' + replace(@ColumnIntezmenyId, 'i.', 'd.') + ' AS IID,
|
|
ISNULL(d.MODIFIER, d.CREATOR) AS [UID],
|
|
' + @oldColumnList + '
|
|
FROM deleted d
|
|
FOR JSON PATH, INCLUDE_NULL_VALUES
|
|
)
|
|
|
|
IF @action = 3 --UPDATE
|
|
IF @rowcount > @limit
|
|
BEGIN
|
|
|
|
SET @json = (
|
|
SELECT TOP (@limit)
|
|
i.ID AS ID,
|
|
' + @ColumnTanevId + ' AS TID,
|
|
' + @ColumnIntezmenyId + ' AS IID,
|
|
ISNULL(i.MODIFIER, i.CREATOR) AS [UID],
|
|
' + @oldColumnList + ',
|
|
' + @newColumnList + '
|
|
FROM #audit_trigger_inserted i
|
|
INNER JOIN #audit_trigger_deleted d ON i.TRIGGER_ADDED_KEY = d.TRIGGER_ADDED_KEY
|
|
WHERE i.TRIGGER_ADDED_KEY > @key
|
|
ORDER BY i.TRIGGER_ADDED_KEY ASC
|
|
FOR JSON PATH, INCLUDE_NULL_VALUES
|
|
)
|
|
|
|
SELECT TOP (@limit) @key = TRIGGER_ADDED_KEY FROM #audit_trigger_inserted WHERE TRIGGER_ADDED_KEY > @key ORDER BY TRIGGER_ADDED_KEY;
|
|
|
|
END
|
|
ELSE
|
|
SET @json = (
|
|
SELECT
|
|
i.ID AS ID,
|
|
' + @ColumnTanevId + ' AS TID,
|
|
' + @ColumnIntezmenyId + ' AS IID,
|
|
ISNULL(i.MODIFIER, i.CREATOR) AS [UID],
|
|
' + @oldColumnList + ',
|
|
' + @newColumnList + '
|
|
FROM inserted i
|
|
INNER JOIN deleted d ON ' + @JoinKeys + '
|
|
FOR JSON PATH, INCLUDE_NULL_VALUES
|
|
)
|
|
|
|
IF @json IS NULL BREAK;
|
|
|
|
SET @json = CONCAT(
|
|
''{'',
|
|
''"ENTITY":"' + @tableName + '",'',
|
|
''"REASON":"'', CHOOSE(@action, ''New'', ''Removed'', ''Modified''), ''",'',
|
|
''"DATETIME":"'', @now, ''",'',
|
|
''"ACTION":'', @action, '','',
|
|
''"HOST":"'', HOST_NAME(), ''",'',
|
|
''"LOGIN":"'', REPLACE(ORIGINAL_LOGIN(), ''\'', ''\\''), ''",'',
|
|
''"USERID":'', COALESCE(CAST(@userid AS VARCHAR(10)), ''null''), '','',
|
|
''"ROWCOUNT":'', @rowcount, '', '',
|
|
''"ROWS": '', @json,
|
|
''}'');
|
|
|
|
SEND ON CONVERSATION @handle MESSAGE TYPE AuditMessage (@json);
|
|
|
|
IF @rowcount <= @limit BREAK;
|
|
|
|
END
|
|
|
|
END CONVERSATION @handle;
|
|
'
|
|
|
|
-- SELECT @SQL
|
|
EXEC sys.sp_executesql @SQL;
|
|
|
|
IF @disabled = 1
|
|
BEGIN
|
|
|
|
SET @SQL = 'DISABLE TRIGGER [tr_AsyncAudit' + UPPER(SUBSTRING(@tableName, 3, 100)) + '] ON [' + @tableName + ']';
|
|
EXEC(@SQL);
|
|
|
|
END
|
|
GO |