Проблема при вызове хранимой процедуры оракула из .net с пользовательским типом - PullRequest
0 голосов
/ 09 сентября 2018

Я пытаюсь вызвать хранимую процедуру Oracle, определенную в пакете Orracle. Процедура не имеет входных параметров, только выходной параметр определенного пользователем типа. Ниже приведены детали пакета и UDT:

CREATE OR REPLACE TYPE obj_systemdetail AS OBJECT
(
          sys_id VARCHAR2(8 CHAR),
          sys_name VARCHAR2(6 CHAR),
          sys_desc VARCHAR2(100 CHAR),
          sys_start_date DATE
);

CREATE OR REPLACE TYPE tab_systemdetailslist IS TABLE OF obj_systemdetail

CREATE OR REPLACE PACKAGE pck_sysDetails IS

    PROCEDURE get_systemdetails(p_system_details OUT NOCOPY tab_systemdetailslist);

END pck_sysDetails;

Попытка вызвать это из .net, как показано ниже

using Oracle.ManagedDataAccess.Client;

    OracleConnection conn = new OracleConnection("User Id=ptTest;Password=p1_sttest;Data Source=STMP231");
    OracleCommand cmd = conn.CreateCommand();
    cmd.CommandText = "pck_sysDetails.get_systemdetails";
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add(new OracleParameter("p_system_details", OracleDbType.Varchar2)
        {
            UdtTypeName = "tab_systemdetailslist",
            Size = 100,
            ArrayBindSize = new int[100],
            Direction = ParameterDirection.Output
        });
    conn.Open();
    cmd.ExecuteNonQuery();

Возможность подключиться к БД, но получаю эту ошибку при выполнении кода

ORA-06550: неверный номер или типы аргументов при вызове 'GET_SYSTEMDETAILS'

Пробовал много искать, но не смог найти ничего полезного о том, как установить этот тип UDT в качестве выходного параметра.

Пожалуйста, кто-нибудь может мне помочь в этом?

1 Ответ

0 голосов
/ 19 сентября 2018

Я думаю, что проблема в том, что ваш тип вывода не Varchar2, как вы определили в этой строке:

cmd.Parameters.Add(new OracleParameter("p_system_details", OracleDbType.Varchar2)

У вас есть p_system_details, определенный как объект varchar2s и даты, а не один varchar2. Тип возврата может быть Array в зависимости от того, какой драйвер доступа к данным Oracle вы используете. Например, это решение использует тип возврата Array для их UDT.

Если ваш драйвер должным образом не поддерживает UDT как тип, я думаю, что одним из вариантов является то, что вы изменяете тип возвращаемого значения вашей хранимой процедуры на что-то, что поддерживает драйвер, например что-то вроде Oracle SYS_REFCURSOR, определенного в .NET as OracleDbType.RefCursor может возвращать те же элементы данных, которые вы ищете.

create or replace PROCEDURE AOF_JOE_TEST_CURSOR_SP (p_system_details OUT SYS_REFCURSOR) AS

BEGIN
OPEN p_system_details FOR

SELECT
    'Test1' as sys_id,
    'Test2' as sys_name,
    'Test3' as sys_desc,
    SYSDATE as sys_start_date
FROM DUAL;

END;

Тогда ваш параметр определяется в .NET как:

OracleParameter cursorParameter = new OracleParameter();
cursorParameter.ParameterName = "p_system_details";
cursorParameter.Direction = ParameterDirection.Output;
cursorParameter.OracleDbType = OracleDbType.RefCursor;
cmd.Parameters.Add(cursorParameter);
...