Замена varchar2 на больший тип данных в Oracle SP

Я использую оракул версии 10. В PL/SQL есть хранимая процедура, использующая переменную varchar2. Код постоянно добавляет переменную varchar2. Когда размер переменной varchar2 превышает 32767, она не может добавить больше значения. Теперь я хочу изменить тип данных на длинный или clob (чтобы вместить больше символов), это не работает. Как изменить код здесь, чтобы иметь ту же функциональность добавления с помощью clob или long?

пример добавления x:= x || 'мои данные';


person user215005    schedule 27.06.2013    source источник
comment
long уже давно (без каламбура) объявлен устаревшим и имеет ограничения. Придерживайтесь clob.   -  person Alex Poole    schedule 28.06.2013
comment
@AlexPoole, я проверил, изменив тип данных на clob, это не сработало.   -  person user215005    schedule 28.06.2013
comment
Я просто имел в виду, что вы должны искать clob решения и вообще не должны рассматривать long. Я не имел в виду, что вы можете конкатенировать, как вы можете с varchar2. Вам может понадобиться dbms_lob.writeappend(), но я m в настоящее время не могу опубликовать больше, чем ответ только по ссылке ...   -  person Alex Poole    schedule 28.06.2013


Ответы (1)


Тип данных long устарел; если вы можете, вам следует серьезно подумать о миграции столбца long в clob.

Если бы вы работали с clob, вы могли бы добавить varchar2 за пределы 32k varchar2 следующим образом:

declare
  l_clob clob;
begin
  dbms_lob.createtemporary(l_clob, true);
  dbms_lob.open(l_clob, dbms_lob.lob_readwrite);
  dbms_lob.writeappend(l_clob, 4, '1234');
  for i in 1..10000 loop
    dbms_lob.writeappend(l_clob, 5, '.5678');
  end loop;
  dbms_output.put_line('CLOB length: ' || length(l_clob));
  dbms_lob.close(l_clob);
  dbms_lob.freetemporary(l_clob);    end;
/

CLOB length: 50004

Вы можете добавить к long оператор конкатенации ||, но, как вы уже видели, только до 32 КБ. Не существует простого способа обработки значений long выше, чем в PL/SQL. Возможно, вы сможете что-то сделать с dbms_sql, но на самом деле это не будет стоить усилий, если есть возможность переключить столбец таблицы на clob.


Если вы хотите передать clob обратно вызывающему, и это временный clob, он должен быть определен вызывающим абонентом и передан после его создания:

create or replace procedure proc1 as
  l_clob clob;
begin
  dbms_lob.createtemporary(l_clob, true);

  proc2(l_clob);
  dbms_output.put_line('proc1 CLOB length: ' || length(l_clob));

  dbms_lob.freetemporary(l_clob);
end;
/

create or replace procedure proc2(p_clob in out clob) as
begin
  dbms_lob.open(p_clob, dbms_lob.lob_readwrite);
  dbms_lob.writeappend(p_clob, 5, '12345');
  for i in 1..9999 loop
    dbms_lob.writeappend(p_clob, 5, '.56789');
  end loop;
  dbms_output.put_line('proc2 CLOB length: ' || length(p_clob));
  dbms_lob.close(p_clob);
end;
/

exec procs;

proc2 CLOB length: 50000
proc1 CLOB length: 50000

В противном случае объект не будет существовать для вызывающего объекта.

Если clob существует - выбрано, скажем, из таблицы, поэтому вам не нужен вызов createtemporary - тогда вы можете просто назначить его параметру out, но я не думаю, что это относится к тому, что вы описали.

person Alex Poole    schedule 28.06.2013
comment
Спасибо @Alex, очень полезно, я просто хочу знать, как вернуть значение из этого клоба. - person user215005; 28.06.2013
comment
@user215005 - вернуться куда и как? Вы пытаетесь вставить/обновить столбец long из процедуры или передать значение обратно клиенту, который выполнит вставку/обновление? - person Alex Poole; 28.06.2013
comment
Это SP, вызванный из другого SP с параметром out. Таким образом, значение clob var должно быть возвращено вызываемому SP - person user215005; 28.06.2013
comment
@user215005 user215005 - это выходной параметр clob или long, или даже varchar2? Для работы потребуется clob, с createtemporary и т. д. в вызывающей программе. Но должен ли он в какой-то момент стать long, что будет где-то между трудным и невозможным в PL/SQL, или теперь он тоже будет храниться как clob? Было бы полезно показать весь процесс в вашем вопросе с типами данных и тем, что такое клиент/язык на каждом этапе. Изменение столбца на clob — единственная жизнеспособная стратегия. - person Alex Poole; 28.06.2013
comment
Я согласен с вами, @Alex, параметр out в настоящее время длинный, я тоже меняю его. Просто хочу знать, как присвоить значение temp clob этому выходному параметру. - person user215005; 28.06.2013
comment
@ user215005 - Хорошо, это хорошо. Я обновил ответ примером того, как процедура вызывает другую, чтобы заполнить clob. Если вы хотите, чтобы оба процесса присоединялись к clob, вам также нужно будет открыть и закрыть его в самом внешнем процессе, а также создать/освободить его. - person Alex Poole; 28.06.2013
comment
Я не верю, что в PL/SQL есть, нет. Вы можете сделать это из внешней программы (Perl, Java, OCI), извлекая clob и вставляя как long, но механизм PL/SQL, похоже, не может (по крайней мере, если значение > 32k, что вот куда мы попали...) - person Alex Poole; 28.06.2013