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

मैं पीएल/एसक्यूएल में दो समान डेटाबेस-स्कीमा को कैसे मर्ज करूं?

जैसा कि मेरी टिप्पणी में मदद करने का वादा किया गया था, मैंने एक गतिशील कोड तैयार किया था जिसे आप डेटा प्राप्त करने का प्रयास कर सकते हैं merged स्रोत और लक्ष्य तालिकाओं के साथ। तर्क इस प्रकार है:

Step1:सभी टेबल नाम SOURCE . से प्राप्त करें स्कीमा। नीचे दी गई क्वेरी में आपको क्रमशः स्कीमा (स्वामी) नाम बदलने की आवश्यकता हो सकती है। परीक्षण के उद्देश्य से मैंने केवल 1 टेबल लिया था, इसलिए जब आप इसे चलाते हैं, तो टेबल नाम फ़िल्टरिंग क्लॉज हटा दें।

चरण 2:तालिका के लिए सीमित कॉलम नाम प्राप्त करें। इसका उपयोग ON . को तैयार करने के लिए किया जाता है क्लॉज जिसे बाद में MERGE . के लिए इस्तेमाल किया जाएगा बयान।

चरण 3:तालिका के लिए गैर-बाधित कॉलम नाम प्राप्त करें। इसका उपयोग UPDATE . में किया जाएगा MERGE . का उपयोग करते समय क्लॉज ।

चरण 4:insert तैयार करें सूची जब डेटा ON से मेल नहीं खाता MERGE . की शर्त बयान।

प्रत्येक चरण को समझने के लिए मेरी इनलाइन टिप्पणियाँ पढ़ें।

CREATE OR REPLACE PROCEDURE COPY_TABLE
AS
Type OBJ_NME is table of varchar2(100) index by pls_integer;

--To hold Table name
v_obj_nm OBJ_NME ;

--To hold Columns of table
v_col_nm OBJ_NME;

v_othr_col_nm OBJ_NME;
on_clause VARCHAR2(2000);
upd_clause VARCHAR2(4000);
cntr number:=0;
v_sql VARCHAR2(4000);

col_list1  VARCHAR2(4000);
col_list2  VARCHAR2(4000);
col_list3  VARCHAR2(4000);
col_list4  varchar2(4000);
col_list5  VARCHAR2(4000);
col_list6  VARCHAR2(4000);
col_list7  VARCHAR2(4000);
col_list8  varchar2(4000);

BEGIN

--Get Source table names
SELECT OBJECT_NAME
BULK COLLECT INTO v_obj_nm
FROM all_objects 
WHERE owner LIKE  'RU%' -- Replace `RU%` with your Source schema name here
AND object_type = 'TABLE'
and object_name ='TEST'; --remove this condition if you want this to run for all tables

FOR I IN 1..v_obj_nm.count
loop
--Columns with Constraints 
  SELECT column_name
  bulk collect into v_col_nm 
  FROM user_cons_columns
  WHERE table_name = v_obj_nm(i);  

--Columns without Constraints remain columns of table
SELECT *
BULK COLLECT INTO v_othr_col_nm
from (
      SELECT column_name 
      FROM user_tab_cols
      WHERE table_name = v_obj_nm(i)
      MINUS
      SELECT column_name  
      FROM user_cons_columns
      WHERE table_name = v_obj_nm(i));

--Prepare Update Clause  
 FOR l IN 1..v_othr_col_nm.count
  loop
   cntr:=cntr+1;
   upd_clause := 't1.'||v_othr_col_nm(l)||' = t2.' ||v_othr_col_nm(l);    
   upd_clause:=upd_clause ||' and ' ;

   col_list1:= 't1.'||v_othr_col_nm(l) ||',';
   col_list2:= col_list2||col_list1;   

   col_list5:= 't2.'||v_othr_col_nm(l) ||',';
   col_list6:= col_list6||col_list5;

   IF (cntr = v_othr_col_nm.count)
   THEN 
    --dbms_output.put_line('YES');
     upd_clause:=rtrim(upd_clause,' and');
     col_list2:=rtrim( col_list2,',');
     col_list6:=rtrim( col_list6,',');
   END IF;
     dbms_output.put_line(col_list2||col_list6); 
   --dbms_output.put_line(upd_clause);
   End loop;
  --Update caluse ends     

   cntr:=0; --Counter reset  

 --Prepare ON clause  
  FOR k IN 1..v_col_nm.count
  loop
   cntr:=cntr+1;
   --dbms_output.put_line(v_col_nm.count || cntr);
   on_clause := 't1.'||v_col_nm(k)||' = t2.' ||v_col_nm(k);    
   on_clause:=on_clause ||' and ' ;

   col_list3:= 't1.'||v_col_nm(k) ||',';
   col_list4:= col_list4||col_list3;    

   col_list7:= 't2.'||v_col_nm(k) ||',';
   col_list8:= col_list8||col_list7;    

   IF (cntr = v_col_nm.count)
   THEN 
    --dbms_output.put_line('YES');
    on_clause:=rtrim(on_clause,' and');
    col_list4:=rtrim( col_list4,',');
    col_list8:=rtrim( col_list8,',');
   end if;

   dbms_output.put_line(col_list4||col_list8);
 -- ON clause ends

 --Prepare merge Statement

    v_sql:= 'MERGE INTO '|| v_obj_nm(i)||' t1--put target schema name before v_obj_nm
              USING (SELECT * FROM '|| v_obj_nm(i)||') t2-- put source schema name befire v_obj_nm here 
              ON ('||on_clause||')
              WHEN MATCHED THEN
              UPDATE
              SET '||upd_clause ||              
              ' WHEN NOT MATCHED THEN
              INSERT  
              ('||col_list2||','
                ||col_list4||
              ')
              VALUES
              ('||col_list6||','
                ||col_list8||          
               ')';

      dbms_output.put_line(v_sql);   
      execute immediate v_sql;
  end loop;    
End loop;
END;
/

निष्पादन:

exec COPY_TABLE

आउटपुट:

anonymous block completed

पीएस:मैंने इसे 2 कॉलम वाली तालिका के साथ परीक्षण किया है जिसमें से मुझे अद्वितीय कुंजी बाधा थी। तालिका का डीडीएल नीचे जैसा है:

अंत में मेरी इच्छा है कि आप मेरे कोड को समझ सकें (आप एक नोब हैं) और यदि आपकी आवश्यकता के लिए उपरोक्त विफल रहता है तो कुछ इसी तरह लागू करें।

 CREATE TABLE TEST
       (    COL2 NUMBER, 
            COLUMN1 VARCHAR2(20 BYTE), 
            CONSTRAINT TEST_UK1 UNIQUE (COLUMN1)  
       ) ;


  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. ओरेकल संग्रहीत प्रक्रिया, रेफरी कर्सर बनाम सहयोगी सरणी लौटा रहा है

  3. Oracle में तालिका में बेस 64 एन्कोडेड img src विशेषता कैसे सम्मिलित करें और फिर इसे Oracle एपेक्स में पृष्ठ पर प्रदर्शित करें

  4. मैं Oracle में SQL निष्पादन योजना कैसे देख सकता हूँ?

  5. Oracle त्रुटि संदेश इनपुट मान पर्याप्त लंबा नहीं है