2009-08-10 11 views
5

मैंने पैरामीटर युक्त एक SQL क्वेरी के साथ एक SQLCommand बनाया। कक्षा में सभी पैरामीटर जोड़ने से I।क्या परम प्रतिस्थापन के बाद एसक्यूएल कॉमांड से पूर्ण एसक्यूएल पाठ वापस पाने का कोई तरीका है?

क्या परिणामी एसक्यूएल क्वेरी को डीबी पर भेजने से पहले एक आसान तरीका है?

यह डिबगिंग उद्देश्यों के लिए आसान होगा। , (जैसे संपूर्ण क्वेरी को कॉपी करने और कोशिश करते हैं और समस्याओं को इंगित करने के प्रबंधन स्टूडियो में इसे चलाने)

आर

उत्तर

4

नहीं है क्योंकि कोई प्रतिस्थापन वास्तव में होता है। क्वेरी सर्वर को पास की जाती है, और पैरामीटर अलग से पास किए जाते हैं।

हालांकि, आप वास्तविक पैरामीटर मानों के साथ पैरामीटर प्लेसहोल्डर्स को प्रतिस्थापित करने के लिए एक विधि लिख सकते हैं ... मैंने अपने अनुप्रयोगों में से एक किया है, मैं जितनी जल्दी हो सके कोड पोस्ट करूंगा।


यहाँ कोड है कि मैं का उपयोग है, लेकिन यह, एक Oracle लाइट डेटाबेस के लिए है, इसलिए यह एक और आरडीबीएमएस के साथ उपयोग करने के लिए कुछ रूपांतरों की आवश्यकता होगी।

public void Log(IDbCommand cmd) 
    { 
     StringBuilder sb = new StringBuilder(cmd.CommandText); 
     for (int i = 0; i < cmd.Parameters.Count; i++) 
     { 
      int pos = sb.ToString().IndexOf("?"); 
      if (pos > 0) 
       sb.Replace("?", FormatParameter(cmd.Parameters[i]), pos, 1); 
     } 
     Log(sb.ToString()); 
    } 

    private string FormatParameter(object prm) 
    { 
     IDbDataParameter p = prm as IDbDataParameter; 
     if (p.Value == null || p.Value == DBNull.Value) 
      return "NULL"; 
     switch (p.DbType) 
     { 
      case DbType.AnsiString: 
      case DbType.AnsiStringFixedLength: 
      case DbType.String: 
      case DbType.StringFixedLength: 
       string s = p.Value as string; 
       return string.Format("'{0}'", s.Replace("'", "''")); 

      case DbType.Binary: 
       byte[] b = p.Value as byte[]; 
       return HexString(b); 

      case DbType.Date: 
      case DbType.DateTime: 
      case DbType.DateTime2: 
       DateTime d = (DateTime)p.Value; 
       return string.Format("to_date('{0}', 'dd/mm/yyyy hh24:mi')", d.ToString("dd/MM/yyyy HH:mm")); 

      default: 
       return p.Value.ToString(); 
     } 
    } 

    private string HexString(byte[] bytes) 
    { 
     StringBuilder sb = new StringBuilder(); 
     for (int i=0; i < bytes.Length; i++) 
      sb.AppendFormat("{0:X2}", bytes[i]); 
     return sb.ToString(); 
    } 
+0

महान ... इससे बहुत मदद मिलती है! – Toad

2

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

बस एक नया ट्रेस जोड़ें, डेटाबेस कॉल करने वाले कोड को चलाएं, फिर परिणामस्वरूप कैप्चर ईवेंट से कमांड को कॉपी करें।

+0

एसक्यूएल प्रोफाइलर आपका मित्र है। – pjp

+0

यह तब भी काम करता है जब डीबी तक पहुंच केवल कनेक्शन स्ट्रिंग तक ही सीमित होती है? या क्या मुझे एक प्रोफाइलर चलाने के लिए और अधिक पहुंच की आवश्यकता है जो पता लगा सकता है? – Toad

+0

क्या आपके द्वारा उपयोग किए जा रहे प्रमाण-पत्रों में sysadmin अधिकार हैं? यदि नहीं, तो आप एसओएल हो सकता है। संभवतः, थॉमस कोड आपकी सबसे अच्छी शर्त है। – davewasthere

0

मैं इसे पोस्ट करने से पहले अपने प्रश्न को फिर से पढ़ता हूं। हालांकि इस तकनीक को शायद .NET पर सीधे लागू नहीं किया जा सकता है, लेकिन आप कुछ इसी तरह से काम करने में सक्षम हो सकते हैं। तो:

मुझे हाल ही में टी-एसक्यूएल में बहुत गतिशील कोडिंग करना पड़ा है, और मैं निम्नलिखित दिनचर्या के साथ आया हूं। तुम इतनी तरह कोड का एक हिस्सा मिल गया है यह मानें कि:

DECLARE 
    @Command nvarchar(max) 
,@SearchFor int 

SET @Command = 'SELECT * from MyTable where PrimaryKey = @SearchFor' 
SET @SearchFor = 1 

EXECUTE sp_executesql 
    @Command 
,N'@SearchFor int' 
,@SearchFor 

यह बहुत simplisitc निश्चित रूप से है - अगर आप गतिशील कोड क्या करने की जरूरत है, तो आप बेतहाशा परिसर में जटिल प्रश्न करने जा रहे हैं, और आप के रूप में पता चला है कि इन्हें डीबग करना बहुत मुश्किल हो सकता है। यहाँ कैसे मैं ऊपर कोड को फिर से लिखने करेंगे:

DECLARE 
    @Command nvarchar(max) 
,@SearchFor int 
,@Debug  int 
    -- 0 = Run it 
    -- 1 = Run and display it 
    -- 2 = Display it 

SET @Command = 'SELECT * from MyTable where PrimaryKey = @SearchFor' 
SET @SearchFor = 1 
SET @Debug = 1 

IF @Debug > 0 
    -- Show the command that would be run 
    PRINT replace(@Command, '@SearchFor', cast(@SearchFor as varchar(10))) 

IF @Debug < 2 
    -- Run it 
    EXECUTE sp_executesql 
     @Command 
    ,N'@SearchFor int' 
    ,@SearchFor 

इस अतिरिक्त कोड लिखने और डिबग करने के लिए है, लेकिन एक बार यह जगह में है और काम कर रहा यह डिबगिंग स्थितियों में अमूल्य हो सकता है। यदि यह संग्रहीत प्रक्रिया का हिस्सा है, तो @Debug को पैरामीटर बनाएं जो 0 पर डिफ़ॉल्ट हो, और सुनिश्चित करें कि यदि 2 पर सेट किया गया है, तो प्रक्रिया वास्तव में कुछ भी नहीं करती है।

+0

मैं सराहना कर सकता हूं कि थोड़ा प्रयास अतिरिक्त, स्पष्ट रूप से डिबगिंग विभाग में बहुत लाभ प्रदान करता है। मुझे कुछ ऐसा ही बनाना पड़ सकता है (यदि ऐसा कुछ भी पहले से मौजूद नहीं है)। – Toad

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