Учитывая этот хранимый оракулом пакет процедур:
CREATE OR REPLACE
PACKAGE TESTPKG AS
FUNCTION TestReturnRefCursor RETURN SYS_REFCURSOR;
PROCEDURE TestingRefCursorsAsOutParam (outp OUT SYS_REFCURSOR);
END TESTPKG
И это тело пакета:
CREATE OR REPLACE
PACKAGE BODY TESTPKG AS
FUNCTION TestReturnRefCursor RETURN SYS_REFCURSOR AS
outp SYS_REFCURSOR;
BEGIN
OPEN outp FOR SELECT * FROM TABLENAME;
RETURN outp;
END TestReturnRefCursor;
PROCEDURE TestingRefCursorsAsOutParam (outp OUT SYS_REFCURSOR) AS
BEGIN
OPEN outp FOR SELECT * FROM TABLENAME;
END TestingRefCursorsAsOutParam;
END TESTPKG;
Я пытаюсь использовать Dapper для вызова любой функции. Я создал класс OracleDynamicParameters, реализующий Dapper.SqlMapper.IDynamicParameters, который я нашел в этом сообщении после поиска в StackOverflow: https://gist.github.com/vijaysg/3096151
Вызов хранимой функции TestReturnRefCursor отлично работает с этим кодом:
var conn = new OracleConnection(ConfigurationManager.ConnectionStrings["DataConnection"].ConnectionString);
conn.Open();
var p = new OracleDynamicParameters();
p.Add("retSet", dbType: OracleDbType.RefCursor, direction: ParameterDirection.ReturnValue);
conn.Execute("TESTPKG.TestReturnRefCursor ", param: p, commandType: CommandType.StoredProcedure);
var refcur = p.Get<OracleRefCursor>("retSet");
// do something with refcur
conn.Close();
Однако, когда я пытаюсь вызвать хранимую процедуру TestingRefCursorsAsOutParam с помощью этого кода:
var conn = new OracleConnection(ConfigurationManager.ConnectionStrings["DataConnection"].ConnectionString);
conn.Open();
var p = new OracleDynamicParameters();
p.Add("retSet", dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);
conn.Execute("TESTPKG.TestingRefCursorsAsOutParam ", param: p, commandType: CommandType.StoredProcedure);
var refcur = p.Get<OracleRefCursor>("retSet");
// do something with refcur
conn.Close();
Я получаю исключение OracleException из Oracle.ManagedDataAccess.dll с подробностями:
"ORA-06550: line 1, column 7:\nPLS-00306: wrong number or types of arguments in call to 'TESTINGREFCURSORSASOUTPARAM'\nORA-06550: line 1, column 7:\nPL/SQL: Statement ignored"
Я обнаружил после поиска другого поста stackoverflow, где иногда параметры не привязаны, если они равны нулю, если вы специально не установили их значение как DBNull.Value, поэтому я попытался изменить строку добавления параметра на:
p.Add("retSet", value: DBNull.Value, dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);
но это не помогло.
Я могу просто вызвать эту хранимую процедуру, используя обычный код оракула С#:
var cmd = conn.CreateCommand();
cmd.CommandText = "TESTPKG.TestingRefCursorsAsOutParam";
cmd.CommandType = CommandType.StoredProcedure;
var outparam = new OracleParameter();
outparam.ParameterName = "retSet";
outparam.Direction = ParameterDirection.Output;
outparam.OracleDbType = OracleDbType.RefCursor;
cmd.Parameters.Add(outparam);
OracleDataAdapter da = new OracleDataAdapter(cmd);
cmd.ExecuteNonQuery();
var refcur = (OracleRefCursor)cmd.Parameters[0].Value;
Я что-то упускаю или Dapper работает неправильно?
IParameterCallbacks
для проверки обновленных значений параметров. Есть ли какая-то причина, по которой вы не можете просто использовать предварительно свернутый классDynamicParameters
? - person Marc Gravell   schedule 09.12.2015code
p.Add(retSet, direction: ParameterDirection.Output);code
Я все еще получаю то же самое сообщение об ошибке, что и выше - неправильный номер или типы аргументов. - person J.T. Dorion   schedule 09.12.2015AddParameters
, который изменяется при добавлении параметров. - person Marc Gravell   schedule 09.12.2015OracleRefCursor
- немного похоже на это, но проще (в этом коде есть два разных представления —SqlGeography
, которое использует поставщик БД, иDbGeography
, которое использует EF; все, что вам действительно нужно настроить, этоOracleDbType
) - person Marc Gravell   schedule 09.12.2015