nhibernate を使用して ref カーソルを返す関数 (オラクル) を呼び出そうとしていますが、hbm ファイルでうまくいきません。
<return class ...
構成エラーが発生するようにすると。
試してみ{ ? = call package.function(:a, :b, :c) as result from dual }
ましたが、これでもうまくいきません。
nhibernate を使用して ref カーソルを返す関数 (オラクル) を呼び出そうとしていますが、hbm ファイルでうまくいきません。
<return class ...
構成エラーが発生するようにすると。
試してみ{ ? = call package.function(:a, :b, :c) as result from dual }
ましたが、これでもうまくいきません。
nHibernate で ORACLE 関数/プロシージャを呼び出す場合、いくつかの制限があります。参照ドキュメント(17.2.2.1)
に記載されているとおり:
Oracle の場合、次の規則が適用されます。
関数は結果セットを返す必要があります。プロシージャーの最初のパラメーターは、結果セットを返す OUT でなければなりません。これは、Oracle 9 または 10 で SYS_REFCURSOR タイプを使用して行われます。Oracle では、REF CURSOR タイプを定義する必要があります。Oracle の資料を参照してください。
私は同じ問題を抱えているので、少し遊んでみました。
パッケージ手順は次のとおりです。
頭:
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;
体:
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>();
この記事は、物事をどのように行う必要があるかを理解するのに役立ちました。
この投稿に基づいて解決します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 は「引数の数が正しくありません」という例外をスローします。
これが誰かに役立つことを願っています。
私の側と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: