Вставьте CLOB из функции в таблицу в PL SQL 11g - PullRequest
0 голосов
/ 27 марта 2020

У меня есть таблица

    CREATE TABLE "SCOTT"."FILES" 
   (    "FILE_ID" NUMBER(10,0) NOT NULL ENABLE, 
    "TEXT" BLOB, 
    "FILE_NAME" VARCHAR2(30), 
    "HTML_CONTENT" CLOB, 
     CONSTRAINT "FILES_PK" PRIMARY KEY ("FILE_ID"));

Я хочу вставить HTML Формат в столбце HTML_CONTENT. Я написал функцию, которая возвращает содержимое файлов html:

    create or replace function get_html(
v_file_id in scott.files.file_id%type) return clob
 as

l_clob clob;
v_file_name scott.files.file_name%type;
v_bfile bfile;

begin
select file_name into v_file_name from scott.files where file_id=v_file_id;
v_bfile := bfilename( 'FILES', v_file_name );
ctx_doc.policy_filter( 'my_policy', v_bfile, l_clob, false );
      return l_clob ;

end;

Я хочу вставить это содержимое в столбец HTML_CONTENT. Я использую процедуру для вставки файлов и соответствующего содержания. Все вставки идут хорошо, кроме содержимого HTML. Он вставляет нулевые значения в столбец clob

    create or replace PROCEDURE LOAD_FILE_TO_TABLE 
(
  DIR_NAME IN VARCHAR2 DEFAULT 'FILES'
, FILE_NAME IN VARCHAR2 
) AS 
 l_clob clob;
l_blob blob;
l_bfile bfile;
html_format clob;  
f_id pls_integer;

BEGIN

f_id:=S1.nextval;

--html_format:=get_html(S1.currval);
 insert into scott.files (file_id,file_name, text,html_content)
    values (f_id,FILE_NAME, empty_blob(),empty_clob())
    returning text,get_html(f_id) into l_blob,html_format;

--insert into scott.files(html_content) values (html_format);

  l_bfile := bfilename( DIR_NAME, FILE_NAME );
  dbms_lob.fileopen( l_bfile );
  dbms_lob.loadfromfile
    (l_blob, l_bfile, dbms_lob.getlength( l_bfile ) );
  --  html_format:=get_html(S1.currval);
    dbms_output.put_line(html_format);
     dbms_lob.loadfromfile
    (html_format, l_bfile, dbms_lob.getlength( l_bfile ) );
  dbms_lob.fileclose( l_bfile );
  commit;


END LOAD_FILE_TO_TABLE;

Пожалуйста, помогите мне создать механизм таким образом, чтобы при вставке нового документа он мог генерировать и вставлять содержимое html в этот столбец clob.

Ответы [ 3 ]

0 голосов
/ 27 марта 2020

Спасибо за быстрый ответ Алекс. При использовании следующей стратегии, но с ошибкой ORA-22290: операция превысит максимальное количество открытых файлов или больших объектов ORA-06512: в «SYS.DBMS_LOB», строка 805 ORA-06512: в «SYS.LOAD_FILE_TO_TABLE», строка 14 ORA-06512: в строке 3 22290. 00000 - «операция превысила бы максимальное количество открытых файлов или больших объектов» * Причина: число открытых файлов или больших объектов достигло максимального предела. * Действие: закройте некоторые из открытых файлов или больших объектов и повторите операцию.

 create or replace PROCEDURE LOAD_FILE_TO_TABLE 
    (
      DIR_NAME IN VARCHAR2 DEFAULT 'FILES'
    , FILE_NAME IN VARCHAR2 
    ) AS 

      l_bfile bfile;
      l_clob clob;
      l_blob blob;

    BEGIN

      l_bfile := bfilename( DIR_NAME, FILE_NAME );
      dbms_lob.fileopen( l_bfile );
      dbms_lob.loadfromfile
        (l_blob, l_bfile, dbms_lob.getlength( l_bfile ) );


      ctx_doc.policy_filter( 'my_policy', l_blob, l_clob, false );

      insert into scott.files (file_id, file_name, text, html_content)
      values (s1.nextval, FILE_NAME, empty_blob(), empty_clob()) returning text,html_content into l_blob,l_clob;
      dbms_output.put_line(l_clob);
    dbms_lob.fileclose( l_bfile );
    END LOAD_FILE_TO_TABLE;
0 голосов
/ 28 марта 2020

Успешно вставлено в этот лог c

 create or replace PROCEDURE LOAD_FILE_TO_TABLE 
    (
      DIR_NAME IN VARCHAR2 DEFAULT 'FILES'
    , FILE_NAME IN VARCHAR2 
    ) AS 

      l_bfile bfile;
      l_clob clob;
      l_blob blob;

    BEGIN
    insert into scott.files (file_id, file_name, text, html_content)
      values (s1.nextval, FILE_NAME, empty_blob(), empty_clob()) returning text,html_content into l_blob,l_clob;
      l_bfile := bfilename( DIR_NAME, FILE_NAME );
      dbms_lob.fileopen( l_bfile );
      dbms_lob.loadfromfile
        (l_blob, l_bfile, dbms_lob.getlength( l_bfile ) );


      ctx_doc.policy_filter( 'my_policy', l_bfile, l_clob, false );


     -- dbms_output.put_line(l_clob);
    dbms_lob.fileclose( l_bfile );
    END LOAD_FILE_TO_TABLE;
0 голосов
/ 27 марта 2020

Ваша вставка устанавливает text в и html_content для пустых больших объектов (не ноль). Вы возвращаете их, но ничего с ними не делаете (l_blob заменяется более поздним load-from_file() вызовом; html_format печатается, но затем также заменяется).

Я думаю, вы можете упростить это совсем немного; если вы все равно собираетесь прочитать файл в процедуре, тогда вам не нужна функция, и вам не нужно читать ее несколько раз:

create or replace PROCEDURE LOAD_FILE_TO_TABLE 
(
  DIR_NAME IN VARCHAR2 DEFAULT 'FILES'
, FILE_NAME IN VARCHAR2 
) AS 

  l_bfile bfile;
  l_clob clob;
  l_blob blob;

BEGIN

  l_bfile := bfilename( DIR_NAME, FILE_NAME );

  dbms_lob.createtemporary(l_blob, false);

  dbms_lob.fileopen( l_bfile );
  dbms_lob.loadfromfile
    (l_blob, l_bfile, dbms_lob.getlength( l_bfile ) );
  dbms_lob.fileclose( l_bfile );

  ctx_doc.policy_filter( 'my_policy', l_blob, l_clob, false );

  insert into files (file_id, file_name, text, html_content)
  values (s1.nextval, FILE_NAME, l_blob, l_clob);

END LOAD_FILE_TO_TABLE;
/

Не проверено, поскольку у меня нет CTX пакеты доступны, или ваша политика, но, кажется, делает то, что вы хотели ... он компилирует хотя, по крайней мере.

...