如何使用 SQL 将 blob 数据编码为 base 64?

How to encode blob data to base 64 with SQL?

我正在尝试将我的 blob 数据编码为 base64,以便我可以将图像传递给 XML BI Publisher

我最初试过这个:

select UTL_ENCODE.base64_encode(dbms_lob.substr(EPHOTO, 4000,1))) as 
string1 FROM EMPL_PHOTO WHERE emplid='1234';

但是我得到错误:

ORA-06502: PL/SQL: numeric or value error: raw variable length too long ORA-06512: at line 1

所以,我打算尝试将字符串拆分为 3 个部分,然后在 PeopleCode 中组合字符串。所以我尝试了下面的 sql,但是 dms_lob.substr 函数的第三个参数没有按位置拾取字符(因为它与字节有关),所以我不确定要做什么做或如何正确做。

SELECT utl_raw.cast_to_varchar2( 
UTL_ENCODE.base64_encode(dbms_lob.substr(EPHOTO, 1000,1))) as 
string1, 
utl_raw.cast_to_varchar2( 
UTL_ENCODE.base64_encode(dbms_lob.substr(EPHOTO, 1000,1001))) as 
string2,
utl_raw.cast_to_varchar2( 
UTL_ENCODE.base64_encode(dbms_lob.substr(EPHOTO, 1000,2001))) as 
string3
FROM EMPL_PHOTO WHERE emplid='1234';

第一个select (string1) returns 1/4的照片,但是string2和string3不行,因为位置不对什么的...

感谢您的帮助!

您可以使用 peoplecode 执行此操作,但您需要先将文件保存在一个目录中(如果您在这里有任何问题,请告诉我),然后:

import SCC_COMMON_UTILITIES:UTIL:Base64Wrapper;
Local File &FILE;
Local Record &REC;
Local SQL &SQL;

&REC = CreateRecord(Record.EMPL_PHOTO);
&SQL = CreateSQL("%SelectAll(:1) where emplid=:2", Record.EMPL_PHOTO, &emplid);
&imgPath = "EMPL_PHOTO.GIF";
&FILE = GetFile(&imgPath, "w", "a", %FilePath_Relative);

While &SQL1.Fetch(&REC)
   &FILE.WriteRaw(&REC.EMPLOYEE_PHOTO.Value);
End-While;
&FILE.Close();

&l_aBASE64 = create SCC_COMMON_UTILITIES:UTIL:Base64Wrapper();
&base64 = &l_aBASE64.encode(&imgPath);

Base64Wrapper 使用 Java class 来实现这一点。

 class Base64Wrapper
   method Base64Wrapper();
   method encode(&filename As string) Returns string;
   method decode(&filename As string, &base64data As string) Returns boolean;
   rem method getErrorDetails() Returns string;
private
   instance JavaObject &joB64;
end-class;

method Base64Wrapper
   rem &joB64 = CreateJavaObject("com.peoplesoft.hrms.hrs.base64Utils");
   &joB64 = CreateJavaObject("com.peoplesoft.hr.sa.base64Utils");
end-method;

method encode
   /+ &filename as String +/
   /+ Returns String +/


   Local string &filedata;


   &filedata = &joB64.base64Encode(&filename);

   Return &filedata;
end-method;

method decode
   /+ &filename as String, +/
   /+ &base64data as String +/
   /+ Returns Boolean +/
   Return &joB64.base64Decode(&filename, &base64data);

end-method;

我不得不采用仅 SQL 的解决方案,因为我们的代码库中缺少 java 库。

注意:此查询仅在照片小于或等于 7275 字节时有效。如果一些员工的照片比这个大,People Soft 中的调整员工照片大小脚本将需要 运行 才能运行此查询。

我在这里使用了 Jim Marion 的解决方案:

SELECT
CASE
  WHEN DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) > 1455 THEN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(DBMS_LOB.SUBSTR(EMPLOYEE_PHOTO, 1455, 1)))
  WHEN DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) <= 1455 THEN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(EMPLOYEE_PHOTO))
END AS C1,
CASE
  WHEN DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) > 2910 THEN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(DBMS_LOB.SUBSTR(EMPLOYEE_PHOTO, 1455, 1456)))
  WHEN DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) <= 2910 AND DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) > 1455 THEN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(DBMS_LOB.SUBSTR(EMPLOYEE_PHOTO, DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) - 1455, 1456)))
END AS C2,
CASE
  WHEN DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) > 4365 THEN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(DBMS_LOB.SUBSTR(EMPLOYEE_PHOTO, 1455, 2911)))
  WHEN DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) <= 4365 AND DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) > 2910 THEN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(DBMS_LOB.SUBSTR(EMPLOYEE_PHOTO, DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) - 2910, 2911)))
END AS C3,
CASE
  WHEN DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) > 5820 THEN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(DBMS_LOB.SUBSTR(EMPLOYEE_PHOTO, 1455, 4366)))
  WHEN DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) <= 5820 AND DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) > 4365 THEN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(DBMS_LOB.SUBSTR(EMPLOYEE_PHOTO, DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) - 4365, 4366)))
END AS C4,
CASE
  WHEN DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) > 7275 THEN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(DBMS_LOB.SUBSTR(EMPLOYEE_PHOTO, 1455, 5821)))
  WHEN DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) <= 7275 AND DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) > 5820 THEN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(DBMS_LOB.SUBSTR(EMPLOYEE_PHOTO, DBMS_LOB.GETLENGTH(EMPLOYEE_PHOTO) - 5820, 5821)))
END AS C5 
FROM PS_EMPL_PHOTO
WHERE EMPLID = 'KUL704';

http://jjmpsj.blogspot.com/2014_08_17_archive.html