这是我的第一个问题
我在尝试将表列(long raw)转换为base 64字符串时遇到问题,此列包含一些员工图片。
这是查询,我想要转换的字段是 f.fot_empl :
SELECT e.NOM_EMPL First_name,
APE_EMPL Last_name,
e.NOM_EMPL || ' ' || e.APE_EMPL Full_name,
car.NOM_CARG position,
COS.NOM_CCOS Area,
f.fot_empl Picture,
E.FEC_NACI Birth_date
FROM EMPLE e
INNER JOIN CONTR c
ON E.COD_EMPL = C.COD_EMPL
INNER JOIN cargo car
ON C.COD_CARG = CAR.COD_CARG
INNER JOIN CCOST cos
on COS.COD_CCOS = C.COD_CCOS
LEFT JOIN FOEMP f -- employee picture
ON e.cod_empl = F.COD_EMPL
WHERE C.IND_ACTI = 'A';
我尝试了什么:
这篇文章的接受答案没有结果,我不断收到“非法使用LONG数据类型”错误。 Workaround for ORA-00997: illegal use of LONG datatype
我尝试实现以下功能但没有结果:
CREATE OR REPLACE FUNCTION to_base64 (
vcodem IN FOEMP.COD_EMPR%TYPE,
vcodempl IN FOEMP.COD_EMPL%TYPE)
RETURN VARCHAR2
IS
V_VAR FOEMP.FOT_EMPL%TYPE;
V_result VARCHAR2 (4000);
BEGIN
DBMS_OUTPUT.put_line ('Start');
SELECT UTL_RAW.cast_to_varchar2 (
UTL_ENCODE.base64_encode (
UTL_RAW.cast_to_raw (DBMS_LOB.SUBSTR (f.FOT_EMPL, 4000))))
INTO V_result
FROM FOEMP f
WHERE COD_EMPL = vcodempl AND COD_EMPR = vcodem;
DBMS_OUTPUT.put_line ('End');
DBMS_OUTPUT.put_line ('Result: ' || V_result);
END to_base64;
/
由于ORA-00997在
中,该功能无效 SELECT UTL_RAW.cast_to_varchar2 (
UTL_ENCODE.base64_encode (
UTL_RAW.cast_to_raw (DBMS_LOB.SUBSTR (f.FOT_EMPL, 4000))))
INTO V_result
FROM FOEMP f
WHERE COD_EMPL = vcodempl AND COD_EMPR = vcodem;
非常感谢提前。
答案 0 :(得分:3)
您可以将LONG RAW值转换为PL / SQL块中的BLOB,然后对其进行base64编码:
CREATE OR REPLACE FUNCTION to_base64 (
vcodem IN FOEMP.COD_EMPR%TYPE,
vcodempl IN FOEMP.COD_EMPL%TYPE)
RETURN VARCHAR2
IS
l_blob BLOB;
l_long_raw LONG RAW;
BEGIN
SELECT fot_empl INTO l_long_raw
FROM foemp
WHERE COD_EMPL = vcodempl AND COD_EMPR = vcodem;
l_blob := TO_BLOB(l_long_raw);
RETURN UTL_RAW.cast_to_varchar2 (UTL_ENCODE.base64_encode (l_blob));
END;
/
当然,strongly recommends that you convert LONG RAW columns to binary LOB (BLOB) columns;仍然将数据存储为LONG或LONG raw现在似乎过时了。
答案 1 :(得分:1)
SQL为varchar2绑定最多4000,为char绑定最多2000。 raw是一个二进制char,所以我会编码不到2k的块,比如:
create or replace FUNCTION base64enc(p_blob IN BLOB) RETURN CLOB
AS
l_clob CLOB;
l_step PLS_INTEGER := 1998;
BEGIN
FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(p_blob) - 1 )/l_step) LOOP
l_clob := l_clob || UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(DBMS_LOB.substr(p_blob, l_step, i * l_step + 1)));
END LOOP;
RETURN l_clob;
END base64enc;
现在您已经拥有了base64enc功能,您可以传入(已转换的)blob并存储CLOB。
一个例子可能是:
create table t1 ( id int primary key, x long raw )
insert into t1 values( 1, rpad( 'a', 2000, 'a' ) )
commit;
create or replace function convertLR(i_id in int)
return clob
as
l_blob blob;
l_longraw long raw;
begin
select x into l_longraw from t1 where id = i_id;
l_blob := to_blob(l_longraw);
return base64enc(l_blob);
end;
select convertLR(1) from dual;
答案 2 :(得分:1)
<强>解决方案强>
考虑到我在长原始时遇到的许多问题,我决定创建一个 像这样的表:
CREATE TABLE FOTS_EMPL ( cod_empr, cod_empl, foto)
AS
SELECT F.COD_EMPR, F.COD_EMPL, TO_LOB (FOT_EMPL)
FROM FOEMP f;
我接受了@tbone给出的功能,我添加了条件 像这样:
CREATE OR REPLACE FUNCTION base64enc (p_blob IN BLOB)
RETURN CLOB
AS
l_clob CLOB;
l_step PLS_INTEGER := 1998;
BEGIN
IF p_blob IS NOT NULL
THEN
FOR i IN 0 .. TRUNC ( (DBMS_LOB.getlength (p_blob) - 1) / l_step)
LOOP
l_clob :=
l_clob
|| UTL_RAW.cast_to_varchar2 (
UTL_ENCODE.base64_encode (
DBMS_LOB.SUBSTR (p_blob, l_step, i * l_step + 1)));
END LOOP;
RETURN l_clob;
ELSE
RETURN NULL;
END IF;
END base64enc;
这是我最后的选择陈述:
SELECT e.NOM_EMPL First_name,
APE_EMPL Last_name,
e.NOM_EMPL || ' ' || e.APE_EMPL Full_name,
car.NOM_CARG position,
COS.NOM_CCOS Area,
base64enc(foto) Picture,
E.FEC_NACI Birth_date
FROM EMPLE e
INNER JOIN CONTR c
ON E.COD_EMPL = C.COD_EMPL
INNER JOIN cargo car
ON C.COD_CARG = CAR.COD_CARG
INNER JOIN CCOST cos
on COS.COD_CCOS = C.COD_CCOS
LEFT JOIN FOTS_EMPL F -- new table with blob instead of long raw
ON e.cod_empl = F.COD_EMPL AND e.cod_empr = f.cod_empr
WHERE C.IND_ACTI = 'A';
非常感谢。