Как обновить столбец clob с данными более 2 миллионов символов

Я пытаюсь обновить значение clob длиной > 2 миллиона символов в PL/SQL. я получаю сообщение об ошибке

Строковый литерал слишком длинный

Можно ли как-нибудь обойти эту ошибку?

Это фрагмент кода PL/SQL, с помощью которого я пытаюсь обновить значение clob:

 DECLARE 
   value clob; 
   clob_field clob;
   fromindex integer;
   offset integer;
   chunks integer;
   eclob clob;
   sql_stmt clob;
BEGIN 
   fromindex := 1;
   offset := 2;  
   clob_field := '<clob_value_with_length_2Million>';
   chunks := 1+(dbms_lob.Getlength(clob_field) / 2);
   value :='';
   
   FOR chunk IN 1 .. chunks LOOP 
     IF ( chunk != 1) THEN
       value := value || ' || ';
     END IF;
     value := value || 'to_clob('''||dbms_lob.Substr(clob_field, offset, fromindex)||''')';
     fromindex := fromindex + 2;
   END LOOP; 
   dbms_output.put_line(value); 
  sql_stmt := 'update mytable
  set sources = ' || value ||' where scenario_id = 1 and entry_index = 1';
  EXECUTE IMMEDIATE sql_stmt;
END; 

Я получаю сообщение об ошибке при инициализации clob_field, и это очевидно, поскольку PL/SQl не позволяет использовать более 32 тыс. символов. Итак, я обращаюсь сюда, чтобы узнать, могу ли я найти какое-либо решение моей проблемы.


person Mallikarjuna    schedule 04.02.2021    source источник
comment
Вы просто ищете такое решение: stackoverflow.com/a/64154242/409172   -  person Jon Heller    schedule 06.02.2021


Ответы (1)


Вы можете уменьшить объем необходимого кода и повысить его производительность, если используете переменные связывания. Если вы каждый раз пытаетесь создать новый оператор обновления, база данных должна будет разработать план выполнения для каждого отдельного запроса. Использование переменных связывания также устраняет необходимость выполнения какой-либо очистки SQL для защиты от SQL-инъекций.

Пример

SQL> CREATE TABLE mytable
  2  AS
  3      SELECT 1 AS scenario_id, 1 AS entry_index, EMPTY_CLOB () || 'clob1' AS sources FROM DUAL
  4      UNION ALL
  5      SELECT 2 AS scenario_id, 2 AS entry_index, EMPTY_CLOB () || 'clob2' AS sources FROM DUAL;

Table created.

SQL> SELECT * FROM mytable;

SCENARIO_ID ENTRY_INDEX SOURCES
----------- ----------- --------------------------------------------------------------------------------
          1           1 clob1
          2           2 clob2

SQL> DECLARE
  2      clob_field      CLOB;
  3      l_scenario_id   NUMBER;
  4      l_entry_index   NUMBER;
  5      sql_stmt        CLOB;
  6  BEGIN
  7      clob_field := '<clob_value_with_length_2Million>';
  8      l_scenario_id := 1;
  9      l_entry_index := 1;
 10
 11      sql_stmt :=
 12          'update mytable set sources = :bind_clob where scenario_id = :scenario and entry_index = :entry';
 13
 14      EXECUTE IMMEDIATE sql_stmt
 15          USING clob_field, l_scenario_id, l_entry_index;
 16  END;
 17  /

PL/SQL procedure successfully completed.

SQL> SELECT * FROM mytable;

SCENARIO_ID ENTRY_INDEX SOURCES
----------- ----------- --------------------------------------------------------------------------------
          1           1 <clob_value_with_length_2Million>
          2           2 clob2
person EJ Egyed    schedule 04.02.2021