2015-04-29 123 views
0

我試圖弄清楚如何獲取正在存儲過程中保存的動態SQL查詢的結果。如何使用ODP.NET在存儲過程中從Oracle動態SQL返回記錄

的存儲過程很簡單:

CREATE OR REPLACE PROCEDURE PORT_CALL_PROCEDEURE(queryin IN varchar2,result out varchar2) 
is 

BEGIN 

    dbms_output.put_line(queryin); 
    EXECUTE IMMEDIATE queryin;  
END ; 

的方式我'從VS調用它是:

OracleCommand oracmd = GetCommand("PORT_CALL_PROCEDEURE", oraconn); 
oraconn.Open(); 
string row = string.Empty; 
StringBuilder sb = new StringBuilder(); 
sb.Append("SELECT * into result Where port = 'MSO'and Map = 'Local'"); 
sb.Append(" FROM VESSEL"); 
string commandString = sb.ToString(); 
command.Parameters.Add("query_in", OracleDbType.Varchar2, 10000000,  commandString, ParameterDirection.Input); 
command.Parameters.Add("result", OracleDbType.Varchar2, 10000000,  `commandString, ParameterDirection.Output);` 
oracmd.ExecuteNonQuery(); 

我'得到一個例外:

{"ORA-00905: missing keyword 
    ORA-06512: at \"BOAZ.PORT_CALL_PROCEDEURE\", line 7 
    ORA-06512: at line 1"} 

任何幫幫我? 謝謝。

+0

調用存儲過程僅用於執行標量查詢的目的是什麼?通常這個動作可以在不使用存儲過程的情況下完成!如果您不知道,請查看OracleCommand.ExecuteScalar方法。 http://docs.oracle.com/cd/E11882_01/win.112/e23174/OracleCommandClass。htm#i998581 –

+0

查詢只是一個例子,我將查詢編輯到了正確的一個。 –

+0

這並不會改變我評論的意義!你看到我發佈的文檔鏈接了嗎?還有一個簡短的例子,顯示應該如何完成這些事情。如果您不知道如何在PL/SQL中正確執行動態SQL,那麼這不是絕對適合您的情況,這是另一個問題,但嘗試將這兩件事分開! –

回答

0

該解決方案爲我工作:

甲骨文C程序頌:

CREATE OR REPLACE PROCEDURE PORT_CALL_PROCEDEURE 
    (queryin IN varchar2, result out varchar2) is 
BEGIN 
    dbms_output.put_line(queryin); 
    EXECUTE IMMEDIATE queryin into result; 
END ; 

C#代碼:

OracleCommand oracmd = new OracleCommand("PORT_CALL_PROCEDEURE", oraconn); 
oracmd.CommandType = CommandType.StoredProcedure; 
oracmd.Parameters.Add("query_in", OracleDbType.Varchar2, 10000000, 
    "select * from dual where dummy='X'", ParameterDirection.Input); 
oracmd.Parameters.Add("result", OracleDbType.Varchar2, 10000000, 
    null, ParameterDirection.Output); 
oracmd.ExecuteNonQuery(); 
Console.WriteLine(oracmd.Parameters["result"].Value); 

這將爲標,VARCHAR值工作。要獲得結果作爲DataTable,您需要將Oracle過程中的類型更改爲sys_refcursor,並將C#中的類型更改爲RefCursor(未對其進行測試)。

0

錯誤說EXECUTE IMMEDIATE不明白result

修改execute immediate

execute immediate queryin into result. 

發送查詢像

select clmn from tbl where .... 

演示:

declare 
v_name varchar2(50); 
begin 
execute immediate q'{select 'my name' into v_name from dual}'; 
dbms_output.put_line(v_name); 
end; 
/
ORA-00905: missing keyword 
ORA-06512: at line 4 
00905. 00000 - "missing keyword" 


declare 
v_name nvarchar2(50); 
begin 
execute immediate q'{select 'my name' from dual}' into v_name; 
dbms_output.put_line(v_name); 
end; 
/
anonymous block completed 
my name 
1

要執行該查詢,您不需要動態SQL,也不需要PL/SQL存儲過程。如果你想要學習這兩件事情,沒有什麼不好的,但是試着只做一件你不知道的事情。這將幫助您識別錯誤。

在你的代碼由三個主要錯誤:

  1. 在查詢的WHERE子句從
  2. SELECT INTO之前的工作只能在PL/SQL塊,並執行即時不出手
  3. DBMS_OUTPUT不會在.NET中工作,如果你不叫DBMS_OUTPUT.GET_LINES,如果你不這樣做所有需要的東西越來越之前做的工作

因此,這是C#代碼你會以簡單和正確的方式執行它:

OracleConnection connection = new OracleConnection(); 
connection.ConnectionString = "xxxYYYzzz"; 
connection.Open(); 

OracleCommand oracmd = connection.CreateCommand(); 
oraCmd.CommandText = 
@"SELECT * 
FROM VESSEL 
Where port = 'MSO'and Map = 'Local'".Replace("\r", ""); // Oracle SQL Parset doesn't like '\r' char 
object res = oraCmd.ExecuteScalar(); 

Console.WriteLine(res); 
相關問題