调用带有输出参数的过程 [英] Calling a PROCEDURE with output parameters

查看:84
本文介绍了调用带有输出参数的过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ORACLE软件包,该软件包接收很少的参数并返回-带有一些其他(输出)参数-唯一值(数字).
这是程序包代码:

I've got an ORACLE package which receives few parameters and returns - with some other (output) parameters - a unique value (number).
Here's is the package code:

create or replace
PACKAGE BODY           "USP_SHIPMENTS" AS

    PROCEDURE  usp_GetNewShipmentNumber
    (
    pErrorCode OUT NUMBER,
    pMessage OUT VARCHAR2,      
    pCompanyCode IN CHAR,
    pNumber OUT VARCHAR2
    )

    IS

      BEGIN

    pErrorCode := 0;

       UPDATE 
        UTSASHN
       SET 
        UTSASHN.UTSHNCOR = UTSASHN.UTSHNCOR + 1
       WHERE 
        UTSASHN.UTSHCOSC = pCompanyCode AND UTSASHN.UTSHTIPO = 'S***'
    RETURNING 
        CONCAT(TRIM(UTSASHN.UTSHDESC) , TRIM(to_char(UTSASHN.UTSHNCOR, '000000'))) INTO pNumber;

    EXCEPTION
        WHEN OTHERS THEN 
              pErrorCode := SQLCODE;
              ROLLBACK;

    END usp_GetNewShipmentNumber;

END USP_SHIPMENTS;

我已经使用ODP.NET长期使用了此软件包,并且一切正常. 现在,我正在使用nHibernate 3.1.0.4000开发一个新的应用程序. 到目前为止,我已经能够映射所有实体并执行常规查询.一切正常.
我试图打电话给这个包裹,但我不断出错.

I've been using this package for a long time using ODP.NET and everything has always worked properly.
Now I am developing a new App with nHibernate 3.1.0.4000. So far I've been able to map all my entities and execute regular queries. Everything works fine.
I was trying to call this package but I keep on getting errors.

这是该过程的映射:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="BpSpedizioni" namespace="BpSpedizioni.Domain">
    <sql-query name="GetNewShipmentNumber">
        { call USP_SHIPMENTS.usp_GetNewShipmentNumber ( :pErrorCode, :pMessage, :pCompanyCode, :pNumber) }
    </sql-query>
</hibernate-mapping>

这是电话:

Session.GetNamedQuery("GetNewShipmentNumber")
      .SetParameter("pErrorCode", "")
      .SetParameter("pMessage", "")
      .SetParameter<string>("pCompanyCode", "HBP00")
      .SetParameter("pNumber", 0)
      .UniqueResult();

我尝试使用.UniqueResult().ExecuteUpdate().List(),但是我只能得到例外:

I've tried with .UniqueResult() or .ExecuteUpdate() or .List() but I can only get exceptions:

could not execute query
[ USP_SHIPMENTS.usp_GetNewShipmentNumber ]
  Name:pErrorCode - Value:  Name:pMessage - Value:  Name:pCompanyCode - Value:HBP00  Name:pNumber - Value:0
[SQL: USP_SHIPMENTS.usp_GetNewShipmentNumber]

这是InnerException:

and this is the InnerException:

ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'USP_GETNEWSHIPMENTNUMBER'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

我不知道自己在做什么错! 有谁可以帮助我吗?

I can't figure out what I am doing wrong! Is there anybody who can help me?

推荐答案

我设法使其正常运行. 它可能不是最好的解决方案,但它可以工作.

I managed to make it work. It might not be the best solution but it works.

这是我对ORACLE PROCEDURE的映射:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MyAssembly">
    <sql-query name="GetNewShipmentNumber">
        { call MY_PACKAGE.usp_GetNewShipmentNumber ( :pCompanyCode ) }
    </sql-query>
</hibernate-mapping>

这是ORACLE PACKAGE:

标题:

create or replace
PACKAGE           "MY_PACKAGE" AS

    TYPE ReferenceCursor IS REF CURSOR;

    PROCEDURE  usp_GetNewShipmentNumber
        (
        pCursor OUT ReferenceCursor,
        pCompanyCode IN CHAR
        );

END MY_PACKAGE;

身体:

create or replace
PACKAGE BODY           "MY_PACKAGE" AS

PROCEDURE  usp_GetNewShipmentNumber
    (
        pCursor OUT ReferenceCursor,
        pCompanyCode IN CHAR
    )

IS

    err_code NUMBER := 0;
    err_msg VARCHAR2(200) := '';
    ShipmentNumber VARCHAR2(10);

  BEGIN

   UPDATE 
        UTSASHN
   SET 
        UTSASHN.UTSHNCOR = UTSASHN.UTSHNCOR + 1
   WHERE 
        UTSASHN.UTSHCOSC = pCompanyCode AND UTSASHN.UTSHTIPO = 'S***'
    RETURNING 
        CONCAT(TRIM(UTSASHN.UTSHDESC) , TRIM(to_char(UTSASHN.UTSHNCOR, '000000'))) INTO ShipmentNumber;

    OPEN pCursor FOR
          SELECT ShipmentNumber AS DeliveryNoteNumber, err_code AS ErrorCode, err_msg AS ErrorMessage FROM DUAL;

    EXCEPTION
        WHEN OTHERS THEN 
          err_code := SQLCODE;
          err_msg := substr(SQLERRM, 1, 200);
          ROLLBACK;

    OPEN pCursor FOR
          SELECT '' AS DeliveryNoteNumber, err_code AS ErrorCode, err_msg AS ErrorMessage FROM DUAL;

END usp_GetNewShipmentNumber;

END MY_PACKAGE;

如您所见,我摆脱了返回参数,这些参数显然不适用于nHibernate.
我返回的是REF CURSOR.

As you can see I got rid of the return parameters which, apparently, do not work with nHibernate.
I am returning a REF CURSOR instead.

REF CURSOR必须始终是程序包中的第一个参数(文档(17.2.2.1))

A REF CURSOR must always be the first parameter in a package (documentation (17.2.2.1))

对于Oracle,以下规则适用:

一个函数必须返回一个结果集.一个的第一个参数 过程必须是返回结果集的OUT.这是通过 在Oracle 9或10中使用SYS_REFCURSOR类型.在Oracle中,您需要 定义REF CURSOR类型,请参见Oracle文献.

A function must return a result set. The first parameter of a procedure must be an OUT that returns a result set. This is done by using a SYS_REFCURSOR type in Oracle 9 or 10. In Oracle you need to define a REF CURSOR type, see Oracle literature.

由于我想返回唯一的结果,并且要管理复杂的类型,所以我创建了一个类:

Since I want to return a unique result and I am managing a complex type I've created a class:

public class NewDeliveryNoteNumber
{
    public string DELIVERYNOTENUMBER { get; set; }
    public decimal ERRORCODE { get; set; }
    public string ERRORMESSAGE { get; set; }
}

将很容易这样填充:

using (var tx = Session.BeginTransaction())
    {
    var x = Session.GetNamedQuery("GetNewShipmentNumber")
        .SetParameter<string>("pCompanyCode", "ABC")
        .SetResultTransformer(Transformers.AliasToBean<NewDeliveryNoteNumber>())
        .UniqueResult<NewDeliveryNoteNumber>();

    tx.Commit();
    }

如果有人感兴趣,我尝试用更多的信息来回答另一个问题.

If someone is interested I've tried to answer another question with some more infos.

这篇关于调用带有输出参数的过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆