我已经存储了plsql过程,该过程从文件中获取大文本

create or replace
procedure dbst_load_a_file( p_file_name in varchar2, l_clob  out  clob )
    as
        l_bfile   bfile;
        dst_offset  number := 1 ;
        src_offset  number := 1 ;
        lang_ctx    number := DBMS_LOB.DEFAULT_LANG_CTX;
        warning     number;
    begin
        l_bfile := bfilename( 'SCHEMES_OF_PS', p_file_name );
        dbms_lob.fileopen( l_bfile );
        dbms_lob.loadclobfromfile(
          DEST_LOB     => l_clob
        , SRC_BFILE    => l_bfile
        , AMOUNT       => dbms_lob.getlength( l_bfile )
        , DEST_OFFSET  => dst_offset
        , SRC_OFFSET   => src_offset
        , BFILE_CSID   => DBMS_LOB.DEFAULT_CSID
        , LANG_CONTEXT => lang_ctx
        , WARNING      => warning);
        dbms_lob.fileclose( l_bfile );
    end;

然后我尝试以这种方式使用它:
  insert into SCHEME_SOURCE (SOURCE, ID, CODE)
  values (exec dbst_load_a_file( 'SCHEMES_OF_PS', 'Konotop.svg' ), 15, 'Konotop');

或更正确:
declare
  myVal clob := empty_clob();

begin
  DBMS_OUTPUT.PUT_LINE(myVal);
  dbst_load_a_file('Konotop.svg', myVal);
  DBMS_OUTPUT.PUT_LINE(myVal);
end;

在第二种情况下,我得到一个错误



在第一种情况下,我怀疑语法不存在。

如何从已存储的plsql中从使用该过程/函数的过程/函数中退出/返回CLOB参数

如果我有此代码
create or replace
function dbst_load_a_file2( p_file_name in varchar2 ) return clob
    is
        l_clob  clob;
        l_bfile   bfile;
        dst_offset  number := 1 ;
        src_offset  number := 1 ;
        lang_ctx    number := DBMS_LOB.DEFAULT_LANG_CTX;
        warning     number;
    begin
        l_bfile := bfilename( 'SCHEMES_OF_PS', p_file_name );
        dbms_lob.fileopen( l_bfile );
        dbms_lob.loadclobfromfile(
          DEST_LOB     => l_clob
        , SRC_BFILE    => l_bfile
        , AMOUNT       => dbms_lob.getlength( l_bfile )
        , DEST_OFFSET  => dst_offset
        , SRC_OFFSET   => src_offset
        , BFILE_CSID   => DBMS_LOB.DEFAULT_CSID
        , LANG_CONTEXT => lang_ctx
        , WARNING      => warning);
        dbms_lob.fileclose( l_bfile );
        return l_clob;
    end;

  insert into SCHEME_SOURCE (SOURCE, ID, CODE)
  values (dbst_load_a_file2('Konotop.svg' ), 15, 'Konotop');

然后又出现了错误



谢谢

最佳答案

这一点:

    dbms_lob.loadclobfromfile(
      DEST_LOB     => l_clob

...您的l_clob OUT参数尚未初始化。使其为空的CLOB也不起作用(因此,即使您将l_clob设置为IN OUT参数,它仍然会抱怨)as the documentation for empty_clob mentions:



您可以改用临时CLOB,方法是在尝试使用dbms_lob.createtemporary(l_clob, true)之前添加对其的调用:
...
begin
    l_bfile := bfilename( 'SCHEMES_OF_PS', p_file_name );
    dbms_lob.fileopen( l_bfile );
    dbms_lob.createtemporary(l_clob, true);
    dbms_lob.loadclobfromfile(
      DEST_LOB     => l_clob
      ...

然后,您在调用它时无需给出初始的空值:
declare
  myVal clob;
begin
  dbst_load_a_file('Konotop.svg', myVal);
  DBMS_OUTPUT.PUT_LINE(myVal);
end;
/

这也可以用作功能:
create or replace
function dbst_load_a_file( p_file_name in varchar2) return clob
as
    l_clob    clob;
    l_bfile   bfile;
    dst_offset  number := 1 ;
    src_offset  number := 1 ;
    lang_ctx    number := DBMS_LOB.DEFAULT_LANG_CTX;
    warning     number;
begin
    l_bfile := bfilename( 'SCHEMES_OF_PS', p_file_name );
    dbms_lob.fileopen( l_bfile );
    dbms_lob.createtemporary(l_clob, true);
    dbms_lob.loadclobfromfile(
      DEST_LOB     => l_clob
    , SRC_BFILE    => l_bfile
    , AMOUNT       => dbms_lob.getlength( l_bfile )
    , DEST_OFFSET  => dst_offset
    , SRC_OFFSET   => src_offset
    , BFILE_CSID   => DBMS_LOB.DEFAULT_CSID
    , LANG_CONTEXT => lang_ctx
    , WARNING      => warning);
    dbms_lob.fileclose( l_bfile );
    return l_clob;
end;
/

select dbst_load_a_file('Konotop.svg') from dual;

或者像编辑的问题一样在insert中使用。

07-24 20:22