插入大于2000或4000字节的BLOB测试字符串

时间:2015-10-16 09:12:53

标签: sql oracle blob database-management dbeaver

我在oracle中有一个BLOB列的表,可以存储XML,也可以压缩XMLs。这些是客户的要求,不能更改。将创建表格,我必须阅读并使用BLOBs内的一些信息。

我已经研究过,任何不明确的解决方案都是明确的或为我工作。

我遇到的问题是INSERT XML普通数据大于2000 bytesutl_raw.cast_to_raw使用DBeaver作为数据库管理员。我收到了消息:

SQL Error [6502] [65000]: ORA-06502: PL/SQL: numeric or value error: raw variable length too long ORA-06512: at "SYS.UTL_RAW", line 224
java.sql.SQLException: ORA-06502: PL/SQL: numeric or value error: raw variable length too long
ORA-06512: at "SYS.UTL_RAW", line 224

问题

  1. 我进行了研究,UTL_RAW不能超过2000 bytes
  2. 似乎Oracle {/ 1>中4000 bytes的{​​{1}}存在另一个限制

    我可以为这些案件做些什么?

2 个答案:

答案 0 :(得分:5)

对于初学者,您需要了解LOB是什么。它们是大数据",可能比Oracle中的任何其他数据类型都大。它们就像文件系统上的常规文件。要写入文件系统上的文件,您必须

  1. 打开文件进行编写
  2. 如果您希望从头开始填写文件,请截断文件
  3. 以循环方式读取您的源数据
  4. 将您的数据块一个接一个地附加到同一个循环中的文件
  5. 关闭文件
  6. LOB或多或少都是如此。在您的表中,LOB(CLOB / BLOB / NCLOB)列只是指向磁盘存储上保存实际数据的另一个位置的指针/引用。在标准的Oracle术语中,指针被称为" LOB定位器"。你需要

    1. 打开/初始化LOB定位器
    2. 截断LOB内容,如果您希望从头开始填写
    3. 将数据块一个接一个地附加到循环中的LOB内容
    4. 关闭LOB定位器
    5. 在PL / SQL中,它可能如下所示:

      -- create table blob_test(id number, b blob);
      
      declare 
        v_b blob; 
        aaa raw(32767);
        longLine varchar2(32767);
      begin 
        longLine :=  LPAD('aaaa', 32767,'x');
        aaa := UTL_RAW.CAST_TO_RAW(longLine);
        insert into blob_test values(1,empty_blob()) returning b into v_b;
        dbms_lob.open(v_b,dbms_lob.lob_readwrite);
        dbms_lob.writeappend(v_b,UTL_RAW.LENGTH (aaa) ,aaa);
        dbms_lob.close(LOB_LOC=>v_b);
        commit;
      end;
      

      解释:

      1. 初始化LOB定位器= insert into blob_test values(1,empty_blob()) returning b into v_b;
      2. 打开LOB定位器以写入= dbms_lob.open(v_b,dbms_lob.lob_readwrite);
      3. 截断LOB内容,如果您希望从头开始填写...这是通过empty_blob()中的insert调用完成的。
      4. 将数据块一个接一个地附加到循环中的LOB内容中=此处只有dbms_lob.writeappend()的一次迭代,仅追加长度为aaa的单个块utl_raw.length(aaa)(最大值为32767)进入LOB v_b
      5. 关闭LOB定位器= dbms_lob.close(LOB_LOC=>v_b);

答案 1 :(得分:-1)

函数utl_raw.cast_to_raw将数据类型VARCHAR2的值转换为原始值。显然,字符串的长度受VARCHAR2数据类型的限制。如果您需要将大型文本数据转换为LOB,则可以使用DBMS_LOB.CONVERTTOBLOB过程。

例如,您可以创建函数将大字符串值(clob作为输入)转换为blob。像这样的东西 -

create or replace function ClobToBlob (p_clob in clob) return blob is
   l_dest_offset   integer := 1;
   l_source_offset integer := 1;
   p_csid          number  := 0;
   l_lang_context  integer := DBMS_LOB.DEFAULT_LANG_CTX;
   l_warning       integer := DBMS_LOB.WARN_INCONVERTIBLE_CHAR;
   l_tmpblob blob;

  begin
   dbms_lob.createtemporary(l_tmpblob, true);
   DBMS_LOB.CONVERTTOBLOB
  (
   l_tmpblob,
   p_clob,
   DBMS_LOB.LOBMAXSIZE,
   l_dest_offset,
   l_source_offset,
   p_csid,
   l_lang_context,
   l_warning
  );
  return l_tmpblob;
end;