Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

nhibernate, Oracle में कॉल फ़ंक्शन जो sys refcursor लौटाता है

ORACLE फ़ंक्शन/प्रक्रियाओं को nHibernate के साथ कॉल करते समय कुछ सीमाएँ होती हैं।
जैसा कि संदर्भ दस्तावेज़ीकरण (17.2.2.1) में बताया गया है:

<ब्लॉकक्वॉट>

Oracle के लिए निम्नलिखित नियम लागू होते हैं :

एक फ़ंक्शन को परिणाम सेट वापस करना होगा। प्रक्रिया का पहला पैरामीटर एक आउट होना चाहिए जो एक परिणाम सेट देता है। यह 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>

यह मेरा ओरेकल पैकेज है:

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>();

इस लेख ने मुझे यह समझने में मदद की कि काम कैसे किया जाना चाहिए।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL चयन कथन में पैकेज स्थिरांक का उपयोग कैसे करें?

  2. ऑरैकल में व्यू कैसे बनाएं

  3. ईबीएस 12.2 . में वेब पोर्ट कैसे बदलें

  4. कनेक्शन स्ट्रिंग पर सेवा नाम के बजाय SID का उपयोग करते समय cx_Oracle कनेक्ट नहीं होता है

  5. Oracle डेटाबेस में PL/SQL पैकेज कैसे बनाएँ?