जैसा कि मेरी टिप्पणी में मदद करने का वादा किया गया था, मैंने एक गतिशील कोड तैयार किया था जिसे आप डेटा प्राप्त करने का प्रयास कर सकते हैं 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)
) ;