#c# #oracle #stored-procedures #stored-functions #linq2db
#c# #Oracle #хранимые процедуры #сохраненные функции #linq2db
Вопрос:
Используя linq2db с базой данных Oracle 12, как я могу вызвать хранимую функцию или хранимую процедуру, которая возвращает значение? Судя по информации, которую я смог найти, решение, по-видимому, заключалось в использовании:
IEnumerable<T> QueryProc<T>(
this DataConnection connection,
string sql,
params DataParameter[] parameters);
Но это не работает с функциями и с сохраненным процессом, я не получаю выходное значение из процесса.
create or replace PROCEDURE TESTPROC(inputParm VARCHAR2, outputParm OUT VARCHAR2)
IS
BEGIN
outputParm := 'TEST OUTPUT STRING';
END TESTPROC;
Я вызываю это с помощью linq2db следующим образом:
DataParameter[] para = { new DataParameter("inputParm", "some_string", DataType.VarChar), new DataParameter("outputParm", "", DataType.VarChar) };
var res = myDataContext.QueryProc<string>("TESTPROC", para).FirstOrDefault();
Что я делаю не так?
Ответ №1:
Обновление: обновленный ответ, чтобы быть правильным
IEnumerable<T> QueryProc<T>(...)
возвращаемое значение — это набор данных, возвращаемый процедурой / функцией с помощью инструкции select.
Если ваша процедура не возвращает таблицу, вам нужно использовать не общую версию ExecuteProc
, которая просто возвращает количество затронутых записей.
Чтобы получить значение выходного параметра, вам необходимо получить доступ к параметру в command: ((IDbDataParameter)dataConnection.Command.Parameters["parameter_name"]).Value
ниже приведен пример помощника по вызову процедуры из тестов linq2db, сгенерированных шаблоном T4:
public static int OUTREFTEST(this DataConnection dataConnection, decimal? PID, out decimal? POUTPUTID, ref decimal? PINPUTOUTPUTID, string PSTR, out string POUTPUTSTR, ref string PINPUTOUTPUTSTR)
{
var ret = dataConnection.ExecuteProc("TESTUSER.OUTREFTEST",
new DataParameter("PID", PID, DataType.Decimal),
new DataParameter("POUTPUTID", null, DataType.Decimal) { Direction = ParameterDirection.Output, Size = 22 },
new DataParameter("PINPUTOUTPUTID", PINPUTOUTPUTID, DataType.Decimal) { Direction = ParameterDirection.InputOutput, Size = 22 },
new DataParameter("PSTR", PSTR, DataType.NVarChar),
new DataParameter("POUTPUTSTR", null, DataType.NVarChar) { Direction = ParameterDirection.Output },
new DataParameter("PINPUTOUTPUTSTR", PINPUTOUTPUTSTR, DataType.NVarChar) { Direction = ParameterDirection.InputOutput });
POUTPUTID = Converter.ChangeTypeTo<decimal?>(((IDbDataParameter)dataConnection.Command.Parameters["POUTPUTID"]). Value);
PINPUTOUTPUTID = Converter.ChangeTypeTo<decimal?>(((IDbDataParameter)dataConnection.Command.Parameters["PINPUTOUTPUTID"]). Value);
POUTPUTSTR = Converter.ChangeTypeTo<string> (((IDbDataParameter)dataConnection.Command.Parameters["POUTPUTSTR"]). Value);
PINPUTOUTPUTSTR = Converter.ChangeTypeTo<string> (((IDbDataParameter)dataConnection.Command.Parameters["PINPUTOUTPUTSTR"]).Value);
return ret;
}