2009-10-28 15 views
3

Merci d'avance pour vos experts.Copie de métadonnées via un lien de base de données dans Oracle 10g

Je veux être en mesure de copier sur des objets de base de données à partir de la base de données A dans la base de données B avec une procédure créée sur la base de données B.

J'ai créé un lien de base de données entre les deux et ont peaufiné la fonction get_ddl du DBMS_METADATA à ressembler à ceci:

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 [email protected] 
     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; 

afin de supprimer le préfixe de schéma qui vient généralement avec les métadonnées. Je reçois une valeur nulle chaque fois que j'exécute cette fonction via le lien de base de données avec les requêtes suivantes.

Sélectionnez getddl ('TABLE', 'TABLE1') à partir de user_tables @ ENTORA où table_name = 'TABLE1'; Sélectionnez getddl ('TABLE', 'TABLE1') à partir de dual @ ENTORA;

t_string est varchar2 (30) t_longstring est varchar2 (32767) et le type t_ArrayLongString est table des t_longstring

J'apprécierais vraiment si quelqu'un pouvait aider. Merci beaucoup.

Répondre

2
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; 
/

S'il vous plaît noter que la signature dans le schéma doit avoir le SELECT_CATALOG_ROLE pour exécuter cette fonction.

Un exemple est

select demo_fn @ db_link ('table', 'TABLE_NAME') du double;

+0

Oui, je pensais que la solution finale devrait être quelque chose comme ça ... –

-1

J'espère obtenir le droit de syntaxe, mais je pense qu'il devrait être v_clob := [email protected]_ddl(...) au lieu de v_clob := dbms_metadata.get_ddl(...)

+0

Merci AmmoQ mais Nope, il a donné une erreur [email protected]_ddl (...); a donné une erreur ORA-04054: le lien de base de données ENTORA.GET_DD n'existe pas et [email protected] (...); a donné cette erreur: ORA-06553: Les arguments lob PLS -564 ne sont pas autorisés dans les appels au serveur distant. Les deux n'ont pas compilé dans la fonction, je les ai courus contre la table double. – Tunde

+0

[email protected] est la bonne syntaxe, mais ... eh bien, ce n'est pas si simple, évidemment. –

+0

Oui, je suppose. J'ai été capable de contourner ce problème en modifiant un peu le DBMS_METADATA.GET_DDL. Le principal inconvénient est qu'Oracle 10g ne prend pas en charge le transfert de types de données CLOB entre les liaisons de base de données. Je ne suis pas sûr qu'il a été ammended dans 11g ... Voici un nouveau dbms_metadata.get_ddl que j'ai créé. Il supprime également les noms de schéma et les guillemets doubles. Et oui, votre syntaxe fonctionne. La fonction que j'ai utilisée peut être vue ci-dessous. Merci pour votre aide. – Tunde

1

Ce beau travail, petit bug fixe:

declare 
    v_ddl clob; 
    V_DDL_PART varchar2(4000); 
begin 
    for I in 0 .. 10 loop 
     select [email protected](
      [email protected]('TABLE','NAME','SCHEMA'), 
      4000,(4000 * I + 1)) into V_DDL_PART from [email protected]; 
     V_DDL := V_DDL || V_DDL_PART; 
    end loop; 
    dbms_output.put_line(v_ddl); 
end;