【问题标题】:How to encode blob data to base 64 with SQL?如何使用 SQL 将 blob 数据编码为 base 64?
【发布时间】:2018-08-20 19:42:00
【问题描述】:

我正在尝试将我的 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)返回图片的1/4,但是string2和string3因为位置不对什么的,不起作用……

感谢您的帮助!

【问题讨论】:

    标签: sql blob peoplesoft


    【解决方案1】:

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

    【讨论】:

    • 谢谢 Walucas,你能告诉我一个将文件保存在目录部分的例子吗?谢谢!
    • 由于某种原因我们没有应用包 SCC_COMMON_UTILITIES
    • 您在哪个应用程序中? FSCM 还是 HR?
    • 我们在人力资源部 :)
    • 啊好吧!我将从 SCC_COMMON_UTILITIES 发布代码,您需要重新创建它
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-15
      • 2017-11-29
      • 2018-09-01
      • 2018-02-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多