2008-08-29 13 views
13

में संग्रहीत प्रक्रिया से पैरामीटर की एक सूची पुनर्प्राप्त कैसे कर सकता हूं C# और System.Data.SqlClient का उपयोग करना, वास्तव में SQL सर्वर पर संग्रहीत प्रक्रिया से संबंधित पैरामीटर की एक सूची पुनर्प्राप्त करने का एक तरीका है इसे निष्पादित करो?मैं SQL सर्वर

मेरे पास एक "बहु-पर्यावरण" परिदृश्य है जहां एक ही डेटाबेस स्कीमा के कई संस्करण हैं। वातावरण के उदाहरण "विकास", "स्टेजिंग", & "उत्पादन" हो सकते हैं। "विकास" में संग्रहीत प्रक्रिया का एक संस्करण होगा और "स्टेजिंग" में एक और होगा।

मैं बस इतना करना चाहता हूं कि यह एक मानदंड पास करने और संग्रहीत प्रक्रिया को कॉल करने से पहले एक पैरामीटर होगा। इसे पकड़ने के बजाय SqlException से बचें मेरे लिए एक प्लस है।

यहोशू

उत्तर

8

आप SqlCommandBuilder.DeriveParameters उपयोग कर सकते हैं() (SqlCommandBuilder.DeriveParameters - Get Parameter Information for a Stored Procedure - ADO.NET Tutorials देखें) या वहाँ this way जो के रूप में सुंदर नहीं है।

+1

डेविड हेडन की साइट (पहला लिंक) का लिंक मौजूद नहीं है और ऐसा लगता है कि यह अपने पुराने ब्लॉग से माइग्रेट नहीं हुआ था। – JoeFletch

2
SqlCommandBuilder.DeriveParameters(command) 

यह बयान क्या मैं इसे करने की जरूरत है।

इस समस्या को हल करने के तरीके के लिए यहां एक पूर्ण कोड नमूना है।

Public Sub GetLogEntriesForApplication(ByVal settings As FilterSettings, 
           Optional ByVal RowGovernor As Integer = -1) 

    Dim command As New SqlCommand("GetApplicationActions", 
     New SqlConnection(m_environment.LoggingDatabaseConnectionString)) 
    Dim adapter As New SqlDataAdapter(command) 

    Using command.Connection 

     With command 

      .Connection.Open() 
      .CommandType = CommandType.StoredProcedure 

      SqlCommandBuilder.DeriveParameters(command) 

      With .Parameters 

       If settings.FilterOnLoggingLevel Then 
        If .Contains("@loggingLevel") Then 
         .Item("@loggingLevel").Value = settings.LoggingLevel 
        End If 
       End If 

       If settings.FilterOnApplicationID Then 
        If .Contains("@applicationID") Then 
         .Item("@applicationID").Value = settings.ApplicationID 
        End If 
       End If 

       If settings.FilterOnCreatedDate Then 
        If .Contains("@startDate") Then 
         .Item("@startDate").Value = settings.CreatedDate.Ticks 
        End If 
       End If 

       If settings.FilterOnEndDate Then 
        If .Contains("@endDate") Then 
         .Item("@endDate").Value = settings.EndDate.Ticks 
        End If 
       End If 

       If settings.FilterOnSuccess Then 
        If .Contains("@success") Then 
         .Item("@success").Value = settings.Success 
        End If 
       End If 

       If settings.FilterOnProcess Then 
        If settings.Process > -1 Then 
         If .Contains("@process") Then 
          .Item("@process").Value = settings.Process 
         End If 
        End If 
       End If 

       If RowGovernor > -1 Then 
        If .Contains("@topRows") Then 
         .Item("@topRows").Value = RowGovernor 
        End If 
       End If 

      End With 

     End With 

     adapter.TableMappings.Clear() 
     adapter.TableMappings.Add("Table", "ApplicationActions") 
     adapter.TableMappings.Add("Table1", "Milestones") 

     LogEntries.Clear() 
     Milestones.Clear() 
     adapter.Fill(m_logEntryData) 

    End Using 

End Sub 
2

आप SqlCommandBuilder ऑब्जेक्ट का उपयोग कर सकते हैं, और DeriveParameters विधि को कॉल कर सकते हैं।

मूल रूप से आप इसे एक आदेश पारित करने के लिए की जरूरत है, जो आपके संग्रहीत proc कॉल करने के लिए सेटअप है, और यह मानकों की खोज के लिए डीबी मारा जाएगा, और SqlCommand

के पैरामीटर संपत्ति में उपयुक्त पैरामीटर बना संपादित करें: आप सब बहुत तेज़ हैं !!

14

आप SqlCommandBuilder.DeriveParameters(SqlCommand) विधि चाहते हैं। ध्यान दें कि इसे डेटाबेस के लिए अतिरिक्त राउंड ट्रिप की आवश्यकता है, इसलिए यह कुछ हद तक महत्वपूर्ण प्रदर्शन हिट है। आपको परिणामों को कैशिंग करने पर विचार करना चाहिए।

एक उदाहरण कॉल:

using (SqlConnection conn = new SqlConnection(CONNSTRING)) 
using (SqlCommand cmd = new SqlCommand("StoredProc", conn)) { 
    cmd.CommandType = CommandType.StoredProcedure; 
    SqlCommandBuilder.DeriveParameters(cmd); 

    cmd.Parameters["param1"].Value = "12345"; 

    // .... 
} 
5

हालांकि इसकी बिल्कुल आप क्या चाहते हैं, यहाँ SqlConnection.GetSchema() विधि का उपयोग करता है सभी संग्रहीत एक डेटाबेस के साथ जुड़े प्रक्रियाओं वापस जाने के लिए कुछ नमूना कोड, और फिर आगे चलकर प्रत्येक संग्रहीत प्रक्रिया के लिए सभी पैरामीटर नाम और प्रकार। नीचे दिया गया उदाहरण बस इसे चर में लोड करता है। ध्यान दें कि यह सभी "सिस्टम" संग्रहित प्रक्रियाओं को भी लौटाता है, जो वांछित नहीं हो सकता है।

स्टीव

public void LoadProcedureInfo() 
    { 
     SqlConnection connection = new SqlConnection(); 

     ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings["ConnectionString"]; 

     connection.ConnectionString = settings.ConnectionString; 
     connection.Open(); 

     DataTable procedureDataTable = connection.GetSchema("Procedures"); 
     DataColumn procedureDataColumn = procedureDataTable.Columns["ROUTINE_NAME"]; 

     if (procedureDataColumn != null) 
     { 
      foreach (DataRow row in procedureDataTable.Rows) 
      { 
       String procedureName = row[procedureDataColumn].ToString(); 

       DataTable parmsDataTable = connection.GetSchema("ProcedureParameters", new string[] { null, null, procedureName }); 

       DataColumn parmNameDataColumn = parmsDataTable.Columns["PARAMETER_NAME"]; 
       DataColumn parmTypeDataColumn = parmsDataTable.Columns["DATA_TYPE"]; 

       foreach (DataRow parmRow in parmsDataTable.Rows) 
       { 
        string parmName = parmRow[parmNameDataColumn].ToString(); 
        string parmType = parmRow[parmTypeDataColumn].ToString(); 
       } 
      } 
     } 
    } 
1

मार्क DeriveParameters का सबसे अच्छा कार्यान्वयन है। जैसा कि उन्होंने कहा, सुनिश्चित करें कि आप this tutorial में कैश की तरह हैं।

हालांकि, मुझे लगता है कि यह डेटाबेस स्पोक संस्करण की आपकी मूल समस्या को हल करने का एक खतरनाक तरीका है। डिफ़ॉल्ट (नया पैरामीटर के लिए) का उपयोग करके

  • एक पीछे की ओर-संगत ढंग से कोड या बस की अनदेखी करके: आप जोड़ने या मानकों को हटाकर एक प्रक्रिया के हस्ताक्षर को बदलने के लिए जा रहे हैं, तो आप निम्न में से एक करना चाहिए एक param (हटाए गए पैराम के लिए)।यह सुनिश्चित करता है कि आपका ग्राहक कोड हमेशा आपकी संग्रहीत प्रक्रिया के किसी भी संस्करण को कॉल कर सकता है।
  • स्पष्ट रूप से नाम से प्रक्रिया का संस्करण (इसलिए आपके पास my_proc और my_proc_v2 होगा)। यह सुनिश्चित करता है कि आपका ग्राहक कोड और स्पॉक्स सिंक में रहें।

डेरिव पैरामीटर पर निर्भर करते हुए कि आप जिस स्पोक का उपयोग कर रहे हैं उसका सत्यापन करने के लिए नौकरी के लिए गलत उपकरण लगता है, IMHO।

0

इन सभी ADO.NET समाधान कोड लाइब्रेरी से आपकी ओर से डेटाबेस के मेटाडेटा से पूछने के लिए कह रहे हैं। आपको लगता है कि प्रदर्शन किसी भी तरह मारा लेने के लिए जा रहे हैं, तो हो सकता है आप बस कुछ सहायक कार्यों कि

Select count(*) from information_schema.parameters 
where ...(proc name =.. param name=...) (pseudo-code) 

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

0

मैं कुछ वर्षों से .NET 1.1 और 2.0 के साथ DeriveParameters का उपयोग कर रहा हूं, और हर बार एक आकर्षण की तरह काम करता हूं।

अब मैं .NET 3.5 के साथ अपने पहले असाइनमेंट पर काम कर रहा हूं, और अभी पाया और बदसूरत आश्चर्य: DeriveParameters SqlDbTpepe "Variant" के साथ सभी पैरामीटर बना रहा है, इसके बजाय उचित SqlDbTypes। यह संख्यात्मक मानकों के साथ एसपी निष्पादित करने का प्रयास करते समय एक एसक्यूएलएक्सप्शन बना रहा है, क्योंकि SQL सर्वर 2005 का कहना है कि एसक्यूएल-वेरिएंट प्रकारों को अंतर्निहित रूप से int (या छोटे, या संख्यात्मक) मानों में परिवर्तित नहीं किया जा सकता है।

मैंने अभी एक ही कोड का परीक्षण .NET CF 2.0 और SQL Server 2000 के साथ किया है, और उम्मीद के अनुसार काम किया है, प्रत्येक पैरामीटर में सही SqlDbType असाइन करना।

मैं परीक्षण किया था नेट SQL सर्वर 2005 डेटाबेस के खिलाफ 2.0 क्षुधा है, तो संबंधित मुद्दे एक एसक्यूएल सर्वर नहीं है, तो यह .NET 3.5

कोई भी विचार के साथ संबंधित कुछ किया जाना है?

+0

बस पता चला कि यह समस्या कॉम्पैक्टफ्रेमवर्क-संबंधित समस्या है। बस WindowsForms ऐप में एक परीक्षण चलाया और उम्मीद की तरह काम किया, लेकिन एक ही कोड कोड SmartDEvice प्रोजेक्ट से चलाया, सभी पैरामीटर 'संस्करण' के रूप में देता है। :( – VictorEspina