2010-11-08 13 views
9

मैं उपयोगकर्ता द्वारा परिभाषित ओरेकल फ़ंक्शन निष्पादित करने का प्रयास कर रहा हूं जो ODP.NET का उपयोग करके एक RefCursor देता है।ओरेकल फ़ंक्शन से RefCursor कैसे वापस करें?

CREATE OR REPLACE FUNCTION PKG.FUNC_TEST (ID IN TABLE.ID%type) 
    RETURN SYS_REFCURSOR 
AS 
    REF_TEST SYS_REFCURSOR; 
BEGIN 
    OPEN REF_TEST FOR 
     SELECT * 
     FROM TABLE; 
    RETURN REF_TEST; 
END; 
/

मैं टॉड में इस समारोह कॉल कर सकते हैं (func_test चयन (7) दोहरी से) और एक कर्सर वापस पाने: यहाँ कार्य है। लेकिन मुझे डेटासेट भरने के लिए सी # और ओडीपी.नेट का उपयोग कर कर्सर प्राप्त करने की आवश्यकता है, लेकिन मुझे एक NullReferenceException मिल रहा है - "ऑब्जेक्ट रेफरेंस ऑब्जेक्ट के इंस्टेंस पर सेट नहीं है"।

OracleConnection oracleCon = new OracleConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString); 
OracleCommand sqlCom = new OracleCommand("select func_test(7) from dual", oracleCon); 
sqlCom.Parameters.Add("REF_TEST", OracleDbType.RefCursor, ParameterDirection.ReturnValue); 
OracleDataAdapter dataAdapter = new OracleDataAdapter(); 
dataAdapter.SelectCommand = sqlCom; 

DataSet dataSet = new DataSet(); 
dataAdapter.Fill(dataSet); //FAILS HERE with NullReferenceException 

मैं और संग्रहित प्रक्रियाओं और ODP.NET के प्रयोग पर जानकारी के बहुत सारे नमूने प्राप्त करने में सक्षम था, लेकिन नहीं कार्यों से RefCursors लौटने के लिए बहुत बहुत: यहाँ क्या मुझे लगता है कि के लिए है।

संपादित करें: मैं स्पष्ट रूप से OracleCommand वस्तु के लिए इनपुट पैरामीटर जोड़ने के लिए नहीं करना चाहते हैं (यानी sqlCom.Parameters.Add("id", OracleDbType.Int32,ParameterDirection.Input).Value = 7;) के रूप में है कि यह मुश्किल एक सामान्य RESTful वेब सेवा के रूप में इस लागू करने के लिए, लेकिन मैं अपने अंतिम उपाय के रूप में यह आरक्षण हूँ बनाता है लेकिन बदले में संग्रहीत प्रक्रियाओं का उपयोग करेगा।

किसी भी मदद की बहुत सराहना की है!

+0

आप पैरामीटर जोड़ रहे हैं लेकिन आप इसे एक क्वेरी के रूप में चला रहे हैं; क्या आप कुछ ऐसा नहीं करना चाहते हैं जैसे: REF_TEST: = func_test (7) '? –

+0

यह सुनिश्चित नहीं है कि इसका उपयोग कहां करें। क्या यह पैरामीटर के बजाय प्रयोग किया जाता है? चुनने के बजाय – Gady

+0

ओरेकल कॉमांड स्ट्रिंग के रूप में। (मुझे शायद यह इंगित करना चाहिए कि मुझे ओडीपी.Net के बारे में कुछ नहीं पता है, लेकिन यह अभी भी गलत दिखता है * 8-) –

उत्तर

15

मुझे लगता है कि आप sqlCom.ExecuteNonQuery();

भी चलाने के बजाय दोहरी से func_test (7) का चयन करें; की सुविधा देता है समारोह चलाने के लिए और परम

OracleConnection oracleCon = new OracleConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString); 


    // Set the command 

    string anonymous_block = "begin " + 
           " :refcursor1 := func_test(7) ;" + 
           "end;"; 
//fill in your function and variables via the above example 
    OracleCommand sqlCom= con.CreateCommand(); 
    sqlCom.CommandText = anonymous_block; 

    // Bind 
    sqlCom.Parameters.Add("refcursor1", OracleDbType.RefCursor); 
    sqlCom.Parameters[0].Direction = ParameterDirection.ReturnValue; 

    try 
    { 
    // Execute command; Have the parameters populated 
    sqlCom.ExecuteNonQuery(); 

    // Create the OracleDataAdapter 
    OracleDataAdapter da = new OracleDataAdapter(sqlCom); 

    // Populate a DataSet with refcursor1. 
    DataSet ds = new DataSet(); 
    da.Fill(ds, "refcursor1", (OracleRefCursor)(sqlCom.Parameters["refcursor1"].Value)); 

    // Print out the field count the REF Cursor 
    Console.WriteLine("Field count: " + ds.Tables["refcursor1"].Columns.Count); 
    } 
    catch (Exception e) 
    { 
    Console.WriteLine("Error: {0}", e.Message); 
    } 
    finally 
    { 
    // Dispose OracleCommand object 
    cmd.Dispose(); 

    // Close and Dispose OracleConnection object 
    con.Close(); 
    con.Dispose();} 

इस उदाहरण ODP पाया जा सकता है पर आधारित है में पारित करने के लिए यह स्विच @% ora_home% \ Client_1 \ ODP.NET \ नमूने \ RefCursor \ Sample5.csproj

यदि आप प्रत्येक प्रो/फ़ंक्शन कॉल के लिए कस्टम निर्मित पैरा संग्रह को टालना चाहते हैं, तो आप अपने कोड में अज्ञात ब्लॉक का उपयोग करके इसके आसपास हो सकते हैं, मैंने कोड (एक बार फिर से अनचाहे!) कोड को संशोधित किया है इस तकनीक को प्रतिबिंबित करने के लिए ऊपर। यहां एक अच्छा ब्लॉग है (मार्क विलियम्स के अलावा किसी अन्य से) इस तकनीक को दिखा रहा है। http://oradim.blogspot.com/2007/04/odpnet-tip-anonymous-plsql-and.html

+0

यह काम कर सकता है, लेकिन जैसा कि इसका उपयोग एक विश्वसनीय वेब सेवा में किया जाएगा, मैं इनपुट पैरामीटर (यानी 'sqlCom.Parameters.Add ("id", OracleDbType के स्पष्ट जोड़ों से बचने की कोशिश कर रहा हूं। Int32, पैरामीटर डायरेक्शन. इनपुट)। वैल्यू = 7; ') इसलिए मैं आसानी से फ्लाई पर एक SQL कथन बना सकता हूं। – Gady

+0

@ गुड्डी, आप इसे 'जेनेरिक' महसूस करने के लिए अनाम ब्लॉक का उपयोग कर सकते हैं। मैंने इस – Harrison

+0

हां को दर्शाने के लिए उपर्युक्त उदाहरण बदल दिया है! तुम जीते! ठीक वही जो मेरे द्वारा खोजा जा रहा था! – Gady

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