Вызов ПРОЦЕДУРЫ с выходными параметрами - PullRequest
0 голосов
/ 22 февраля 2012

У меня есть пакет ORACLE, который получает несколько параметров и возвращает - с некоторыми другими (выходными) параметрами - уникальное значение (число).
Вот код пакета:

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. До сих пор я был в состоянии отобразить все свои объекты и выполнять регулярные запросы. Все отлично работает.
Я пытался вызвать этот пакет, но продолжаю получать ошибки.

Это отображение для ПРОЦЕДУРЫ:

<?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(), но я могу получить только исключения:

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:

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

Я не могу понять, что я делаю неправильно! Есть кто-нибудь, кто может мне помочь?

1 Ответ

4 голосов
/ 23 февраля 2012

Мне удалось заставить его работать. Возможно, это не лучшее решение, но оно работает.

Это мое отображение для 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:

HEADER:

create or replace
PACKAGE           "MY_PACKAGE" AS

    TYPE ReferenceCursor IS REF CURSOR;

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

END MY_PACKAGE;

BODY:

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 вместо этого.

REF CURSOR всегда должен быть первым параметром в пакете ( документация (17.2.2.1))

Для Oracle применяются следующие правила :

Функция должна возвращать набор результатов. Первый параметр Процедура должна быть OUT, которая возвращает набор результатов. Это сделано используя тип SYS_REFCURSOR в Oracle 9 или 10. В Oracle вам нужно определить тип REF CURSOR, см. литературу по Oracle.

Поскольку я хочу вернуть уникальный результат и управляю сложным типом, я создал класс:

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();
    }

Если кому-то интересно, я попытался ответить на другой вопрос еще с помощью информация .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...