2015-04-29 3 views
0

Я пытаюсь выяснить, как я могу получить результат динамического SQL-запроса, который хранится в процедуре хранилища.Как вернуть записи из Oracle динамического SQL в хранимой процедуре с ODP.NET

Процедура магазина проста:

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

BEGIN 

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

Путь I'am вызов из 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(); 

I'am получает исключение:

{"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

Это не меняет смысл моего комментария! Вы видели ссылку на документацию, которую я опубликовал? Существует также краткий пример, показывающий, как это должно быть сделано. Если вы не знаете, как правильно выполнять динамический SQL в PL/SQL, это не совсем подходит в вашем случае, это еще одна проблема, но попытайтесь отделить две вещи! –

ответ

0

Это решение работает для меня:

Oracle процедуры с ода:

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# код будет n чтобы выполнить его простым и правильным способом:

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); 

 Смежные вопросы

  • Нет связанных вопросов^_^