调用返回值的数据库存储函数或存储过程

Posted

技术标签:

【中文标题】调用返回值的数据库存储函数或存储过程【英文标题】:Calling a database stored function or stored proc that returns a value 【发布时间】:2019-03-28 10:30:28 【问题描述】:

使用 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&lt;T&gt; QueryProc&lt;T&gt;(...)返回值是一个数据集,由过程/函数通过select语句返回。

如果你的过程不返回表,你需要使用ExecuteProc的非泛型版本,它只返回受影响的记录数。

要获取输出参数值,您需要在命令中访问参数: ((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;
    

【讨论】:

以上是关于调用返回值的数据库存储函数或存储过程的主要内容,如果未能解决你的问题,请参考以下文章

oracle函数和存储过程有什么区别

存储过程和函数的区别

MySQL高级存储过程/函数/触发器

procrdure存储过程

用JAVA调用Mysql数据库,数据存储过程的封装与调用;

存储过程和存储函数区别