【问题标题】:How to export clob field datas in oracle sql developeroracle sql developer中如何导出clob字段数据
【发布时间】:2017-02-15 09:07:57
【问题描述】:

如何在 oracle sql developer 中导出 clob 字段数据。目前在oracle sql developer中无法导出clob字段数据。

【问题讨论】:

  • Possible duplicate? 你想做什么出口?
  • @AlexPoole 我想以 sql 格式导出 clob 数据。所以我可以在需要时重新插入相同的数据。
  • 您的意思是insert 语句的列表?正如链接的答案所问的那样,在这种情况下,插入语句会是什么样子,尤其是当 CLOB 值超过 4k 时?数据泵导出有什么问题?

标签: oracle export oracle-sqldeveloper clob


【解决方案1】:

如果您不想(或不能)export and import 您的数据,并且真的希望它作为一组插入语句,您可以使用 SQL Developer 的内置格式化工具自动将您的 CLOB 拆分为多个小到足以作为字符串文字有效的块,然后将结果假脱机到文件中:

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

对于更新的版本,您可以使用the sqlformat command 来控制输出格式,而无需修改查询;这是等价的:

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

生成的插入语句如下所示:

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 ...'));

【讨论】:

  • 对 SQL Developer 用户的重要信息:为了使这个工作,您不能单独执行这些行。您需要将它们作为脚本执行。
  • 我有一些语句错误地带有双勾号。我不得不手动清理这些。示例:TO_CLOB('' 应该是 TO_CLOB('
【解决方案2】:

下面的EXP_IMP_LOB包可以使用简单的SQL(文本)文件导出和导入CLOB、NCLOB、BLOB类型的列数据。

使用方法:

首先将软件包安装到源模式和目标模式上。 要导出运行此选择

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

其中 Table_Name 和 LOB_Column_Name 定义数据列,可选的 Condition 定义行。 如果没有条件,则将每行数据逐行导出。

示例:

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

结果:

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

因此,导出将二进制数据转换为 400 个字符长度的六进制字符串,并从中创建一个脚本。 我用 ..... 来表示许多字符,因为这只是上面的一个示例。

不要对结果进行排序!

要导入,您只需要将包也安装到目标架构上,然后在目标架构中运行上面的脚本。 就是这样。

...更多:

  • 源表名和目标表名、列名必须相同!
  • 表(源和目标)必须具有主键并且它们必须相同。
  • EXPORT 功能可以自动检测主键。理论上它也可以管理组合键...
  • 十六进制字符串的大小在 G_LENGTH 全局变量中定义。 200 个字符表示 400 个十六进制字符。
  • 附加程序:
  • IMPORT_NEW :重置包变量以准备接受新的 LOB
  • IMPORT_APPEND :将十六进制字符串转换为二进制数据并将其附加到包变量中
  • IMPORT_UPDATE : 使用包变量更新给定的表、行、列
  • DIRECT_SQL :使用全局 LOB 变量作为参数执行给定的 SQL。例如:EXP_IMP_LOB.DIRECT_SQL('插入 ANY_TABLE (ID, IMAGE) 值 (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;
/

【讨论】:

  • 我不明白...这是我的代码。你是什​​么意思? github.com/frankiechapson/Export-and-Import-LOB-values>
  • 好的。抱歉,我没有看到链接:-)。是的,我,Ferenc Toth = Frankie Chapson。
  • 那没关系
【解决方案3】:

我在尝试将具有 CLOB 列的表从一台数据库服务器复制到另一台时遇到了这个问题。 Oracle SQL Developer 的“工具 > 复制数据库”工具对我来说不是一个好选择,因为我需要为目标表指定另一个名称,所以我不得不使用“工具 > 导出数据库”为您生成插入语句.sql 文件,如果您选择的话。

我做的步骤:

  1. 在源数据库中运行:

    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. 右键导出到文件,所有插入语句都会写入临时表:EXPORT_TABLE。

  3. 在目标数据库服务器中运行该文件以创建 EXPORT_TABLE

  4. 现在,运行这个来导入前 4000 个字符:

    Insert Into YourDestinationTable(.., myClobColumn, ..)
    SELECT .., myClobColumn_part1, ..
    FROM EXPORT_TABLE ;
    
  5. 运行此命令以附加 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)
    ;
    ... 
    

直到第 N 部分。

你已经完成了。

【讨论】:

    【解决方案4】:

    当我尝试导出插入时遇到同样的问题,字段是 clob 或 blob,然后它不包含在插入查询中。

    这是由于插入限制不适用于 clob 数据类型大小的问题。

    解决方案:

    我以 XML 或 PDF 或加载程序或 Json 格式导出数据。然后我得到了 clob 或 blob 的数据。

    工具 > 数据库导出 > 选择连接 > 如果您只想要数据,请取消选中导出 DDl > 选中导出数据 > 选择格式:XML > 下一步 > 下一步 > 下一步 > 下一步 >完成。

    打开保存该 XML 文件的文件并进行验证。

    享受...

    【讨论】:

      【解决方案5】:

      以下代码可用于为 clob 数据创建更新脚本。

      DECLARE
         TYPE varchar2_t IS TABLE OF VARCHAR2 (32767)
            INDEX BY BINARY_INTEGER;
      
         read_str    VARCHAR2 (32000);
         V_records   varchar2_t;
      
         PROCEDURE Clob_to_records (p_clob IN CLOB, p_records OUT varchar2_t)
         IS
            v_record_separator        VARCHAR2 (2) := CHR (13) || CHR (10);
            v_last                    INTEGER;
            v_current                 INTEGER;
         BEGIN
            -- If the file has a DOS newline (cr+lf) - manually created - use above
            -- If the file does not have a DOS newline, use a Unix newline (lf)
            IF (NVL (DBMS_LOB.INSTR (p_clob,
                                     v_record_separator,
                                     1,
                                     1),
                     0) = 0)
            THEN
               v_record_separator := CHR (10);
            END IF;
      
            v_last := 1;
      
            LOOP
               v_current :=
                  DBMS_LOB.INSTR (p_clob,
                                  v_record_separator,
                                  v_last,
                                  1);
               EXIT WHEN (NVL (v_current, 0) = 0);
               p_records (p_records.COUNT + 1) :=
                  DBMS_LOB.SUBSTR (p_clob, v_current - v_last, v_last);
               v_last := v_current + LENGTHB (v_record_separator);
            END LOOP;
         EXCEPTION
            WHEN OTHERS
            THEN
               DBMS_OUTPUT.put_line ('Error ' || SQLERRM);
         END Clob_to_records;
      BEGIN
        -- DBMS_OUTPUT.put_line ('Processing Clob');
      
         FOR eachrec
            IN (SELECT a.clob_data
                  FROM table1 a
                 WHERE   COLUMN1=CONDITION1  )
         LOOP
            Clob_to_records (eachrec.data, v_records);
            DBMS_OUTPUT.put_line ('update table2 a set a.clob_data =');
            FOR i IN 1 .. v_records.COUNT
            LOOP
               read_str := v_records (i);
      
               IF i = 1
               THEN
                  DBMS_OUTPUT.put_line ('TO_CLOB(''' || read_str || ''')');
               ELSE
                  DBMS_OUTPUT.put_line ('||CHR(10)|| TO_CLOB(''' || read_str || ''')');
               END IF;
            END LOOP;
              DBMS_OUTPUT.put_line (' WHERE COLUMN1=CONDITION1;');
         END LOOP;
      END;
      

      【讨论】:

        猜你喜欢
        • 2015-10-16
        • 2011-02-02
        • 1970-01-01
        • 2010-11-28
        • 1970-01-01
        • 2023-01-27
        • 2011-07-25
        • 2013-07-31
        • 1970-01-01
        相关资源
        最近更新 更多