Reputation: 83
I am new to LOB data type, i am getting error will execute this procedure script as below....
CREATE TABLE SA_ZIP_TEST (
SEQ NUMBER,
STRING_BLOB BLOB,
STRING_CLOB CLOB,
DT DATE
);
CREATE OR REPLACE PROCEDURE ZIP(src IN clob, dst IN OUT NOCOPY BLOB )
IS
BEGIN
IF src is not null THEN
DBMS_LOB.createtemporary(dst, true, DBMS_LOB.CALL);
XML_ZIP_PKG_2.ZIP_CLOB(src, dst);
DBMS_LOB.FREETEMPORARY(dst);
END IF;
END ZIP;
Will execute the below script getting an error message ORA-22275
DECLARE
V_Query_Str VARCHAR2 (4000);
V_RESULT CLOB;
V_RESULT2 bLOB;
BEGIN
DBMS_LOB.CREATETEMPORARY(V_Result, TRUE, dbms_lob.session);
FOR I IN 1..100
LOOP
V_Query_Str:=
'INSERT INTO SA_ZIP_TEST
(seq
,DT
,STRING_BLOB
)
VALUES
(:Cmd_Seq
,:Cmd_DT
,:Result)
';
xml_zip_pkg_2.ZIP(V_Result,V_RESULT2);
EXECUTE IMMEDIATE V_Query_Str USING I, SYSDATE,V_RESULT2 ;
END LOOP;
END;
Upvotes: 0
Views: 25958
Reputation: 191275
You are freeing the BLOB before the caller has a chance to do anything with it. But you don't need to create it either really, since it's declared by the caller - you would only need to create it if the parameter was OUT
, rather than IN OUT
. So your procedure only needs to do:
IF src is not null THEN
DBMS_LOB.createtemporary(dst, true, DBMS_LOB.CALL);
XML_ZIP_PKG_2.ZIP_CLOB(src, dst);
END IF;
The caller can (and should) still free the BLOB after using it:
ZIP(V_Result,V_RESULT2);
EXECUTE IMMEDIATE V_Query_Str USING I, SYSDATE,V_RESULT2 ;
DBMS_LOB.FREETEMPORARY(V_RESULT2);
Or after the loop. It might be more efficient to create the temporary BLOB once in the caller, before the loop, and free it at the end; then your procedure can do:
IF src is not null THEN
XML_ZIP_PKG_2.ZIP_CLOB(src, dst);
END IF;
And the caller can do:
BEGIN
DBMS_LOB.CREATETEMPORARY(V_Result, TRUE, dbms_lob.session);
DBMS_LOB.CREATETEMPORARY(V_Result2, TRUE, dbms_lob.call);
FOR I IN 1..100
LOOP
..
ZIP(V_Result,V_RESULT2);
EXECUTE IMMEDIATE V_Query_Str USING I, SYSDATE,V_RESULT2 ;
END LOOP;
DBMS_LOB.FREETEMPORARY(V_RESULT2);
END;
Although you can define V_Query_Str
once, and this doesn't need to use dynamic SQL at all:
DECLARE
V_RESULT CLOB;
V_RESULT2 bLOB;
BEGIN
DBMS_LOB.CREATETEMPORARY(V_Result, TRUE, dbms_lob.session);
DBMS_LOB.CREATETEMPORARY(V_Result2, TRUE, dbms_lob.call);
FOR I IN 1..100 LOOP
ZIP(V_Result,V_RESULT2);
INSERT INTO SA_ZIP_TEST
(seq
,DT
,STRING_BLOB
)
VALUES
(i
,sysdate
,V_RESULT2);
END LOOP;
DBMS_LOB.FREETEMPORARY(V_RESULT2);
END;
/
Here's an SQL Fiddle demo, using converttoblob
as we don't have your package.
Upvotes: 2
Reputation: 23737
V_RESULT2
becomes invalid locator after invocation of xml_zip_pkg_2.ZIP(V_Result,V_RESULT2);
because of DBMS_LOB.FREETEMPORARY(dst);
inside ZIP
Upvotes: 3