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

时间:2018-03-12 17:23:24

标签: sql blob peoplesoft

我尝试将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函数的第3个参数不是按位置拾取字符(因为它与字节有关),所以我不确定该做什么或如何做做得对。

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';

第一个选择(string1)返回照片的1/4,但是string2和string3不起作用,因为它们处于错误的位置或者什么......

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

您可以使用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 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;

答案 1 :(得分:0)

我不得不使用仅限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