2008-12-09 13 views
20

मैं एक नहीं बल्कि जटिल सूत्र मूल्यांकनकर्ता T-SQL UDFs में लिखा (मत पूछो) डिबग करने के लिए कोशिश कर रहा हूँ कॉल रिकर्सिवली (लेकिन एक मध्यवर्ती समारोह के माध्यम से परोक्ष रूप से) ही कहता है, blah , ब्लाह।T-SQL समारोह का पता लगाने के लिए कैसे

और, ज़ाहिर है, हमारे पास एक बग है।

अब, PRINT कथन का उपयोग करके (जिसे InfoMessage ईवेंट के लिए हैंडलर लागू करके ADO.NET से पढ़ा जा सकता है), मैं संग्रहित प्रक्रियाओं के लिए एक ट्रेस अनुकरण कर सकता हूं।

एक संकलन समय संदेश में यूडीएफ परिणाम के लिए एक ही कर रहा:

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

मैं (संदेश मिलता है प्रिंट @@ROWCOUNT को रीसेट जो निश्चित रूप से है जैसे कुछ सामान करता नहीं-नहीं UDFs में है, लेकिन मैं कैसे पता लगा सकते हैं ? कॉल के माध्यम से मैं इस का पता लगाने के लिए बाहर मुद्रित करना चाहते हैं, तो मैं डीबगर में कॉल के माध्यम से कदम से विचलित हुए बिना यह अध्ययन कर सकते हैं ...

संपादित करें: मैं एसक्यूएल प्रोफाइलर उपयोग करने के लिए कोशिश की है (इस मेरे लिए पहली बार एक था), लेकिन मैं यह नहीं समझ सकता कि किसके लिए पता लगाना है: Alt आटा मैं डाटाबेस को भेजे गए प्रश्नों को आउटपुट करने के लिए ट्रेस प्राप्त कर सकता हूं, वे इस अर्थ में अपारदर्शी हैं कि मैं अभिव्यक्ति-यूडीएफ को ड्रिल नहीं कर सकता हूं: मैं वास्तविक संग्रहित प्रक्रिया का पता लगा सकता हूं, लेकिन इसके द्वारा बुलाए गए यूडीएफ प्रक्रिया सूचीबद्ध नहीं है। क्या मैं कुछ भूल रहा हूँ? मुझे नहीं लगता है कि ...

संपादित करें # 2: Allthough (ऑटो) स्वीकार किए जाते हैं जवाब का पता लगाने फ़ंक्शन को कॉल करता है - बहुत ही उपयोगी है, धन्यवाद - यह क्या मापदंडों के लिए पारित थे जानने में मदद नहीं करता है समारोह। यह, ज़ाहिर है, में रिकर्सिव फ़ंक्शन डिबगिंग में आवश्यक है। अगर मुझे कोई सोशलेशन मिल जाए तो मैं पोस्ट करूंगा ...

+0

हां, नीचे मैथ्यूयू से जवाब देखें, जो बताता है कि आपको अपने प्रोफाइलर सेटअप में कौन सी घटनाओं को जोड़ने की आवश्यकता है। डिफ़ॉल्ट रूप से यह केवल कुछ घटनाओं को कैप्चर करता है, और वे आपके समस्या निवारण के लिए आवश्यक नहीं हैं। –

उत्तर

26

कथन स्तर की घटनाओं के साथ एसक्यूएल प्रोफाइलर का उपयोग क्यों नहीं किया गया?

संपादित: सपा: Stmt शुरू या सपा: संग्रहीत प्रक्रिया के लिए घटनाओं जोड़े डिबग करने के लिए यदि आवश्यक हो तो, अर्थात सेट @ डिबग = 'मैं यहाँ हूँ' Stmt पूरे उपयोग चर; यूडीएफ, तकनीकी रूप से संग्रहीत प्रक्रियाओं के दौरान, बयान स्तर की घटनाओं के साथ पता लगाया जाएगा।

+0

निश्चित रूप से, लेकिन इसकी संग्रहीत प्रक्रियाओं में मुझे रूचि नहीं है, लेकिन यूडीएफ। ये टी-एसक्यूएल में एक पूरी तरह से अलग जानवर हैं और वास्तव में कठोर प्रतिबंध हैं ... –

+3

एसपी: StmtStarting कार्यों को संभालती है। उदाहरण के लिए, मेरा उत्तर आगे नीचे देखें। –

0

मैं एसक्यूएल प्रोफाइलर सुझाव दूसरा सेकेंड करता हूं। इसे सेट अप करने के लिए कुछ समय दें ताकि आउटपुट आकार में कटौती करने के लिए केवल उन्हीं घटनाओं को लॉग इन किया जा सके। आप एक फ़ाइल में ट्रेस आउटपुट कर सकते हैं - मैंने विश्लेषण को सक्षम करने के लिए अक्सर उस फ़ाइल को तालिका में वापस लोड किया है। (प्रदर्शन विश्लेषण के लिए बेहद आसान है, हालांकि इसमें कोई संदेह नहीं है कि कोई मुझे बताएगा कि 2008 में यह सब कुछ बनाया गया है ...)

कभी-कभी आपको SQL प्रोफाइलर चलाने की अनुमति नहीं होगी क्योंकि यह सर्वर को धीमा कर देता है - पूछें आपके डीबीए को आपको अपने देव सर्वर पर अनुमति देने के लिए। उन्हें इसके साथ कोई समस्या नहीं होनी चाहिए।

+0

मैंने यह कोशिश की है, यह वास्तव में काम नहीं करता है: हालांकि ट्रेस मूल संग्रहीत प्रक्रिया को दिखाता है जिसे वास्तविक कहा गया था, वास्तविक यूडीएफ (अभिव्यक्ति) सूचीबद्ध नहीं हैं और इसलिए मैं अभी भी एक ब्लैक बॉक्स देख रहा हूं। –

+0

हम्म, मुझे मेरे सामने एसक्यूएल प्रोफाइलर नहीं मिला है (वर्तमान गीग ओरेकल आधारित है)।हो सकता है कि कोई व्यक्ति जो यूडीएफ जानकारी प्राप्त करने के लिए सही घटनाएं ढूंढ सके (या यह बताएं कि यह संभव नहीं है)। – kpollock

+0

संग्रहीत प्रक्रिया: एसपी: StmtStarting या एसपी: StmtCompleted इसके अलावा आप स्थानीय चर जोड़ सकते हैं और सेट @ डीबग = 'मैं यहाँ हूं' जो प्रोफाइलर – SqlACID

1

एसक्यूएल प्रोफाइलर का उपयोग करें, मैं आपको पहली बार घटनाओं को जोड़ने पर ओवरबोर्ड पर जाने की सलाह देता हूं जिससे आपको अपनी आवश्यकता के बारे में महसूस हो सके। परीक्षण के बिना मैं एसपी के लिए घटनाओं को जोड़ूंगा: StmtStarted (या पूर्ण या दोनों), एसक्यूएल: StmtStarted (फिर से पूरा या दोनों)।

0

ठीक है अतीत में मुझे सामान्य मूल्यों को लेना पड़ता है जो यूडीएफ में होंगे और फिर एक अलग क्वेरी विंडो में केवल udf भाग चलाएं, क्योंकि सामान्य एसक्यूएल सामान्य रूप से एक udf नहीं है, जैसा कि घोषणाओं के साथ सेट चर के रूप में होता है और एक सेट स्टेटमेंटयदि यह केवल एक मान रखने के बजाय तालिका से चलाया जाता है, तो मैं इनपुट मानों के साथ एक temp तालिका या तालिका चर सेट अप करता हूं और फिर उन्हें यूडीएफ में एसक्यूएल के माध्यम से चलाता हूं (लेकिन फिर से सीधे एसक्यूएल एक यूडीएफ नहीं) कर्सर रखें। सीधे एसक्यूएल चलाकर आप क्या हो रहा है यह देखने के लिए प्रिंट प्रिंट स्टेटमेंट प्राप्त कर सकते हैं। मुझे पता है कि यह एक दर्द है, लेकिन यह काम करता है। (जब मैं ट्रिगर बनाने/डिबगिंग करते समय एक सिमलीर प्रक्रिया के माध्यम से जाता हूं, सेटअप # सम्मिलित और # टेस्ट मानों के साथ हटाया जाता है और उसके बाद ट्रिगर में डालने का इरादा रखने वाले कोड का परीक्षण करता है, तो वैश्विक # को कुछ भी नहीं बदलता है और ट्रिगर कोड बना देता है।)

4

This आपको क्या चाहिए की तरह दिखता है, लेकिन यह दृश्य स्टूडियो की टीम/समर्थक संस्करणों में ही उपलब्ध है ट्रेसिंग करने के लिए SQL CLR उपयोग कर सकते हैं।

0

क्या आप अपना कार्य ले सकते हैं, और इसकी दूसरी प्रतिलिपि बना सकते हैं, लेकिन अपनी डीबग जानकारी के लिए एक अतिरिक्त कॉलम के साथ एक टेबल प्रकार लौटा सकते हैं।

उदाहरण के लिए, नीचे

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) 

mySum समारोह

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) 

नहीं एक आदर्श समाधान में बदल सकते हैं, लेकिन उपयोगी सिर्फ एक बग नीचे ट्रैक करने में मदद के लिए कुछ पाठ वापस जाने के लिए।

12

एसक्यूएल प्रोफाइलर में, आपको इसकी आवश्यकता है: एसपी: प्रारंभ, एसपी: StmtStarting, एसपी: पूर्ण, एसक्यूएल: बैचस्टार्टिंग। फिर, आप प्रत्येक प्रविष्टि प्राप्त करते हैं, कार्यों/संग्रहीत प्रक्रियाओं से बाहर निकलें।

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 

आप के लिए है कि पर्याप्त है?

0

मैं एसक्यूएल एसपीवाई का उपयोग करता हूं जो आप खोज रहे हैं और अधिक।

SQL SPY

SQL SPY Feature Documentation

एसक्यूएल जासूस की आने वाली एसक्यूएल स्निफर प्रत्येक कनेक्शन के भेजे एसक्यूएल कोड से पता चलता (शामिल DDL और DML कथन ट्रैकिंग)

यह सुविधा \ 2008 एमएस SQL ​​सर्वर 2005 के लिए डिज़ाइन किया गया है , लेकिन सीमित स्कोप में एमएस एसक्यूएल सर्वर 2000 के साथ काम करेगा। इसमें आने वाली एसक्यूएल पर रिकॉर्ड और रिपोर्ट करने की क्षमता है। सुविधाओं का उपयोग कैसे करें:

प्रकटीकरण: मैं एसक्यूएल एसपीवाई टीम का हिस्सा हूं।

+0

में दिखाया जाएगा साइट मर चुका है, शायद यह बन गया: https: // sqlspy। codeplex.com/ - मुझे नहीं लगता कि यह सवाल का जवाब देता है। –

संबंधित मुद्दे