كيفية الحصول على نص الإجراء قبل التغيير من DDL الزناد

StackOverflow https://stackoverflow.com/questions/1521598

سؤال

أنا أخلق الزناد لتتبع كيفية وجود نص الإجراء 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top