在PL / SQL中拆分和插入字符串

时间:2017-01-19 14:37:15

标签: sql oracle plsql oracle11g

我有一个名为LOG的表,其中有一个名为MESSAGE的列,它是VARCHAR2(4000)。 由于我正在计划迁移,并且新数据库中的列MESSAGEVARCHAR2(2000),因此我希望迭代所有MESSAGE行,其长度为> 2000并在2000个字符后对文本进行子串,并将2000个字符后面的文本的所有内容插入到新行中。 我还必须更新原始行以拥有2000个字符。

我该怎么做?自从我使用PL / SQL以来已经很长时间了,我真的很感谢你的帮助。

4 个答案:

答案 0 :(得分:1)

一种方法是:

select . . ., substr(l.message, 1, 2000) as message
from log l
union all
select . . ., substr(l.message, 2001, 2000) as message
from log l
where lenght(l.message) > 2000;

答案 1 :(得分:1)

也可以使用connect by轻松完成,因为它在此示例中演示了它应该在每第5个字符后分割:

select substr(test.test, (level-1)*5, 5)
from (select 'THIS IS A LONG MESSAGE ACTUALLY' test from dual) test
connect by substr(test.test, (level-1)*5, 5) IS NOT NULL

在这种情况下,你甚至不用担心它会自动分离这些值,无论它们是否长于2000.

select substr(l.message, (level-1)*2000, 2000) message
from log l
substr(l.message, (level-1)*2000, 2000) IS NOT NULL

这可能是你的最终选择。

答案 2 :(得分:0)

您可以使用PLSQL块解决问题,如下所示。请尝试实现内联提到的逻辑,并检查是否有效。

代码:

 declare
  ---getting each message of length 4000 characters
  cursor cur is 
  select message 
  from log;

   var number;                 
   var1 varchar2(2000);
   cntr number:=0;
begin
  --Loop for each message 
  for i in cur
   loop                
      --getting length of message
     var:= length(i.message);

       for len in 1..(var / 2000)
        loop
            --setting the offset to pick 2000 chracters
            if cntr = 0 then
             cntr := cntr +1;
            else 
              cntr := cntr + 2000;
            end if;  

            --selecting 2000 characters from message 
            var1:=substr(i.message,cntr,2000);

             ---inserting 2000 charcters to table
            insert into table_log(col1) 
            values(var1 );

             commit;
        end loop;

    end loop;

end;

演示:

SQL> create table log(message varchar2(4000));

SQL> select message from log ;

MESSAGE
--------------------------------------------------------------------------------
KHAGDKAGDHAGDKHAGD
ADSJHA:DAH:DHHAHDH
.
.
.
SQL> select length(message) from log ;

LENGTH(MESSAGE)
---------------
           3989

SQL> create  table table_log(col1 varchar2(2000));


SQL> select col1 from table_log ;

COL1
--------------------------------------------------------------------------------


SQL> /

PL/SQL procedure successfully completed.

 --- Two rows created to destination table with size approx 2000 characters each
SQL> select length(col1) from table_log ;

LENGTH(COL1)
------------
        2000
        1989

在Simple SQL中,您可以将其作为

insert into table_log(col1) 
select SUBSTR(l.MESSAGE, 1, 2000) AS MESSAGE
FROM LOG l
UNION ALL
select  SUBSTR(l.MESSAGE, 2001, 2000) AS MESSAGE
FROM LOG l
WHERE length(l.MESSAGE) > 2000;

答案 3 :(得分:0)

您可以在复制到新表时拆分行。为此,您应该使用INSERT ALL WHEN。对于条件计算结果为true的每个WHEN子句,数据库将执行相应的INTO子句列表。

create table src_test_table(long_msg varchar2(20));
create table dest_test_table(long_msg varchar2(10));

insert into src_test_table values(lpad('1',20,'1'));
insert into src_test_table values(lpad('2',20,'2'));
insert into src_test_table values(lpad('3',20,'3'));
insert into src_test_table values(lpad('4',10,'4'));
insert into src_test_table values(lpad('5',10,'5'));

insert all 
 when length(long_msg) <= 10 then 
    into dest_test_table values(long_msg)
 when length(long_msg) > 10 then 
    into dest_test_table values(substr(long_msg,1,10))   
 when length(long_msg) > 10 then 
    into dest_test_table values(substr(long_msg,11))   
select long_msg from  src_test_table;

结果;

select long_msg,length(long_msg) from dest_test_table;