我想調用一個函數(oracle)使用nhibernate返回參考光標,但我沒有成功的hbm文件,任何人都可以引導我與此。nhibernate,在Oracle返回sys調用函數返回sys refcursor
如果我讓它像<return class ...
我得到配置錯誤。我試過{ ? = call package.function(:a, :b, :c) as result from dual }
,即使這樣也行不通。
我想調用一個函數(oracle)使用nhibernate返回參考光標,但我沒有成功的hbm文件,任何人都可以引導我與此。nhibernate,在Oracle返回sys調用函數返回sys refcursor
如果我讓它像<return class ...
我得到配置錯誤。我試過{ ? = call package.function(:a, :b, :c) as result from dual }
,即使這樣也行不通。
使用nHibernate調用ORACLE函數/過程時有一些限制。
正如reference documentation(17.2.2.1)指出:
對於Oracle有如下規則:
函數必須返回一個結果集。 過程的第一個參數必須是返回結果集的OUT。這是通過在Oracle 9或10中使用SYS_REFCURSOR類型 完成的。在Oracle中,您需要定義一個REF CURSOR類型的 ,請參見Oracle文獻。
我試着玩一點它,因爲我有同樣的問題。
這裏是PACKAGE-程序:
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幫助我瞭解一點必須怎樣做。
在我身邊和Oracle上,NHibernate似乎沒有包內的過程名稱。因此,我們假設前面的示例:call MYPACKAGE.usp_GetOrders (:pCompanyCode , :pOrderNumer)
- >導致包MyPackage
不是存儲過程。
WARN:Oracle.DataAccess.Client.OracleException ORA-06550:第1行,第7列:PLS-00221: 'mypackage的' 不是過程或未定義ORA-06550:第1行,第7列:
您是否爲該包創建了同義詞? – 2013-06-25 05:09:07
我解決它立足於這個職位mapping-to-oracle-stored-procedure-with-fluent-nhibernate
這裏是我的總結:
p_cursor OUT SYS_REFCURSOR, MyVar1 int, MyVar2 nvarchar
要返回resulset做
OPEN p_cursor FOR <select statement here>;
在我的情況是一個動態的查詢和它的作品就像一個魅力。
在HBM映射圍繞呼叫
{ }
EX之間:
{ call MyProc (MyVar1, MyVar2) }
如果不使用{ }
,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>
C#>
...
IQuery Q = session.GetNamedQuery("MyFunctionQuery")
.SetParameter("par", 1);
var result = Q.UniqueResult();
問候。
返回值是一個sys_refcursor,而不是標量值... – 2013-06-25 05:07:45
您的問題是否解決?我也很喜歡同樣的 – Vamsi 2011-07-19 11:14:39