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

टेबल और ट्रांजैक्शन एपीआई के बीच अंतर को समझना

आइए टेबल एपीआई से शुरू करें। यह पीएल/एसक्यूएल एपीआई के माध्यम से टेबल तक पहुंच में मध्यस्थता का अभ्यास है। तो, हमारे पास प्रति टेबल एक पैकेज है, जिसे डेटा डिक्शनरी से जेनरेट किया जाना चाहिए। पैकेज तालिका के खिलाफ डीएमएल जारी करने और डेटा पुनर्प्राप्त करने के लिए कुछ कार्यों के लिए प्रक्रियाओं का एक मानक सेट प्रस्तुत करता है।

तुलना करके एक लेन-देन संबंधी एपीआई कार्य की एक इकाई का प्रतिनिधित्व करता है। यह अंतर्निहित डेटाबेस ऑब्जेक्ट्स के बारे में किसी भी जानकारी का खुलासा नहीं करता है। लेन-देन संबंधी एपीआई बेहतर एनकैप्सुलेशन और एक क्लीनर इंटरफ़ेस प्रदान करते हैं।

कंट्रास्ट इस प्रकार है। नया विभाग बनाने के लिए इन व्यावसायिक नियमों पर विचार करें:

  1. नए विभाग का एक नाम और स्थान होना चाहिए
  2. नए विभाग में एक प्रबंधक होना चाहिए, जो एक मौजूदा कर्मचारी होना चाहिए
  3. अन्य मौजूदा कर्मचारियों को नए विभाग में स्थानांतरित किया जा सकता है
  4. नए विभाग को नए कर्मचारी सौंपे जा सकते हैं
  5. नए विभाग में कम से कम दो कर्मचारी (प्रबंधक सहित) असाइन किए जाने चाहिए

टेबल एपीआई का इस्तेमाल करते हुए लेन-देन कुछ इस तरह दिख सकता है:

DECLARE
    dno pls_integer;
    emp_count pls_integer;
BEGIN
    dept_utils.insert_one_rec(:new_name, :new_loc, dno);
    emp_utils.update_one_rec(:new_mgr_no ,p_job=>'MGR’ ,p_deptno=>dno);
    emp_utils.update_multi_recs(:transfer_emp_array, p_deptno=>dno);
    FOR idx IN :new_hires_array.FIRST..:new_hires_array.LAST LOOP
        :new_hires_array(idx).deptno := dno;
    END LOOP;
    emp_utils.insert_multi_recs(:new_hires_array);
    emp_count := emp_utils.get_count(p_deptno=>dno); 
    IF emp_count < 2 THEN
        raise_application_error(-20000, ‘Not enough employees’);
    END IF;
END;
/

जबकि एक लेन-देन संबंधी एपीआई के साथ यह बहुत आसान है:

DECLARE
    dno subtype_pkg.deptno;
BEGIN
    dept_txns.create_new_dept(:new_name
                                , :new_loc
                                , :new_mgr_no
                                , :transfer_emps_array
                                , :new_hires_array
                                , dno);
END;
/

तो डेटा पुनर्प्राप्त करने में अंतर क्यों? क्योंकि लेन-देन संबंधी एपीआई दृष्टिकोण जेनेरिक get() . को हतोत्साहित करता है अक्षम चयन कथनों के नासमझी से उपयोग से बचने के लिए कार्य करता है।

उदाहरण के लिए, यदि आप किसी कर्मचारी के लिए केवल वेतन और कमीशन चाहते हैं, तो यह प्रश्न पूछें ...

select sal, comm
into l_sal, l_comm
from emp
where empno = p_eno;

... इसे क्रियान्वित करने से बेहतर है...

l_emprec := emp_utils.get_whole_row(p_eno);

...खासकर यदि कर्मचारी रिकॉर्ड में LOB कॉलम हैं।

यह इससे भी अधिक कुशल है:

l_sal := emp_utils.get_sal(p_eno);
l_comm := emp_utils.get_comm(p_eno);

... यदि उनमें से प्रत्येक गेटर्स एक अलग SELECT स्टेटमेंट निष्पादित करता है। जो अज्ञात नहीं है:यह एक खराब ओओ अभ्यास है जो भयानक डेटाबेस प्रदर्शन की ओर जाता है।

टेबल एपीआई के प्रस्तावक उनके लिए इस आधार पर तर्क देते हैं कि वे डेवलपर को एसक्यूएल के बारे में सोचने की आवश्यकता से बचाते हैं। जो लोग उन्हें बहिष्कृत करते हैं वे टेबल एपीआई को नापसंद करते हैं उसी कारण से . यहां तक ​​​​कि सर्वश्रेष्ठ टेबल एपीआई भी आरबीएआर प्रसंस्करण को प्रोत्साहित करते हैं। यदि हम हर बार अपना स्वयं का SQL लिखते हैं तो हम सेट-आधारित दृष्टिकोण चुनने की अधिक संभावना रखते हैं।

लेन-देन संबंधी APIs का उपयोग करने से get_resultset() के उपयोग को अनिवार्य रूप से खारिज नहीं किया जा सकता है कार्य। एक क्वेरीिंग एपीआई में अभी भी बहुत अधिक मूल्य है। लेकिन यह अलग-अलग टेबल पर SELECTs की तुलना में जॉइन को लागू करने वाले विचारों और कार्यों से निर्मित होने की अधिक संभावना है।

संयोग से, मुझे लगता है कि टेबल एपीआई के शीर्ष पर ट्रांजेक्शनल एपीआई बनाना एक अच्छा विचार नहीं है:हमने अभी भी सावधानीपूर्वक लिखे गए जॉइन के बजाय एसक्यूएल स्टेटमेंट्स को बंद कर दिया है।

उदाहरण के तौर पर, यहां एक क्षेत्र में प्रत्येक कर्मचारी के वेतन को अद्यतन करने के लिए एक ट्रांजेक्शनल एपीआई के दो अलग-अलग कार्यान्वयन हैं (क्षेत्र संगठन का एक बड़ा वर्ग है; विभागों को क्षेत्रों को सौंपा गया है)।

पहले संस्करण में कोई शुद्ध एसक्यूएल नहीं है बस टेबल एपीआई कॉल, मुझे नहीं लगता कि यह एक स्ट्रॉ मैन है:यह टेबल एपीआई पैकेज में देखी गई कार्यक्षमता का उपयोग करता है (हालांकि कुछ SET_XXX() प्रक्रियाओं के नाम के बजाय गतिशील एसक्यूएल का उपयोग करते हैं) .

create or replace procedure adjust_sal_by_region
    (p_region in dept.region%type
           , p_sal_adjustment in number )
as
    emps_rc sys_refcursor;
    emp_rec emp%rowtype;
    depts_rc sys_refcursor;
    dept_rec dept%rowtype;
begin
    depts_rc := dept_utils.get_depts_by_region(p_region);

    << depts >>
    loop
        fetch depts_rc into dept_rec;
        exit when depts_rc%notfound;
        emps_rc := emp_utils.get_emps_by_dept(dept_rec.deptno);

        << emps >>
        loop
            fetch emps_rc into emp_rec;
            exit when emps_rc%notfound;
            emp_rec.sal := emp_rec.sal * p_sal_adjustment;
            emp_utils.set_sal(emp_rec.empno, emp_rec.sal);
        end loop emps;

    end loop depts;

end adjust_sal_by_region;
/

SQL में समतुल्य कार्यान्वयन:

create or replace procedure adjust_sal_by_region
    (p_region in dept.region%type
           , p_sal_adjustment in number )
as
begin
    update emp e
    set e.sal = e.sal * p_sal_adjustment
    where e.deptno in ( select d.deptno 
                        from dept d
                        where d.region = p_region );
end adjust_sal_by_region;
/

यह नेस्टेड कर्सर लूप और पिछले संस्करण के सिंगल रो अपडेट की तुलना में बहुत अच्छा है। ऐसा इसलिए है क्योंकि SQL में यह शामिल होने के लिए एक चिंच है जिसे हमें क्षेत्र द्वारा कर्मचारियों का चयन करने की आवश्यकता है। टेबल एपीआई का उपयोग करना बहुत कठिन है, क्योंकि क्षेत्र कर्मचारियों की कुंजी नहीं है।

निष्पक्ष होने के लिए, अगर हमारे पास एक टेबल एपीआई है जो गतिशील एसक्यूएल का समर्थन करती है, तो चीजें बेहतर हैं लेकिन फिर भी आदर्श नहीं हैं:

create or replace procedure adjust_sal_by_region
    (p_region in dept.region%type
           , p_sal_adjustment in number )
as
    emps_rc sys_refcursor;
    emp_rec emp%rowtype;
begin
    emps_rc := emp_utils.get_all_emps(
                    p_where_clause=>'deptno in ( select d.deptno 
                        from dept d where d.region = '||p_region||' )' );

    << emps >>
    loop
        fetch emps_rc into emp_rec;
        exit when emps_rc%notfound;
        emp_rec.sal := emp_rec.sal * p_sal_adjustment;
        emp_utils.set_sal(emp_rec.empno, emp_rec.sal);
    end loop emps;

end adjust_sal_by_region;
/

अंतिम शब्द

यह सब कहने के बाद, ऐसे परिदृश्य हैं जहां टेबल एपीआई उपयोगी हो सकते हैं, ऐसी स्थितियाँ जब हम केवल एक ही टेबल के साथ काफी मानक तरीकों से बातचीत करना चाहते हैं। एक स्पष्ट मामला अन्य प्रणालियों से डेटा फ़ीड का उत्पादन या उपभोग करना हो सकता है उदा। ईटीएल।

यदि आप टेबल एपीआई के उपयोग की जांच करना चाहते हैं, तो शुरू करने के लिए सबसे अच्छी जगह स्टीवन फ्यूरस्टीन की क्वेस्ट कोडजेन यूटिलिटी (पूर्व में क्यूएनएक्सओ) है। यह लगभग उतना ही अच्छा है जितना TAPI जनरेटरों को मिलता है, और यह मुफ़्त है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. एक ट्रिगर बनाएं जो एक टेबल पर कॉलम अपडेट करता है जब दूसरी टेबल में कॉलम अपडेट होता है

  2. क्या CASE स्टेटमेंट और DECODE समकक्ष हैं?

  3. केवल समय कैसे स्टोर करें; तारीख और समय नहीं?

  4. ORA-1114 रनिंग डाटापैच

  5. Oracle के लिए हल्का