我有一个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开发一个新的应用程序。
到目前为止,我已经能够映射我的所有实体并执行常规查询。一切正常。
我试图打电话给这个包,但我一直在犯错误。
这是PROCEDURE的映射:
<?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
我无法弄清楚我做错了什么! 有没有人可以帮助我?
答案 0 :(得分:4)
我设法让它发挥作用。 它可能不是最好的解决方案,但它确实有效。
这是我对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;
<强> 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必须始终是包中的第一个参数(documentation(17.2.2.1))
对于Oracle,以下规则适用:
函数必须返回结果集。 a的第一个参数 procedure必须是返回结果集的OUT。这是通过 在Oracle 9或10中使用SYS_REFCURSOR类型。在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();
}
如果有人感兴趣,我会尝试用更多infos来回答另一个问题。