كيفية الحصول على نص الإجراء قبل التغيير من DDL الزناد
-
19-09-2019 - |
سؤال
أنا أخلق الزناد لتتبع كيفية وجود نص الإجراء ALTER
إد.
داخل قاعدة بيانات DDL Trigger، من الممكن الوصول إلى نص الإجراء الحالي /EVENT_INSTANCE/TSQLCommand
.
حتى بعد التحقيق EVENTDATA()
, ، لم يكن يحتوي على قيم للتعريف السابق للإجراءات من قبل ALTER
.
هل هناك طريقة لاسترداد النص السابق مثل كيفية الوصول إلى القيم المحذوفة في مشغلات DML باستخدام DELETED
جدول؟
create trigger trgDDLAuditQuery
on database
for alter_procedure
as
begin
set nocount on;
declare @data xml
set @data = EVENTDATA()
insert dbo.tblQueryAudit(ObjectName, TSQLCommand)
select @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(256)'),
--; Only gets currently changed procedure text, not previous one
@data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(max)')
end
GO
المحلول
يعمل الزناد بعد التغيير، حتى الآن بقدر ما أستطيع أن أخبر أنه لا يوجد إمكانية الوصول إلى القيم "قبل". يتم تعريف EventData () وليس هناك مخصص ل "السابق". نتيجة لذلك، سيكون عليك تسجيل القيمة الحالية فقط في السجل. ومع ذلك، إذا قمت بإعطاء سجل تسجيل الدخول الخاص بك مع هذا الأمر:
INSERT INTO dbo.tblQueryAudit
(ObjectName, TSQLCommand)
SELECT
o.Name,m.definition
FROM sys.objects o
INNER JOIN sys.sql_modules m ON o.object_id=m.object_id
WHERE type='P'
يمكنك استخدام الزناد الخاص بك ولا يزال لديك صورة كاملة لجميع التغييرات. سيكون لسجلك جميع الإصدارات السابقة بالإضافة إلى الإصدار الحالي من كل إجراء. يمكنك استخدام الإصدار الخاص بي من الزناد (انظر أدناه)، حيث ستحصل على الوصول إلى بعض الأعمدة الأخرى من SYS.Objects و sys.sql_modules، مثل:
uses_ansi_nulls
uses_quoted_identifier
is_schema_bound
null_on_null_input
principal_id
والتي قد تكون مفيدة لسجل كذلك. نسخة بديلة:
CREATE trigger trgDDLAuditQuery
on database
for alter_procedure
as
begin
set nocount on;
DECLARE @EventData xml
SET @EventData=EVENTDATA()
INSERT INTO dbo.tblQueryAudit
(ObjectName, TSQLCommand) --hope you have datetime column that defaults to GETDATE()
SELECT
o.Name,m.definition
FROM sys.objects o
INNER JOIN sys.sql_modules m ON o.object_id=m.object_id
WHERE o.Name=@EventData.value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(max)')
--modify as necessary AND type='P'
end
GO