zoukankan      html  css  js  c++  java
  • (Oracle)关于blob转到目标库报ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值错误解决方案

    在数据抽取时,开发需要clob类型的数据,但是目标库类型是blob类型的,于是抽取的时候报错:

    ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值错误

    可能有以下几种原因:

    可能有以下几种原因:

    1、插入到字符串长度大于4000字节。

    2、插入到表中的记录的某个字段数据的实际长度大于2000个字节(如果是UTF-8,则是1333个字节);或者是插入的记录中有两个或两个以上长度大于2000字节的字符串。

    3、数据库与客户端的JDBC 驱动不匹配。对于UTF-8或欧洲的某些字符集,oracle在存储时,对于一个字符需要2个或3个字节的存储空间,虽然表定义中为 varchar2(4000),但是其实该字段的data_length为其2倍或3倍长。这种情况下oracle会把data_length长度超过 4000的当做LONG型处理,你的表中有两个这样的字段,插入数据时相当于同时操作2个LONG字段。

    4、使用9i的及以下的版本引发的bug. 10.1.0.1版本中已经修复bug

    我这边遇到的是第一种,字符串长度大于4000了。

    解决方法:

    创建函数进行转换就可以了。

    函数如下:

    CREATE OR REPLACE FUNCTION BlobToClob(blob_in IN BLOB) RETURN CLOB AS
      v_clob    CLOB;
      v_varchar VARCHAR2(32767);
      v_start   PLS_INTEGER := 1;
      v_buffer  PLS_INTEGER := 32767;
    BEGIN
      DBMS_LOB.CREATETEMPORARY(v_clob, TRUE);
      FOR i IN 1 .. CEIL(DBMS_LOB.GETLENGTH(blob_in) / v_buffer) LOOP
        v_varchar := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_in,
                                                              v_buffer,
                                                          
                                                              v_start));
        DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_varchar), v_varchar);
        DBMS_OUTPUT.PUT_LINE(v_varchar);
        v_start := v_start + v_buffer;
      END LOOP;
      RETURN v_clob;
    END BlobToClob;
    

     blob转varchar

    CREATE OR REPLACE Function Blob_To_Varchar (Blob_In In Blob) Return Varchar2
    Is
        V_Varchar Varchar2(4000);
        V_Start Pls_Integer := 1;
        V_Buffer Pls_Integer := 4000;
    Begin
        If Dbms_Lob.Getlength(Blob_In) Is Null Then
            Return '';
        End If;
        For I In 1..Ceil(Dbms_Lob.Getlength(Blob_In) / V_Buffer) Loop
            --当转换出来的字符串乱码时,可尝试用注释掉的函数
            --V_Varchar := Utl_Raw.Cast_To_Varchar2(Utl_Raw.Convert(Dbms_Lob.Substr(Blob_In, V_Buffer, V_Start),'SIMPLIFIED CHINESE_CHINA.ZHS16GBK', 'AMERICAN_THE NETHERLANDS.UTF8'));
            V_Varchar := Utl_Raw.Cast_To_Varchar2(Dbms_Lob.Substr(Blob_In, V_Buffer, V_Start));
            V_Start := V_Start + V_Buffer;
        End Loop;
        Return V_Varchar;
    End Blob_To_Varchar;
    
  • 相关阅读:
    EVIOCGNAME:Get Device Name
    Andriod Sensor HAL 分析
    通知内核你的设备 不支持llseek, 通过在你的 open 方法中调用nonseekable_open
    linux Gsensor驱动(bma250为例子)
    Linux输入子系统:输入设备编程指南 -- input-programming.txt
    Android UEventObserver 使用
    android switch模块
    linux里的驱动接口
    input subsystem 函数解释
    2.6 内核中的计时器 小结
  • 原文地址:https://www.cnblogs.com/littlewu/p/7798240.html
Copyright © 2011-2022 走看看