oracle需要把blob(在不截取的条件下)完整转为varchar2类型

oracle需要把blob(在不截取的条件下)完整转为varchar2类型,可以做到吗?(仅限函数,sql)怎么做?

标准varchar2标准不超过4000字符,oracle 12c以后,开启扩展支持参数,varchar2可以支持32k。
字符型默认使用clob存储。
在支持长度内,select 查询clob可以默认转换varchar2.
超长的发生截取。
或者使用函数分段读取实现。
考虑极端情况,一个2gb的clob,你确认药要执行这种操作?

可以参考一下:
https://blog.csdn.net/weixin_32946543/article/details/116321001

oracle数据库字段设置成blob类型 进行文件二进制存储,或者转成base64进行字符串存储,但不建议这样直接把文件存数据库里,软件后期维护和数据性能都会有比较大的影响

可以使用dbms_lob.substr()函数

使用 UTL_RAW.CAST_TO_VARCHAR2 函数, 官网: https://docs.oracle.com/en/database/oracle/oracle-database/21/arpls/UTL_RAW.html#GUID-E972F35F-C8EC-4CC2-8EC5-17702E8921D8
一些用法示例如下:


-- blob长度小于2000
SELECT
    UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(HEAD_IMG))
FROM
    table
WHERE
    HEAD_IMG IS NOT NULL;

-- blob长度大于4000
SELECT
    UTL_RAW.CAST_TO_VARCHAR2(UTL_RAW.CONVERT(DBMS_LOB.SUBSTR(HEAD_IMG, 2000, 1),'SIMPLIFIED CHINESE_CHINA.ZHS16GBK', 'AMERICAN_THE NETHERLANDS.UTF8')) COLUME_NAME1,
    UTL_RAW.CAST_TO_VARCHAR2(UTL_RAW.CONVERT(DBMS_LOB.SUBSTR(HEAD_IMG, 2000, 2001),'SIMPLIFIED CHINESE_CHINA.ZHS16GBK', 'AMERICAN_THE NETHERLANDS.UTF8')) COLUME_NAME2,
    UTL_RAW.CAST_TO_VARCHAR2(UTL_RAW.CONVERT(DBMS_LOB.SUBSTR(HEAD_IMG, 2000, 4001),'SIMPLIFIED CHINESE_CHINA.ZHS16GBK', 'AMERICAN_THE NETHERLANDS.UTF8')) COLUME_NAME3
FROM
    table
WHERE
    HEAD_IMG IS NOT NULL;
    
-- blob长度大于2000,小于4000
SELECT
    UTL_RAW.CAST_TO_VARCHAR2(UTL_RAW.CONVERT(DBMS_LOB.SUBSTR(HEAD_IMG, 2000, 1),'SIMPLIFIED CHINESE_CHINA.ZHS16GBK', 'AMERICAN_THE NETHERLANDS.UTF8'))
||  UTL_RAW.CAST_TO_VARCHAR2(UTL_RAW.CONVERT(DBMS_LOB.SUBSTR(HEAD_IMG, 2000, 2001),'SIMPLIFIED CHINESE_CHINA.ZHS16GBK', 'AMERICAN_THE NETHERLANDS.UTF8'))
FROM
    table
WHERE
    HEAD_IMG IS NOT NULL;

SELECT CONVERT(UTL_RAW.CAST_TO_VARCHAR2(HEAD_IMG), 'ZHS16GBK', 'AL32UTF8') FROM table WHERE HEAD_IMG IS NOT NULL;

不可以哦,varchar2最大长度为4000,不能直接将blob转为varchar2,一般都是通过函数将blob返回为table格式来实现的
1、创建两个新的type,用于函数返回

create or replace type obj_table as object
(
  name varchar2(2000)
);create or replace type t_table is table of obj_table

2、创建blob转varchar2的函数

CREATE OR REPLACE
Function Blob_To_Varchar (id In VARCHAR2) Return t_table
as
  rs t_table:= t_table();-- 定义上面创建的类型
  Blob_In blob;
    V_Varchar Varchar2(2000);
    V_Start Pls_Integer := 1;
    V_Buffer Pls_Integer := 2000;
Begin
 
    SELECT COLIMN_BLOB_NAME into Blob_In FROM table a WHERE a.id= id; -- 根据id查询blob所在的表
    For I In 1..Ceil(Dbms_Lob.Getlength(Blob_In) / V_Buffer) Loop -- 遍历blob
        --当转换出来的字符串乱码时,可尝试用注释掉的函数
        --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));
        rs.extend;-- 扩展已知的数组空间
    rs(rs.count) := obj_table(V_Varchar);-- 往上面创建obj_table中写入数据
    V_Start := V_Start + V_Buffer;
    End Loop;
    Return rs;
End Blob_To_Varchar;

3、查询结果

select * from table(Blob_To_Varchar(id))