Popola tabella target da una tabella sorgente
Occorre popolare alcune tabelle dall'ambiente di produzione (sorgente) a quello di test (target).
In ambiente di test creiamo un db link tra i due scema che hanno le stesse tabelle.
In ambiente di test abbiamo creato l'utente " testimp" e creato il database link "dbltest" verso l'utente prodimp di produzione.
In ambiente di produzione abbiamo creato l'utente "prodimp" e due tabelle A e A1. Le stesse sono state poi create poi in ambiente di test.
1) La procedura seguente popola la tabella di target scritta nel codice e utilizza un cursore per leggere le righe della tabella sorgente e utilizza una variabile per impostare il numero di righe da leggere prima di effettuare la commit;
CREATE OR REPLACE procedure testimp.Popolatabella1 IS
v_error_code NUMBER;
v_error_msg VARCHAR2(512);
n_read number;
tot_row number;
BEGIN
n_read := 0;
tot_row := 0;
select count(*) into tot_row from prodimp.A@dbltest;
dbms_output.put_line ('la tabella contiene '||tot_row|| ' righe');
execute immediate ('truncate table testimp.A');
FOR rec IN ( SELECT pr.rowid , pr.* FROM prodimp.A@dbltest pr )
LOOP
n_read:= n_read+1;
INSERT INTO testimp.A (select * from prodimp.A@dbltest pr where rowid=rec.rowid);
if n_read = 1000
then begin commit;
dbms_output.put_line ('sono state committate '||n_read|| ' righe intermedie');
n_read:= 0;
end;
end if;
END LOOP;
dbms_output.put_line ('sono state inserite '||n_read|| 'alla fine de loop');
commit;
EXCEPTION
WHEN OTHERS THEN BEGIN
v_error_code := SQLCODE;
v_error_msg := SQLERRM;
raise_application_error(-20001,'import_-ERRORE - '||SQLCODE||' -ERROR- '||SQLERRM);
END;
END Popolatabella1;
/
2) La seguente procedura usa SQL DINAMICO ed è parametrizzata.
La prima Procedura effettua prima la truncate della tabella target (di test) e la popola prendendo i dati dalla tabella sorgente (produzione). Il nome della tabella è passato come parametro.
CREATE OR REPLACE procedure testimp.Popolatabella2 (nometab varchar2 )is
sql_stmt VARCHAR2(1000);
v_nometab varchar2(20);
v_error_code NUMBER;
v_error_msg VARCHAR2(512);
begin
v_nometab := upper (nometab);
DBMS_OUTPUT.PUT_LINE ('il nome ='|| v_nometab);
execute immediate ('truncate table testimp.'||v_nometab);
sql_stmt:= (
'insert into testimp.'||v_nometab ||
'(SELECT pr.* FROM prodimp.'||v_nometab||'@dbltest pr)'
);
execute immediate sql_stmt;
commit;
EXCEPTION
WHEN OTHERS THEN BEGIN
v_error_code := SQLCODE;
v_error_msg := SQLERRM;
raise_application_error(-20001,'import_-ERRORE - '||SQLCODE||' -ERROR- '||SQLERRM);
END;
end Popolatabella2;
/
2) La seconda procedura prende in ingresso una lista di tabelle e tramite un cursore richiama per ogni tabella la procedura “Popolatabella2”.
Tabella da popolare prima di lanciare la procedura
select * from testimp.list_table;
NAME_TAB
-----------------
A1
A
CREATE OR REPLACE procedure testimp.Popolalistatabella is
v_error_code NUMBER;
v_error_msg VARCHAR2(512);
CURSOR cur1 IS select * from testimp.list_table;
begin
for rec in cur1
loop
testimp.Popolatabella2(rec.name_tab);
end loop;
EXCEPTION
WHEN OTHERS THEN BEGIN
v_error_code := SQLCODE;
v_error_msg := SQLERRM;
IF cur1%ISOPEN THEN CLOSE cur1;
END IF;
raise_application_error(-20001,'mdr4_import_soggetto_from_geu-ERRORE - '||SQLCODE||' -ERROR- '||SQLERRM);
END;
end Popolalistatabella;
/
In conclusione occorre popolare la tabella "testimp.list_table" e lanciare solo la seconda procedura.
SQL>begin
testimp.Popolalistatabella;
end;
/
In ambiente di test creiamo un db link tra i due scema che hanno le stesse tabelle.
In ambiente di test abbiamo creato l'utente " testimp" e creato il database link "dbltest" verso l'utente prodimp di produzione.
OWNER | DB_LINK | USERNAME | HOST |
TESTIMP | DBLTEST.WORLD | PRODIMP | PROD01 |
In ambiente di produzione abbiamo creato l'utente "prodimp" e due tabelle A e A1. Le stesse sono state poi create poi in ambiente di test.
1) La procedura seguente popola la tabella di target scritta nel codice e utilizza un cursore per leggere le righe della tabella sorgente e utilizza una variabile per impostare il numero di righe da leggere prima di effettuare la commit;
CREATE OR REPLACE procedure testimp.Popolatabella1 IS
v_error_code NUMBER;
v_error_msg VARCHAR2(512);
n_read number;
tot_row number;
BEGIN
n_read := 0;
tot_row := 0;
select count(*) into tot_row from prodimp.A@dbltest;
dbms_output.put_line ('la tabella contiene '||tot_row|| ' righe');
execute immediate ('truncate table testimp.A');
FOR rec IN ( SELECT pr.rowid , pr.* FROM prodimp.A@dbltest pr )
LOOP
n_read:= n_read+1;
INSERT INTO testimp.A (select * from prodimp.A@dbltest pr where rowid=rec.rowid);
if n_read = 1000
then begin commit;
dbms_output.put_line ('sono state committate '||n_read|| ' righe intermedie');
n_read:= 0;
end;
end if;
END LOOP;
dbms_output.put_line ('sono state inserite '||n_read|| 'alla fine de loop');
commit;
EXCEPTION
WHEN OTHERS THEN BEGIN
v_error_code := SQLCODE;
v_error_msg := SQLERRM;
raise_application_error(-20001,'import_-ERRORE - '||SQLCODE||' -ERROR- '||SQLERRM);
END;
END Popolatabella1;
/
2) La seguente procedura usa SQL DINAMICO ed è parametrizzata.
La prima Procedura effettua prima la truncate della tabella target (di test) e la popola prendendo i dati dalla tabella sorgente (produzione). Il nome della tabella è passato come parametro.
CREATE OR REPLACE procedure testimp.Popolatabella2 (nometab varchar2 )is
sql_stmt VARCHAR2(1000);
v_nometab varchar2(20);
v_error_code NUMBER;
v_error_msg VARCHAR2(512);
begin
v_nometab := upper (nometab);
DBMS_OUTPUT.PUT_LINE ('il nome ='|| v_nometab);
execute immediate ('truncate table testimp.'||v_nometab);
sql_stmt:= (
'insert into testimp.'||v_nometab ||
'(SELECT pr.* FROM prodimp.'||v_nometab||'@dbltest pr)'
);
execute immediate sql_stmt;
commit;
EXCEPTION
WHEN OTHERS THEN BEGIN
v_error_code := SQLCODE;
v_error_msg := SQLERRM;
raise_application_error(-20001,'import_-ERRORE - '||SQLCODE||' -ERROR- '||SQLERRM);
END;
end Popolatabella2;
/
2) La seconda procedura prende in ingresso una lista di tabelle e tramite un cursore richiama per ogni tabella la procedura “Popolatabella2”.
Tabella da popolare prima di lanciare la procedura
select * from testimp.list_table;
NAME_TAB
-----------------
A1
A
CREATE OR REPLACE procedure testimp.Popolalistatabella is
v_error_code NUMBER;
v_error_msg VARCHAR2(512);
CURSOR cur1 IS select * from testimp.list_table;
begin
for rec in cur1
loop
testimp.Popolatabella2(rec.name_tab);
end loop;
EXCEPTION
WHEN OTHERS THEN BEGIN
v_error_code := SQLCODE;
v_error_msg := SQLERRM;
IF cur1%ISOPEN THEN CLOSE cur1;
END IF;
raise_application_error(-20001,'mdr4_import_soggetto_from_geu-ERRORE - '||SQLCODE||' -ERROR- '||SQLERRM);
END;
end Popolalistatabella;
/
In conclusione occorre popolare la tabella "testimp.list_table" e lanciare solo la seconda procedura.
SQL>begin
testimp.Popolalistatabella;
end;
/