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.

War es hilfreich?

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(...)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top