我有一个名为LOG
的表,其中有一个名为MESSAGE
的列,它是VARCHAR2(4000)
。
由于我正在计划迁移,并且新数据库中的列MESSAGE
为VARCHAR2(2000)
,因此我希望迭代所有MESSAGE
行,其长度为> 2000并在2000个字符后对文本进行子串,并将2000个字符后面的文本的所有内容插入到新行中。
我还必须更新原始行以拥有2000个字符。
我该怎么做?自从我使用PL / SQL以来已经很长时间了,我真的很感谢你的帮助。
答案 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;