ओरेकल में अस्थायी टेबल या टेबल चर का उपयोग करके SQL सर्वर संग्रहीत प्रक्रियाओं को कैसे स्थानांतरित किया जाए?


9

C # डेवलपर SQL सर्वर संग्रहित प्रक्रियाओं को लिखने के लिए प्रबंधन द्वारा प्रोत्साहित किया जाता है जो अक्सर इस तरह की प्रक्रियाओं का उत्पादन करते हैं

create table #t1 (...);
insert into #t1 Select ... from table_a where ...;
insert into #t1 Select ... from table_b where ...;
update #t1 Set ... = ... where ...
Select * from #t1;

एकल कथन बल्कि सरल हैं और यह विधि उन्हें सही परिणाम प्रदान करती है।

अक्सर मेरा काम ओरेकल के लिए ऐसी प्रक्रियाओं को स्थानांतरित करना है।

आइए निम्नलिखित तथ्यों का सामना करें।

  • एसक्यूएल सर्वर में विभिन्न अस्थायी तालिकाओं के लिए पूरी तरह से स्वतंत्र हैं और किसी भी तदर्थ संरचना हो सकता है।
  • ओरेकल वैश्विक आम टेबल वैश्विक वस्तुएं हैं और सभी एक ही तालिका संरचना का बहुत अधिक उपयोग करते हैं। इस संरचना को संशोधित करना असंभव है, जबकि इसका उपयोग कहीं भी किया जाता है।

ओरेकल डीबीए से जो कुछ मैंने सीखा, उनमें से एक यह था कि जब भी संभव हो, अस्थायी तालिकाओं के उपयोग से बचें। यहां तक ​​कि SQL सर्वर पर प्रदर्शन ऐसे संशोधनों से लाभान्वित होता है।

यूनियनों द्वारा अलग-अलग आवेषण बदलें

सबसे सरल मामले में, उपरोक्त को कुछ में परिवर्तित किया जा सकता है

select case when ... then ... end, ... from table_a where ...
union
select case when ... then ... end, ... from table_b where ...
Order by ...;

कार्यों का उपयोग

स्केलर फ़ंक्शंस और टेबल वैल्यू फ़ंक्शंस दोनों ही आपकी प्रक्रिया को उपरोक्त फ़ॉर्म की एक ही क्वेरी में बदलने में मदद कर सकते हैं।

सामान्य तालिका के भाव उर्फ ​​सबक्वेरी फैक्टरिंग

सबक्वेरी फैक्टरिंग लगभग सबसे अच्छा ओरेकल है जो अस्थायी तालिकाओं से बचने की पेशकश करता है। यह SQL सर्वर के Oracle के लिए माइग्रेशन का उपयोग फिर से आसान है। इसके लिए SQL Server 2005 और इसके बाद के संस्करण की आवश्यकता है।


ये संशोधन SQL सर्वर संस्करण में सुधार करते हैं और कई मामलों में माइग्रेशन को सीधे आगे बढ़ाते हैं। अन्य मामलों में वैश्विक अस्थायी तालिकाओं का सहारा लेना प्रवास को एक तय समय में करना संभव बनाता है, लेकिन यह कम संतोषजनक है।


ओरेकल में वैश्विक अस्थायी तालिकाओं के उपयोग से बचने के और तरीके हैं?


3
मैं कहूंगा कि इस तरह का कोड प्रक्रियात्मक सोच का आधार नहीं है। और ये एक # के साथ स्थानीय टेम्प टेबल हैं। मैं प्रबंधन कर रहा हूँ और मैं पैर तोड़ दूँगा अगर मैंने देखा कि उत्पादन में जा रहा है :-)
gbn

मैं पूरी तरह से सहमत हूँ
bernd_k

@ बीजीएन - मुहावरेदार पीएल / एसक्यूएल मुहावरेदार टी-एसक्यूएल की तुलना में थोड़ा अधिक प्रक्रियात्मक है। टी-एसक्यूएल में सेट ऑप्स में लगभग सभी चीजें करने के लिए टेंप टेबल संभव है। PL / SQL में समानांतर कर्सर ऑप्स हैं और प्रक्रियात्मक कोड को अनुकूलित करने के लिए बहुत अधिक कार्यक्षमता है।
कंसर्नडऑफटुनब्रिजवल्स

जवाबों:


3

ऐसा करने का एक तरीका ऑब्जेक्ट प्रकार होगा , इस मामले में यह प्रकार आपके लिए विनम्र होगा #t1। इसलिए इसे कहीं न कहीं परिभाषित करने की आवश्यकता है लेकिन इसे वैश्विक होने की आवश्यकता नहीं है, यह प्रति-योजना या प्रति-प्रक्रिया भी हो सकती है। सबसे पहले, हम एक प्रकार बना सकते हैं:

SQL> create or replace type t1_type as object (x int, y int, z int)
  2  /

Type created.

SQL> create or replace type t1 as table of t1_type
  2  /

Type created.

अब कुछ नमूना डेटा सेट करें:

SQL> create table xy (x int, y int)
  2  /

Table created.

SQL> insert into xy values (1, 2)
  2  /

1 row created.

SQL> insert into xy values (3, 4)
  2  /

1 row created.

SQL> commit
  2  /

Commit complete.

और हमारे "अस्थायी" प्रकार को लौटाने वाले इस डेटा पर एक फ़ंक्शन बनाएं:

SQL> create or replace function fn_t1 return t1 as
  2  v_t1 t1 := t1();       -- empty temporary table (really an array)
  3  v_ix number default 0; -- array index
  4  begin
  5  for r in (select * from xy) loop
  6  v_ix := v_ix + 1;
  7  v_t1.extend;
  8  v_t1(v_ix) := t1_type(r.x, r.y, (r.x + r.y));
  9  end loop;
 10  return v_t1;
 11  end;
 12  /

Function created.

और अंत में:

SQL> select * from the (select cast (fn_t1 as t1) from dual)
  2  /

         X          Y          Z
---------- ---------- ----------
         1          2          3
         3          4          7

जैसा कि आप देख सकते हैं कि यह बहुत क्लिंकी है (और संग्रह छद्म-कार्यों का उपयोग करता है , जो कि सबसे अच्छे समय में एक अस्पष्ट विशेषता है!), जैसा कि मैं हमेशा कहता हूं, DB से DB तक पोर्ट करना केवल उनकी SQL बोलियों में वाक्य रचना और कीवर्ड के बारे में नहीं है! वास्तविक कठिनाई विभिन्न अंतर्निहित मान्यताओं में आती है (एसक्यूएल सर्वर के मामले में, कि कर्सर महंगे हैं और उनके उपयोग से बचा गया है / हर कीमत पर काम किया गया है)।


3

यदि मामला विकल्प पर्याप्त लचीला नहीं है, तो आप अपनी प्रक्रिया में डेटा एकत्र कर सकते हैं और सरणी (एस) में हेरफेर कर सकते हैं।

--Setup
CREATE TABLE table_a (c1 Number(2));
CREATE TABLE table_b (c1 Number(2));
INSERT INTO table_a (SELECT rownum FROM dual CONNECT BY rownum<=4);
INSERT INTO table_b (SELECT rownum+5 FROM dual CONNECT BY rownum<=4);

--Example
DECLARE
   Type tNumberArray Is Table Of Number;
   v1 tNumberArray;
BEGIN
   SELECT c1 BULK COLLECT INTO v1 FROM (
      SELECT c1 FROM table_a
      UNION ALL
      SELECT c1 FROM table_b
      );

   For x IN v1.First..v1.Last Loop
      /* Complex manipulation goes here. */
      If (v1(x) <= 3) Then
         v1(x) := v1(x)*10;
      End If;
      DBMS_OUTPUT.PUT_LINE(v1(x));
   End Loop;
END;
/

+1, लेकिन यह एक परिणाम सेट नहीं लौटाता है (यदि SELECTटी-एसक्यूएल संग्रहित खरीद में अंतिम चीज़ है, तो यह वही है जो लौटाता है)
गयुस

यदि यह कोड ब्लॉक एक ऐसी प्रक्रिया में बदल गया है, तो आप सरणी को वापस कर सकते हैं या कर्सर के रूप में सरणियों को खोल सकते हैं और कर्सर को वापस कर सकते हैं, या इसे एक फ़ंक्शन भी बना सकते हैं और पंक्तियों को वापस कर सकते हैं। इनमें से प्रत्येक समान होगा, लेकिन जो आपको उपयोग करना चाहिए वह स्थिति पर निर्भर करेगा।
लेह रिफ़ेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.