nhibernate,调用Oracle中返回sys refcursor的函数
我正在尝试使用返回ref cursor的nhibernate调用一个函数oracle,但是我没有成功使用hbm文件,请任何人指导我nhibernate,调用Oracle中返回sys refcursor的函数,oracle,nhibernate,function,sys-refcursor,Oracle,Nhibernate,Function,Sys Refcursor,我正在尝试使用返回ref cursor的nhibernate调用一个函数oracle,但是我没有成功使用hbm文件,请任何人指导我 如果我将其设置为使用nHibernate调用ORACLE函数/过程时会有一些限制。 如17.2.2.1所述: 对于Oracle,以下规则适用: 函数必须返回结果集。a的第一个参数 过程必须是返回结果集的输出。这是由 在Oracle 9或10中使用SYS_REFCURSOR类型。在Oracle中,您需要 定义引用游标类型,请参见Oracle文献 我试着用它玩一点,因为
如果我将其设置为使用nHibernate调用ORACLE函数/过程时会有一些限制。 如17.2.2.1所述: 对于Oracle,以下规则适用: 函数必须返回结果集。a的第一个参数 过程必须是返回结果集的输出。这是由 在Oracle 9或10中使用SYS_REFCURSOR类型。在Oracle中,您需要 定义引用游标类型,请参见Oracle文献 我试着用它玩一点,因为我有同样的问题 以下是程序包: 负责人: 正文: 这是我的映射文件:
<?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>
您必须定义您的实体:
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>
这是实体的映射文件:
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>
现在,您可以使用以下参数轻松获得订单:
var listOfOrders = Session.GetNamedQuery("GetOrder")
.SetParameter<string>("pCompanyCode", "ABC")
.SetParameter<string>("pOrderNumer", "XYZ")
.List<Domain.MyOrder>();
这有助于我理解必须如何做。对于我和Oracle来说,同样的事情,NHibernate似乎在包中丢失了过程的名称。因此,让我们假设前面的示例:call MYPACKAGE.usp_GetOrders:pCompanyCode,:pOrderNumer->result包MYPACKAGE不是存储过程 警告:Oracle.DataAccess.Client.OracleException ORA-06550:第1行第7列:PLS-00221:“MYPACKAGE”不是过程或未定义ORA-06550:第1行第7列:
我是根据这篇文章来解决的 以下是我的总结: 在该过程中,必须声明类型为OUT SYS\u REFCURSOR的第一个参数。例如:p_cursor OUT SYS_REFCURSOR、MyVar1 int、MyVar2 nvarchar 要返回结果集,请执行以下操作:
OPEN p_cursor FOR <select statement here>;
例:
如果不使用{},nhibernate将抛出参数数目不正确的异常
我希望这对别人有帮助。我也遇到了同样的麻烦。我解决了这个问题: 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>
问候。您的问题解决了吗?我也被你们为这个软件包创建的同义词打动了?这篇文章很好。但如果我们需要使用存储函数而不是返回sys_refcursor的过程,我们怎么做呢?@Sash0k:这会很棘手。据我记忆所及,你不能这样做,但事情可能已经改变了。这帮了大忙。如果您得到错误ORA-06553:PLS-306:call to PROCEDURE中参数的数目或类型错误,请确保按照以下建议将调用包装到{}。我得到一个错误:OracleClientDriver不支持CallableStatement语法存储过程。请考虑使用Oracle DATAcLITCHORKER。
OPEN p_cursor FOR <select statement here>;
{ }
{ call MyProc (MyVar1, MyVar2) }
...
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;
...
<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>
...
IQuery Q = session.GetNamedQuery("MyFunctionQuery")
.SetParameter("par", 1);
var result = Q.UniqueResult();