如何使用 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';
我正在尝试将我的 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';