web-dev-qa-db-fra.com

Comment exporter des données de champ clob dans Oracle SQL Developer?

Comment exporter des données de champs clob dans Oracle SQL Developer. Actuellement, les données de champ clob ne peuvent pas être exportées dans Oracle SQL Developer.

8
Prashobh Chandran

Si vous ne voulez pas (ou ne pouvez pas) exporter et importer vos données et que vous le voulez vraiment comme un ensemble d'instructions d'insertion, vous pouvez utiliser les outils de formatage intégrés de SQL Developer pour scinder automatiquement vos CLOB plusieurs morceaux suffisamment petits pour être valides en tant que littéraux de chaîne, puis spouler le résultat dans un fichier:

spool clob_export.sql
select /*insert*/ * from your_table;
spool off

Avec les versions plus récentes, vous pouvez utiliser la commande sqlformat pour contrôler le format de sortie sans avoir à modifier la requête; c'est équivalent:

set sqlformat insert
spool clob_export.sql
select * from your_table;
spool off

Les instructions insert générées ressemblent à quelque chose comme:

REM INSERTING into YOUR_TABLE
SET DEFINE OFF;
Insert into YOUR_TABLE (ID,CLOB_COLUMN) values (1,TO_CLOB('... up to 4k of characters with quotes escaped ...')
|| TO_CLOB('... up to 4k of characters with quotes escaped ...')
|| TO_CLOB('... up to 4k of characters with quotes escaped ...')
...
|| TO_CLOB('... up to 4k of characters with quotes escaped ...'));
7
Alex Poole

Le package EXP_IMP_LOB suivant peut exporter et importer des données de colonne de type CLOB, NCLOB, BLOB à l'aide de simples fichiers SQL (texte).

Comment utiliser:

tout d’abord, installez le paquet sur les schémas source et cible . Pour exporter, exécutez cette sélection.

select * from table( EXP_IMP_LOB.EXPORT('table_name','lob_column_name','condition') );

où Table_Name et LOB_Column_Name définissent la colonne de données et la condition facultative définit la ou les lignes. S'il n'y a pas de condition, toutes les données de la ligne seront exportées ligne par ligne.

Exemple:

select * from table( EXP_IMP_LOB.EXPORT('person','image','id=103' ) );

Résultat:

/******************************************************
    TABLE  :PERSON
    COLUMN :IMAGE
    ROW    :103
******************************************************/
BEGIN
    EXP_IMP_LOB.IMPORT_NEW;
    EXP_IMP_LOB.IMPORT_APPEND ( 'FFD8FFE000104A464....23232323232');
    EXP_IMP_LOB.IMPORT_APPEND ( '32323232323232323....798999AA2A3');
    .........
    EXP_IMP_LOB.IMPORT_APPEND ( 'B2316524267279AA9....51401FFFD9');
    EXP_IMP_LOB.IMPORT_UPDATE ( 'PERSON','IMAGE','103' ); 
    COMMIT;
END;
/   

Ainsi, l'exportation convertit les données binaires en chaînes hexa de 400 caractères de longueur et crée un script à partir de celles-ci .

NE PAS TRIER LE RÉSULTAT!

Pour importer, il vous suffit d'installer également le package sur le schéma cible et d'exécuter ce script ci-dessus dans le schéma cible . C'est tout.

...plus:

  • Le nom de la table source et cible, le nom de la colonne doit être identique!
  • La table (source et cible) doit avoir la clé primaire et être identique.
  • La fonction EXPORT peut détecter automatiquement la clé primaire. Théoriquement, il peut aussi gérer les clés composées ...
  • La taille d'une chaîne hexa est définie dans la variable globale G_LENGTH. 200 caractères signifie 400 caractères hexa.
  • Les procédures supplémentaires:
  • IMPORT_NEW: réinitialise les variables de package pour le préparer à accepter un nouveau LOB
  • IMPORT_APPEND: convertit la chaîne hexa en données binaires et l'ajoute à la variable de package
  • IMPORT_UPDATE: met à jour la table, ligne, colonne donnée avec la variable de package
  • DIRECT_SQL: exécute le SQL donné en utilisant la variable LOB globale en tant que paramètre. Exemple: EXP_IMP_LOB.DIRECT_SQL ('insérer dans ANY_TABLE (ID, IMAGE), valeurs (123,: 1)');

/*============================================================================================*/
create or replace package EXP_IMP_LOB is
/*============================================================================================*/

  type T_STRING_LIST is table of varchar2( 32000 );

    ---------------------------------------------------------------------------
    function  EXPORT ( I_TABLE_NAME  in varchar2
                     , I_COLUMN_NAME in varchar2
                     , I_WHERE       in varchar2 default null
                     ) return T_STRING_LIST pipelined;
    ---------------------------------------------------------------------------

    ---------------------------------------------------------------------------
    procedure IMPORT_NEW;
    ---------------------------------------------------------------------------

    ---------------------------------------------------------------------------
    procedure IMPORT_APPEND ( I_RAW         in varchar2);
    ---------------------------------------------------------------------------

    ---------------------------------------------------------------------------
    procedure DIRECT_SQL ( I_SQL  in varchar2 );
    ---------------------------------------------------------------------------

    ---------------------------------------------------------------------------
    procedure IMPORT_UPDATE ( I_TABLE_NAME  in varchar2
                            , I_COLUMN_NAME in varchar2
                            , I_PK          in varchar2
                            );
    ---------------------------------------------------------------------------

end;
/



/*============================================================================================*/
create or replace package body EXP_IMP_LOB is
/*============================================================================================*/


    G_TABLE_NAME    varchar(   40 );
    G_COLUMN_NAME   varchar(   40 );
    G_COLUMN_TYPE   varchar(   40 );
    G_PK_KEY        varchar( 4000 );
    G_PK_LST        varchar( 4000 );
    G_LENGTH        number := 200;
    G_BLOB          blob;
    G_CLOB          clob;

---------------------------------------------------------------------------
procedure GET_PK ( I_TABLE_NAME in varchar ) is
---------------------------------------------------------------------------
    L_SEP           varchar ( 40 ) := ',';
    L_DATA_TYPE     varchar2( 30 );
begin
    G_PK_KEY := '';
    G_PK_LST := '';
    for L_A_PK in ( select COLUMN_NAME
                      from USER_CONSTRAINTS UC
                         , USER_CONS_COLUMNS DBC
                     where UC.CONSTRAINT_TYPE  = 'P'
                       and DBC.CONSTRAINT_NAME = UC.CONSTRAINT_NAME
                       and DBC.TABLE_NAME      = I_TABLE_NAME 
                     order by position 
                  ) 
    loop
        if nvl( length( G_PK_KEY ), 0 ) + length( L_A_PK.COLUMN_NAME ) < 4000 then
            select DATA_TYPE into L_DATA_TYPE from user_tab_columns where table_name = G_TABLE_NAME and column_name = L_A_PK.COLUMN_NAME;
            if instr( L_DATA_TYPE, 'CHAR') > 0 then
                G_PK_KEY := G_PK_KEY||'''''''''||'||L_A_PK.COLUMN_NAME||'||''''''''||'''||L_SEP||'''||';
            elsif instr( L_DATA_TYPE, 'DATE') > 0 then
                G_PK_KEY := G_PK_KEY||'''TO_DATE(''''''||TO_CHAR('||L_A_PK.COLUMN_NAME||',''YYYY.MM.DD HH24:MI:SS'')||'''''',''''YYYY.MM.DD HH24:MI:SS'''')''||'''||L_SEP||'''||';
            else
                G_PK_KEY := G_PK_KEY||L_A_PK.COLUMN_NAME||'||'''||L_SEP||'''||';
            end if;
            G_PK_LST := G_PK_LST||L_A_PK.COLUMN_NAME||L_SEP;
        end if;
    end loop;
    G_PK_KEY := substr( G_PK_KEY, 1, length( G_PK_KEY ) - ( 6 + length( L_SEP ) ) );
    G_PK_LST := substr( G_PK_LST, 1, length( G_PK_LST ) - length(L_SEP));
end;

---------------------------------------------------------------------------
function EXPORT ( I_TABLE_NAME  in varchar2
                , I_COLUMN_NAME in varchar2
                , I_WHERE       in varchar2 default null
                ) return T_STRING_LIST pipelined is
---------------------------------------------------------------------------
    V_BLOB          blob;
    V_CLOB          clob;
    V_CUR_SQL       varchar( 32000 );
    V_LOB_SQL       varchar( 32000 );
    V_RAW           varchar( 32000 );
    V_START         number;
    V_PK            varchar(  4000 );
    V_REC_SET       sys_refcursor; 

begin
    G_TABLE_NAME  := upper( trim( I_TABLE_NAME  ) );
    G_COLUMN_NAME := upper( trim( I_COLUMN_NAME ) );
    GET_PK( G_TABLE_NAME );
    select DATA_TYPE into G_COLUMN_TYPE from user_tab_columns where table_name = G_TABLE_NAME and column_name = G_COLUMN_NAME;
    if G_COLUMN_TYPE not in ('CLOB','NCLOB','BLOB') then
        raise_application_error ( -20001, 'The type of column '||I_COLUMN_NAME||' is not CLOB, NCLOB or BLOB' );    
    end if;

    V_CUR_SQL := 'select '||G_PK_KEY||' from '||G_TABLE_NAME||' where '||nvl( I_WHERE, ' 1 = 1 ');
    open V_REC_SET for V_CUR_SQL;
    loop
        fetch V_REC_SET into V_PK;
        exit when V_REC_SET%notfound; 
        PIPE ROW( '/******************************************************' );
        PIPE ROW( '   TABLE  :'||G_TABLE_NAME                               );
        PIPE ROW( '   COLUMN :'||G_COLUMN_NAME                              );
        PIPE ROW( '   ROW    :'||V_PK                                       );
        PIPE ROW( '******************************************************/' );
        PIPE ROW( 'BEGIN'                                                   );
        PIPE ROW( '   EXP_IMP_LOB.IMPORT_NEW;'                              );
        V_LOB_SQL := 'select '||G_COLUMN_NAME||' from '||G_TABLE_NAME||' where ('||G_PK_LST||') in ( select '||V_PK||' from dual )';

        if G_COLUMN_TYPE = 'BLOB' then
            execute immediate V_LOB_SQL into V_BLOB;
            if nvl( dbms_lob.getlength( V_BLOB ), 0 ) > 0 then
                V_START := 1;
                for L_I IN 1..ceil( dbms_lob.getlength( V_BLOB ) / G_LENGTH )
                loop
                    V_RAW   := dbms_lob.substr( V_BLOB, G_LENGTH, V_START );
                    PIPE ROW( '   EXP_IMP_LOB.IMPORT_APPEND ( '''||V_RAW||''');'         );
                    V_START := V_START + G_LENGTH;
                end loop;
                PIPE ROW( '   EXP_IMP_LOB.IMPORT_UPDATE ( '''||G_TABLE_NAME||''','''||G_COLUMN_NAME||''','''||replace(V_PK,'''','''''')||''' ); ');
                PIPE ROW( '   COMMIT;'                                              );
            end if;
        else
            execute immediate V_LOB_SQL into V_CLOB;
            if nvl( dbms_lob.getlength( V_CLOB ), 0 ) > 0 then
                V_START := 1;
                for L_I IN 1..ceil( dbms_lob.getlength( V_CLOB ) / G_LENGTH )
                loop
                    V_RAW   := UTL_RAW.CAST_TO_RAW( dbms_lob.substr( V_CLOB, G_LENGTH, V_START ) );
                    PIPE ROW( '   EXP_IMP_LOB.IMPORT_APPEND ( '''||V_RAW||''');'         );
                    V_START := V_START + G_LENGTH;
                end loop;
                PIPE ROW( '   EXP_IMP_LOB.IMPORT_UPDATE ( '''||G_TABLE_NAME||''','''||G_COLUMN_NAME||''','''||replace(V_PK,'''','''''')||''' ); ');
                PIPE ROW( '   COMMIT;'                                              );
            end if;
        end if;
        PIPE ROW( 'END;'                                                    );   
        PIPE ROW( '/'                                                       );
        PIPE ROW( ' '                                                       );
    end loop;
    close V_REC_SET;

    return;

end;

---------------------------------------------------------------------------
procedure IMPORT_NEW is
---------------------------------------------------------------------------
begin
    G_BLOB := null;
    G_CLOB := null;
end;

---------------------------------------------------------------------------
procedure IMPORT_APPEND ( I_RAW         in varchar2 ) is
---------------------------------------------------------------------------
    V_BLOB          blob;
begin
    V_BLOB := hextoraw( I_RAW );
    if nvl( dbms_lob.getlength( V_BLOB ), 0 ) > 0 then
        if nvl( dbms_lob.getlength( G_BLOB ), 0 ) = 0 then 
            G_BLOB := V_BLOB;
        else
            DBMS_LOB.APPEND( G_BLOB, V_BLOB );
        end if;
    end if;       
end;

---------------------------------------------------------------------------
procedure DIRECT_SQL ( I_SQL  in varchar2 ) is
---------------------------------------------------------------------------
begin
    if nvl( dbms_lob.getlength( G_BLOB ), 0 ) > 0 then
        execute immediate I_SQL using G_BLOB;
    else
        execute immediate I_SQL using G_CLOB;
    end if;
    commit;
end;

-- I downloaded this from the Net:
function clobfromblob( p_blob blob ) return clob is
    l_clob         clob;
    l_dest_offsset integer := 1;
    l_src_offsset  integer := 1;
    l_lang_context integer := dbms_lob.default_lang_ctx;
    l_warning      integer;
begin
    if p_blob is null then
        return null;
    end if;
    dbms_lob.createTemporary(lob_loc => l_clob
                            ,cache   => false);
    dbms_lob.converttoclob(dest_lob     => l_clob
                          ,src_blob     => p_blob
                          ,amount       => dbms_lob.lobmaxsize
                          ,dest_offset  => l_dest_offsset
                          ,src_offset   => l_src_offsset
                          ,blob_csid    => dbms_lob.default_csid
                          ,lang_context => l_lang_context
                          ,warning      => l_warning);
    return l_clob;
end;


---------------------------------------------------------------------------
procedure IMPORT_UPDATE ( I_TABLE_NAME  in varchar2
                        , I_COLUMN_NAME in varchar2
                        , I_PK          in varchar2
                        ) is
---------------------------------------------------------------------------
    V_SQL           varchar( 32000 );
begin
    G_TABLE_NAME  := upper( trim( I_TABLE_NAME  ) );
    G_COLUMN_NAME := upper( trim( I_COLUMN_NAME ) );
    GET_PK( G_TABLE_NAME );
    select DATA_TYPE into G_COLUMN_TYPE from user_tab_columns where table_name = G_TABLE_NAME and column_name = G_COLUMN_NAME;
    V_SQL := 'update '||I_TABLE_NAME||' set '||I_COLUMN_NAME||' = :1 where ('||G_PK_LST||') in ( select '||I_PK||' from dual )';
    if G_COLUMN_TYPE in ( 'CLOB', 'NCLOB' ) then
        G_CLOB := clobfromblob ( G_BLOB );
        G_BLOB := null;
        DIRECT_SQL( V_SQL );
    elsif G_COLUMN_TYPE in ( 'BLOB' ) then
        DIRECT_SQL( V_SQL );
    end if;
end;


end;
/
1
Ferenc Tóth

J'ai été confronté à ce problème lorsque j'ai essayé de copier une table contenant une colonne CLOB d'un serveur de base de données à un autre. L'outil "Outils> Copier la base de données" d'Oracle SQL Developer n'était pas un bon choix pour moi, car j'avais besoin d'un autre nom pour la table de destination. Je devais donc utiliser "Outils> Exporter la base de données", qui génère les instructions fichier .sql si vous le souhaitez.

Les étapes que j'ai faites:

  1. Exécutez ceci dans la base de données source:

    SELECT 
    someColumA,
    someColumB,
    SubStr(myClobColumn, 1, 4000)    myClobColumn_part1, 
    SubStr(myClobColumn, 4001, 8000) myClobColumn_part2, 
    . . .
    SubStr(Clob_field, .., ..) Clob_field_partN, 
    OtherColumns
    FROM YourTable ;
    
  2. Faites un clic droit et exportez dans un fichier, toutes les instructions insérées seront écrites dans une table temporaire: EXPORT_TABLE.

  3. Exécutez ce fichier sur le serveur de base de données de destination pour créer EXPORT_TABLE.

  4. Maintenant, lancez ceci pour importer les 4000 premiers caractères:

    Insert Into YourDestinationTable(.., myClobColumn, ..)
    SELECT .., myClobColumn_part1, ..
    FROM EXPORT_TABLE ;
    
  5. Exécutez ceci pour ajouter le reste des parties de Clob:

    Update YourDestinationTable A
       set myClobColumn = myClobColumn 
            || (Select myClobColumn_part2 
                From EXPORT_TABLE B
                Where B.tableKey = A.tableKey 
                  and myClobColumn_part2 is not null)
    ;
    
    
    Update YourDestinationTable A
       set myClobColumn = myClobColumn 
            || (Select myClobColumn_part3 
                From EXPORT_TABLE B
                Where B.tableKey = A.tableKey 
                  and myClobColumn_part3 is not null)
    ;
    ... 
    

jusqu'à la partie N.

Vous avez terminé.

0
W. Elbashier

J'ai le même problème lorsque j'essaie d'exporter une insertion, des champs qui sont clob ou blob, alors il n'est pas inclus dans la requête d'insertion.

Ceci est un problème en raison de l'insertion d'une limite qui n'est pas disponible pour la taille du type de données clob.

Solution:

J'exporte des données au format XML ou PDF, ou au chargeur ou au format Json. Ensuite, j'ai eu des données qui sont clob ou blob.

Outils> Exportation de base de données> sélectionnez une connexion> décochez Export DDl si vous souhaitez uniquement les données> Vérifier les données d'exportation> Sélectionnez le format: XML> suivant> suivant> suivant> suivant> suivant.

ouvrir le fichier où vous enregistrez ce fichier XML et le vérifier.

prendre plaisir...

0
ankit