Kopieren von Metadaten über einen Datenbanklink in Oracle 10G
Frage
Vielen Dank im Voraus für Ihre Hilfe -Experten.
Ich möchte in der Lage sein, Datenbankobjekte aus der Datenbank A in die Datenbank B mit einem in der Datenbank B. erstellten Prozedur kopieren zu können
Ich habe einen Datenbank -Link zwischen den beiden erstellt und die Funktion get_ddl der dbms_metadata so gepoppt, dass sie so aussehen:
create or replace function GetDDL
(
p_name in MetaDataPkg.t_string
p_type in MetaDataPkg.t_string
)
return MetaDataPkg.t_longstring
is
-- clob
v_clob clob;
-- array of long strings
c_SYSPrefix constant char(4) := 'SYS_';
c_doublequote constant char(1) := '"';
v_longstrings metadatapkg.t_arraylongstring;
v_schema metadatapkg.t_string;
v_fullength pls_integer := 0;
v_offset pls_integer := 0;
v_length pls_integer := 0;
begin
SELECT DISTINCT OWNER
INTO v_schema
FROM all_objects@ENTORA
where object_name = upper(p_name);
-- get DDL
v_clob := dbms_metadata.get_ddl(p_type, upper(p_name), upper(v_schema));
-- get CLOB length
v_fullength := dbms_lob.GetLength(v_clob);
for nIndex in 1..ceil(v_fullength / 32767)
loop
v_offset := v_length + 1;
v_length := least(v_fullength - (nIndex - 1) * 32767, 32767);
dbms_lob.read(v_clob, v_length, v_offset, v_longstrings(nIndex));
-- Remove table’s owner from DDL string:
v_longstrings(nIndex) := replace(
v_longstrings(nIndex),
c_doublequote || user || c_doublequote || '.',
''
);
-- Remove the following from DDL string:
-- 1) "new line" characters (chr(10))
-- 2) leading and trailing spaces
v_longstrings(nIndex) :=
ltrim(rtrim(replace(v_longstrings(nIndex), chr(10), '')));
end loop;
-- close CLOB
if (dbms_lob.isOpen(v_clob) > 0)
then
dbms_lob.close(v_clob);
end if;
return v_longstrings(1);
end GetDDL;
Um das Schema -Präfix zu entfernen, das normalerweise mit Metadaten geliefert wird. Ich erhalte einen Nullwert, wenn ich diese Funktion mit den folgenden Abfragen über den Datenbanklink ausführe.
Wählen Sie getddl ('Tabelle', 'Tabelle1') von user_tables@entora wobei table_name = 'Tabelle1';
Wählen Sie getddl ('Tabelle', 'Tabelle1') von Dual@entora;
T_String ist varchar2 (30) t_longString ist varchar2 (32767) und type t_arraylongstring ist Tabelle von t_longstring
Ich würde es sehr schätzen, wenn jemand helfen könnte. Danke vielmals.
Lösung
CREATE OR REPLACE function DEMO_FN
(object_type varchar2, table_name varchar2) return varchar2
is
v_longstrings varchar2(32223);
c_doublequote constant char(1) := '"';
begin
v_longstrings := dbms_metadata.get_ddl(object_type,table_name);
-- Remove double quotes from DDL string:
v_longstrings := replace(v_longstrings, c_doublequote || user || c_doublequote || '.','');
-- Remove the following from DDL string:
-- 1) "new line" characters (chr(10))
-- 2) leading and trailing spaces
v_longstrings := ltrim(rtrim(replace(v_longstrings, chr(10), '')));
return v_longstrings;
end;
/
Bitte beachten Sie, dass das in Schema signierte Schema die Select_Catalog_Role haben muss, um diese Funktion auszuführen.
Ein Beispiel ist
Wählen Sie Demo_fn@db_link ('Tabelle', 'table_name') aus Dual;
Andere Tipps
Das funktioniert gut
declare
v_ddl clob;
V_DDL_PART varchar2(4000);
begin
for I in 0 .. 50 loop
select DBMS_LOB.SUBSTR@db_link(DBMS_METADATA.GET_DDL@db_link('TABLE','MYTABLE'),(4000 * I + 1)) into V_DDL_PART from dual@db_link;
V_DDL := V_DDL || V_DDL_PART;
end loop;
end;
Diese funktioniert gut, kleiner Fehler behoben:
declare
v_ddl clob;
V_DDL_PART varchar2(4000);
begin
for I in 0 .. 10 loop
select DBMS_LOB.SUBSTR@LINK(
DBMS_METADATA.GET_DDL@LINK('TABLE','NAME','SCHEMA'),
4000,(4000 * I + 1)) into V_DDL_PART from dual@LINK;
V_DDL := V_DDL || V_DDL_PART;
end loop;
dbms_output.put_line(v_ddl);
end;
Ich hoffe ich habe die Syntax richtig, aber ich denke, es sollte sein v_clob := dbms_metadata@ENTORA.get_ddl(...)
Anstatt von v_clob := dbms_metadata.get_ddl(...)