سؤال

أحاول تصحيح مقيم صيغة معقد إلى حد ما مكتوب في T-SQL UDFs (لا تسأل) ذلك بشكل متكرر (ولكن بشكل غير مباشر من خلال وظيفة وسيطة) يطلق على نفسه، بلاه، بلاه.

وبطبيعة الحال، لدينا خطأ.

الآن، باستخدام عبارات PRINT (التي يمكن قراءتها بعد ذلك من ADO.NET عن طريق تنفيذ معالج لحدث InfoMessage)، يمكنني محاكاة تتبع الإجراءات المخزنة.

يؤدي القيام بنفس الشيء مع UDF إلى ظهور رسالة وقت الترجمة:

Invalid use of side-effecting or time-dependent operator in 'PRINT' within a function.

تلقيت الرسالة (PRINT تقوم ببعض الأشياء مثل إعادة الضبط @@ROWCOUNT وهو بالتأكيد أمر محظور في UDFs، ولكن كيف يمكنني تتبع المكالمات؟أريد طباعة هذا التتبع، حتى أتمكن من دراسته دون تشتيت انتباهي من خلال التنقل عبر المكالمات في مصحح الأخطاء...

يحرر: لقد حاولت استخدام ملف تعريف SQL (كانت هذه المرة الأولى بالنسبة لي)، لكن لا يمكنني معرفة ما يجب تتبعه:على الرغم من أنه يمكنني الحصول على التتبع لإخراج الاستعلامات المرسلة إلى قاعدة البيانات، إلا أنها غير شفافة بمعنى أنه لا يمكنني الانتقال إلى Expression-UDFs التي تسمى:يمكنني تتبع الإجراء المخزن الفعلي الذي تم استدعاؤه، لكن UDFs التي تم استدعاؤها بواسطة هذا الإجراء غير مدرجة.هل فاتني شيء؟لا أظن...

التعديل رقم 2: على الرغم من أن الإجابة المقبولة (التلقائية) تتبع استدعاءات الوظائف - فهي مفيدة جدًا، شكرًا - فهي لا تساعد في معرفة المعلمات التي كانت اجتاز إلى الوظيفة.وهذا بالطبع ضروري في تصحيح الأخطاء وظائف العودية.سأقوم بالنشر إذا وجدت أي حل على الإطلاق ...

هل كانت مفيدة؟

المحلول

لماذا لا تستخدم SQL Profiler مع إضافة أحداث على مستوى البيان؟

يحرر:إضافة أحداث للإجراءات المخزنة:SP: STMT بدء أو SP: STMT مكتمل استخدام المتغيرات للتصحيح إذا لزم الأمر ، أيset @debug='أنا هنا';على الرغم من أن إجراءات UDF ليست إجراءات مخزنة تقنيًا، إلا أنه سيتم تتبعها من خلال الأحداث على مستوى البيان.

نصائح أخرى

في ملف تعريف SQL، تحتاج إلى:SP: البدء، SP: StmtStarting، SP: مكتمل، SQL: BatchStarting.ثم تحصل على كل إدخال وخروج من الوظائف/الإجراءات المخزنة.

alter FUNCTION [dbo].[ufn_mjf](@i numeric(10))
    RETURNS numeric(20) 
AS
BEGIN
declare @datapoint varchar(10)

    set @datapoint = 'hello world'

    return @i
END
go
drop table foo
go
create table dbo.foo ( foo_id numeric(10)) 
go
delete from foo
insert into foo ( foo_id ) values ( 1 )
insert into foo ( foo_id ) values ( 2 )

select foo_id, dbo.ufn_mjf(foo_id) from foo

وبهذا أحصل على:

SQL:BatchStarting   alter FUNCTION [dbo].[ufn_mjf](@i numeric(10))
SQL:BatchStarting   drop table foo
SQL:BatchStarting   create table dbo.foo ( foo_id numeric(10)) 
SQL:BatchStarting   delete from foo
    insert into foo ( foo_id ) values ( 1 )
    insert into foo ( foo_id ) values ( 2 )
    select foo_id, dbo.ufn_mjf(foo_id) from foo
SP:Starting select foo_id, dbo.ufn_mjf(foo_id) from foo
SP:StmtStarting set @datapoint = 'hello world'
SP:StmtStarting return @i
SP:Completed    select foo_id, dbo.ufn_mjf(foo_id) from foo
SP:Starting select foo_id, dbo.ufn_mjf(foo_id) from foo
SP:StmtStarting set @datapoint = 'hello world'
SP:StmtStarting return @i
SP:Completed    select foo_id, dbo.ufn_mjf(foo_id) from foo

هل ذلك يكفيك؟

هذا يبدو أنه ما تحتاجه ولكنه متوفر فقط في إصدارات الفريق/المحترفين من Visual Studio.

استخدم SQL Profiler، أوصيك بالذهاب إلى إضافة الأحداث في المرة الأولى والتي ستتيح لك التعرف على ما تحتاجه.بدون اختبار أود أن أضيف الأحداث لـ SP:StmtStarted (أو مكتمل أو كليهما)، SQL:StmtStarted (مرة أخرى مكتمل أو كليهما).

أنا أؤيد اقتراح ملف تعريف SQL.خذ بعض الوقت لإعداده بحيث يتم تسجيل الأحداث التي تهتم بها فقط لتقليل حجم الإخراج.يمكنك إخراج التتبع إلى ملف - لقد قمت في كثير من الأحيان بتحميل هذا الملف مرة أخرى إلى جدول لتمكين التحليل.(مفيد للغاية لتحليل الأداء، على الرغم من أنه لا شك أن هناك من سيخبرني أن عام 2008 يحتوي على كل هذا في مكان ما...)

في بعض الأحيان، لن يكون لديك أذونات لتشغيل SQL Profiler لأنه يؤدي إلى إبطاء الخادم - اطلب من DBA الخاص بك منحك الإذن على خادم Dev الخاص بك.لا ينبغي أن يكون لديهم أي مشاكل في ذلك.

حسنًا في الماضي، كان عليّ أخذ القيم النموذجية التي قد تكون موجودة في UDF ثم تشغيل جزء udf فقط في نافذة استعلام منفصلة مثل SQL مستقيم وليس udf باستخدام القيم النموذجية كمتغيرات تم تعيينها مع إعلان وبيان مجموعة.إذا تم تشغيله من جدول بدلاً من وجود قيمة واحدة فقط، فسأقوم بإعداد جدول مؤقت أو متغير جدول بقيم الإدخال ثم تشغيلها من خلال SQL في UDF (ولكن مرة أخرى كـ SQL مستقيم وليس UDF) من خلال المؤشر.من خلال تشغيل SQL بشكل مستقيم، يمكنك طباعة بيانات فيه لمعرفة ما يحدث.أعلم أن هذا ألم، لكنه يعمل.(أجري عملية مشابهة عند إنشاء/تصحيح الأخطاء، وإعداد #إدراج و#حذف مع قيم الاختبار الخاصة بي، ثم اختبار الكود الذي أنوي وضعه في المشغل، ثم استبدال # بلا شيء وإضافة رمز إنشاء المشغل. )

ربما يمكنك استخدام SQL CLR لإجراء التتبع كما هو موضح هناكيفية تسجيل الدخول T-SQL

هل يمكنك أخذ وظيفتك وعمل نسخة ثانية منها، مع إرجاع نوع جدول بعمود إضافي لمعلومات التصحيح الخاصة بك.

على سبيل المثال، الدالة mySum أدناه

CREATE FUNCTION mySum
(   
    @param1 int,
    @param2 int
)
RETURNS INT AS
BEGIN
    DECLARE @mySum int

    SET @mySum = @param1

    SET @mySum = @mySum + @param2

    RETURN @mySum

END
GO
SELECT dbo.mySum(1, 2)

من شأنه أن يتحول إلى

CREATE FUNCTION mySumDebug
(   
    @param1 int,
    @param2 int
)
RETURNS @myTable TABLE
(
    [mySum] int,
    [debug] nvarchar(max)
)
AS
BEGIN
    DECLARE @debug nvarchar(max)

    SET @debug = 'Declare @mySum variable. '
    DECLARE @mySum int

    SET @debug = @debug + 'Set @mySum = @param1(' + CONVERT(nvarchar(50), @param1) + ') '
    SET @mySum = @param1


    SET @debug = @debug + 'Add @param2(' + CONVERT(nvarchar(50), @param2) + ') to @mySum(' + CONVERT(nvarchar(50), @mySum) + ') '
    SET @mySum = @mySum + @param2

    SET @debug = @debug + 'Return @mySum variable. '

    INSERT @myTable (mySum, debug) VALUES (@mySum, @debug)

    RETURN
END
GO
SELECT mySum, debug FROM dbo.mySumDebug(1, 2)

ليس حلاً مثاليًا، ولكنه مفيد فقط لإرجاع بعض النصوص للمساعدة في تعقب الخطأ.

أستخدم SQL SPY الذي يفعل ما تبحث عنه وأكثر.

SQL جاسوس

وثائق ميزة SQL SPY

يُظهر SQL Sniffer الوارد الخاص بـ SQL SPY رمز SQL الوارد لكل اتصال (بما في ذلك تتبع بيان DDL وDML)

تم تصميم هذه الميزة لـ MS SQL Server 2005\2008، ولكنها ستعمل مع MS SQL Server 2000 في نطاق محدود.لديه القدرة على التسجيل والإبلاغ عن SQL الوارد.كيفية استخدام الميزات:يرى

إفشاء:أنا جزء من فريق SQL SPY.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top