create table tclob(c clob);
Что будет выведено кодом из нижеследующих блоков с rollback и без:
declare cl1 clob; cl2 clob; cl3 clob; cl4 clob; begin cl1:='1'; insert into tclob values(cl1) returning c into cl2; cl3:=cl2; dbms_lob.append(cl3,'2'); select c into cl4 from tclob; -- rollback; dbms_output.put_line(cl1); dbms_output.put_line(cl2); dbms_output.put_line(cl3); dbms_output.put_line(cl4); end; /
declare cl1 clob; cl2 clob; cl3 clob; cl4 clob; begin cl1 := '1'; insert into tclob values (cl1) returning c into cl2; cl3 := cl2; dbms_lob.append(cl2, '2'); select c into cl4 from tclob; -- rollback; dbms_output.put_line(cl1); dbms_output.put_line(cl2); dbms_output.put_line(cl3); dbms_output.put_line(cl4); end; /
declare cl1 clob; cl2 clob; cl3 clob; cl4 clob; begin cl1 := '1'; insert into tclob values (cl1) returning c into cl2; cl3 := cl2; dbms_lob.append(cl2, '2'); dbms_lob.append(cl3, '3'); select c into cl4 from tclob; -- rollback; dbms_output.put_line(cl1); dbms_output.put_line(cl2); dbms_output.put_line(cl3); dbms_output.put_line(cl4); end; /
declare cl1 clob; cl2 clob; cl3 clob; cl4 clob; begin cl1 := '1'; insert into tclob values (cl1) returning c into cl2; cl3 := cl2; dbms_lob.append(cl2, '22'); dbms_lob.append(cl3, '3'); dbms_lob.append(cl2, '44'); select c into cl4 from tclob; -- rollback; dbms_output.put_line(cl1); dbms_output.put_line(cl2); dbms_output.put_line(cl3); dbms_output.put_line(cl4); end; /
Ясно, что этот баг платформозависим и что дело в особенностях работы с памятью. Ответ кроется в том, что у cl3 и cl2 не синхронизированы длины, т.е. Oracle "забывает" изменить длины всех остальных переменных, указывающих на этот clob, а т.к. каждая операция изменения cl2/cl3 фактически изменяет одно и то же, то "лишнее" перезаписывается.
Comments
Я бы уже не угадал :-)
Отправить комментарий