2016-08-01 5 views
0

Я пытаюсь вставить большой файл xml длиной 43000 в clob.Как вставить большие данные в таблицу с помощью переменной привязки

asktom remcomanded с использованием переменных связывания, но его связи были сломаны.

так что мой вопрос, как вставить большой файл xml в переменную связывания. это моя процедура

CREATE OR REPLACE PROCEDURE sp_insert_xml 
(
p_id IN INT, 
p_xml IN clob 
) 
AS 

BEGIN 
declare x clob; 
y number(10); 

begin 
SELECT FILE into x from PROCESS_D where PROCESS_ID =1; 

select dbms_lob.getlength(x) into y from dual; 

DBMS_OUTPUT.PUT_LINE(y); 
end; 

--INSERT INTO TEST_ID VALUES (p_id, p_xml); 
END; 

Я хочу, чтобы разделить длину, так что я могу вставить их в таблицу

+0

Где находится документ XML? Если у вас есть только строка (так что не можете загрузить ее непосредственно из файла в базу данных), с какого клиента вы планируете вызывать свою процедуру? –

+0

@AlexPoole мой документ создается из приложения и вставлен в таблицу, я хочу сделать этот «документ» в качестве запроса в блочном выражении и разбить его, чтобы я мог вставить его в другую базу данных. – Moudiz

+0

Не уверен, что я следую. Ваш код помещает 'process_d.file' в CLOB; что XML-документ? Тогда что такое 'p_xml'? Если у вас уже есть CLOB в качестве переменной, я не уверен, в чем проблема. Вы пытаетесь разбить один из CLOB на 32 тыс. Кусков, чтобы сохранить его как varchar2? Или вы пытаетесь [конструировать CLOB из более коротких строковых литералов] (http://stackoverflow.com/a/17359646/266304) перед вызовом вашей процедуры? –

ответ

1

Я не знаю, почему вы хотите, чтобы разделить CLOB вверх в 4К куски для хранения, так как ваше значение уже счастливо сохраняются как CLOB ... но если вы действительно хотите, вы можете использовать иерархическую запрос:

create or replace procedure sp_insert_xml (p_id in int) as 
    l_xml clob; 
    l_len pls_integer; 
    l_chunksize pls_integer := 4000; 
begin 
    select xml into l_xml from process_d where process_id = p_id; 

    l_len := dbms_lob.getlength(l_xml); 
    dbms_output.put_line(l_len); 

    insert into test_id (id, chunk_id, chunk_text) 
    select p_id, level, dbms_lob.substr(l_xml, l_chunksize, (l_chunksize * (level - 1)) + 1) 
    from dual connect by level <= ceil(l_len/l_chunksize); 
end; 
/

или вы могли бы использовать рекурсивные подзапросы факторинг, или цикл PL/SQL:

for l_chunk_id in 0..floor(l_len/l_chunksize) loop 
    insert into test_id (id, chunk_id, chunk_text) 
    values (p_id, l_chunk_id, 
     dbms_lob.substr(l_xml, l_chunksize, (l_chunksize * l_chunk_id) + 1)); 
    end loop; 

но с рекурсивным CTE или подключением вам действительно не нужна процедура, вы можете сделать это в простом SQL.

1
Try to use sqlldr insted of sqlplus. You don't need to chunk lob into smaller pcises 

1. Save your clobs into files(test.xml,test2.xml) 

2. On destination DB create destination table 

    create table clob_table(name varchar2(100), doc clob); 

3. create control file for sqlldr. 



    LOAD DATA 
    INFILE * 
    append 
     INTO TABLE clob_table 
     FIELDS TERMINATED BY ',' 
     (name char(100), 
     doc  LOBFILE(name) TERMINATED BY EOF 
     ) 
    BEGINDATA 
    test.xml 
    test2.xml 


5. execute sqlldr `sqlldr user/[email protected]_db control=load.ctl` 
+0

Вопрос, похоже, заключается в разделении существующего CLOB на более мелкие куски, а не на загрузку из файла. Что кажется странным, и вопрос не совсем ясен; но из комментариев значение не поступает из файла. –

+0

Во втором комментарии он сказал, что хочет вставить документ в другую базу данных. Для этого ему нужно раскалывать клобу в чукны. –

+0

Поскольку вы не можете использовать LOB по ссылке DB? Хорошо, я не понял этого. Я бы, вероятно, использовал datapump в этом случае, но все еще не совсем ясно, что действительно нужно. –

Смежные вопросы