我正在尝试使用返回引用游标的nhibernate来调用函数(oracle),但我对hbm文件没有成功,任何人都可以用这个来指导我。
如果我将其设为<return class ...
我收到配置错误。
我尝试{ ? = call package.function(:a, :b, :c) as result from dual }
,即使这也无效。
答案 0 :(得分:4)
使用nHibernate调用ORACLE函数/过程时存在一些限制 如reference documentation(17.2.2.1)中所述:
对于Oracle,以下规则适用:
函数必须返回结果集。 a的第一个参数 procedure必须是返回结果集的OUT。这是通过 在Oracle 9或10中使用SYS_REFCURSOR类型。在Oracle中,您需要 定义REF CURSOR类型,参见Oracle文献。
由于遇到同样的问题,我试图用它来玩一点。
这是PACKAGE-PROCEDURE:
HEAD:
create or replace
PACKAGE "MYPACKAGE" AS
TYPE ReferenceCursor IS REF CURSOR;
PROCEDURE usp_GetDual
(
pCursor OUT ReferenceCursor,
a IN CHAR,
b IN CHAR
);
END MYPACKAGE;
<强> BODY:强>
PROCEDURE usp_GetDual
(
pCursor OUT ReferenceCursor,
a IN CHAR,
b IN CHAR
)
IS
err_code NUMBER;
err_msg VARCHAR2(200);
BEGIN
OPEN pCursor FOR
SELECT * FROM dual;
EXCEPTION
WHEN OTHERS THEN
err_code := SQLCODE;
err_msg := substr(SQLERRM, 1, 200);
END usp_GetDual;
这是我的映射文件:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MyAssembly">
<sql-query name="GetDaul">
{ call MYPACKAGE.usp_GetDual ( :a, :b ) }
</sql-query>
</hibernate-mapping>
这是我用来测试它的代码:
var value = Session.GetNamedQuery("GetDaul")
.SetParameter<string>("a", "AAA")
.SetParameter<string>("b", "BBB")
.UniqueResult();
正如您所看到的,REF CURSOR必须是您程序中的第一个参数(pCursor OUT ReferenceCursor
),您无需在映射或通话中引用它。
如果你想要返回实体,事情会变得更复杂。
您的映射文件必须指定返回类型(类):
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MyAssembly">
<sql-query name="GetOrders">
<return class="MyAssembly.Domain.MyOrder, MyAssembly" />
{ call MYPACKAGE.usp_GetOrders ( :pCompanyCode , :pOrderNumer ) }
</sql-query>
</hibernate-mapping>
您必须定义您的实体:
public class MyOrder
{
public virtual string Number { get; set; }
public virtual int Ver { get; private set; }
public virtual string Company { get; set; }
public virtual string Customer { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
Order order = obj as Order;
if (order == null)
return false;
if (this.Number.Trim() == order.Number.Trim() &&
this.Ver == order.Ver &&
this.Company.Trim() == order.Company.Trim()
)
return true;
else
return false;
}
public override int GetHashCode()
{
int hash = 0;
hash = hash +
(null == this.Number ? 0 : this.Number.GetHashCode())
+
(this.Ver.GetHashCode())
+
(null == this.Company ? 0 : this.Company.GetHashCode());
return (hash);
}
}
这是您实体的映射文件:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MyAssembly" namespace="MyAssembly.Domain">
<class name="MyOrder" table="OCSAORH" mutable="false">
<composite-id>
<key-property name="Number" column="OCHORDN" type="String" length="10"></key-property>
<key-property name="Ver" column="OCHAMND" type="Int32"></key-property>
<key-property name="Company" column="OCHCOSC" type="String" length="5"></key-property>
</composite-id>
<property name="Customer" column="OCHCLII" type="String"></property>
</class>
</hibernate-mapping>
这是我的ORACLE套餐:
PROCEDURE usp_GetOrders
(
pCursor OUT ReferenceCursor,
pCompanyCode IN CHAR,
pOrderNumer IN CHAR
)
IS
err_code NUMBER;
err_msg VARCHAR2(200);
BEGIN
OPEN pCursor FOR
SELECT
OCSAORH.*
FROM OCSAORH
WHERE OCSAORH.OCHAMND = 0
AND OCSAORH.OCHCOSC = pCompanyCode
AND OCSAORH.OCHORDN = pOrderNumer;
EXCEPTION
WHEN OTHERS THEN
err_code := SQLCODE;
err_msg := substr(SQLERRM, 1, 200);
END usp_GetOrders;
现在您可以使用参数轻松获取订单:
var listOfOrders = Session.GetNamedQuery("GetOrder")
.SetParameter<string>("pCompanyCode", "ABC")
.SetParameter<string>("pOrderNumer", "XYZ")
.List<Domain.MyOrder>();
这article帮助我了解必须如何做。
答案 1 :(得分:1)
我根据这篇文章mapping-to-oracle-stored-procedure-with-fluent-nhibernate
解决了这个问题以下是我的总结:
OUT SYS_REFCURSOR
的第一个参数。例如:p_cursor OUT SYS_REFCURSOR, MyVar1 int, MyVar2 nvarchar
要返回结果集
OPEN p_cursor FOR <select statement here>;
在我的案例中,是一个动态查询,它就像一个魅力。
在hbm映射中围绕
之间的调用{ }
前:
{ call MyProc (MyVar1, MyVar2) }
如果您不使用{ }
,则nhibernate会抛出“参数数量不正确”的异常。
我希望这有助于某人。
答案 2 :(得分:0)
在我和Oracle上使用相同的东西,NHibernate似乎在程序包内部松开了程序的名称。所以我们先假设一个例子:call MYPACKAGE.usp_GetOrders ( :pCompanyCode , :pOrderNumer )
- &gt;包MyPackage
不是存储过程的结果。
警告:Oracle.DataAccess.Client.OracleException ORA-06550:第1行第7列:PLS-00221:'MYPACKAGE'不是程序或未定义ORA-06550:第1行第7列:
答案 3 :(得分:-1)
我遇到了同样的麻烦。我解决了这个问题:
MyPackage中的Oracle PL / SQL:
...
function MyFunction(a number) return number is
n number;
pragma autonomous_transaction; -- Important!
begin
n:=apps.fnd_request.submit_request( ... );
commit; -- Important!
return n;
end;
mapping.hbm.xml :(嵌入式资源)
...
<sql-query name='MyFunctionQuery'>
<query-param name='par' type='System.Int64'/>
<return-scalar column='ret' type='System.Int64'/>
<![CDATA[
select MyPackage.MyFunction(:par) as ret from dual
]]>
</sql-query>
C#&GT;
...
IQuery Q = session.GetNamedQuery("MyFunctionQuery")
.SetParameter("par", 1);
var result = Q.UniqueResult();
最好的问候。