we are in the process of upgrading our oracle database from 11.2 to 12.2
ran into an error: ORA-06553: PLS-306: wrong number or types of arguments in call to
I have created a simplified script that recreates the issue.
the error occurs at compile time.
If I comment out the section that results in the compile time error I can create the same error at run time.
I have added comments that hopefully explain what is going on.
if you want to run the code then you will need to create a directory in oracle called SUBS
and then place in the folder that the SUBS directory maps to a file called small.txt
the file can have anything in it. The only requirements are that the file not be empty and that every line in the file have a length of less than 4000 characters.
Here is detailed info about the versions of oracle we are going from / to:
old version of oracle:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
"CORE 11.2.0.3.0 Production"
TNS for 64-bit Windows: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
new version of oracle:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production
"CORE 12.2.0.1.0 Production"
TNS for 64-bit Windows: Version 12.2.0.1.0 - Production
NLSRTL Version 12.2.0.1.0 - Production
below is the script that recreates the error
--/*
CREATE OR REPLACE PACKAGE FILES AS
TYPE TRow is Record(RowNbr INTEGER, RowVal VARCHAR2(32767));
Type TFile is Table of TRow;
SubType FileNameType is varchar2(500);
SubType FolderNameType is varchar2(500);
FUNCTION Load (
p_FileName IN FileNameType,
p_FolderName IN FolderNameType
)
RETURN TFile pipelined;
FUNCTION Load (
p_FileName IN FileNameType,
p_FolderName IN FolderNameType,
p_MaxLineLength IN INTEGER
)
RETURN TFile pipelined;
FUNCTION DATE_PARAMETERIZE_FILE_NAME
(
p_FileName IN FileNameType,
p_ASOF_DT IN DATE
)
RETURN FileNameType;
FUNCTION File_Backup(
p_SrcFileName IN FileNameType,
p_SrcFolderName IN FolderNameType,
p_BackupFileName IN FileNameType,
p_BackupSrcFolderName IN FolderNameType
)
RETURN BOOLEAN;
FUNCTION File_Exists(
p_FileName IN FileNameType,
p_FolderName IN FolderNameType
)
RETURN BOOLEAN;
PROCEDURE FILE_DELETE(
p_FileName IN FileNameType,
p_FolderName IN FolderNameType
);
PROCEDURE AppendClob
(
p_file UTL_FILE.FILE_TYPE,
p_clob CLOB,
p_bufferSize BINARY_INTEGER DEFAULT 32767
);
END FILES;
commit;
CREATE OR REPLACE PACKAGE BODY FILES AS
FUNCTION Load (
p_FileName IN FileNameType,
p_FolderName IN FolderNameType
)
RETURN TFile pipelined IS
v_File UTL_FILE.FILE_TYPE;
v_RowNbr Integer;
v_Line Varchar2(4000);
v_Row TRow;
BEGIN
v_File := UTL_FILE.FOPEN(p_FolderName, p_FileName,'R');
v_RowNbr := 0;
IF UTL_FILE.IS_OPEN(v_File) THEN
Loop
v_RowNbr := v_RowNbr + 1;
UTL_FILE.GET_LINE(v_File,v_Line);
v_Row.RowNbr := v_RowNbr;
v_Row.RowVal := v_Line;
PIPE ROW(v_Row);
END Loop;
END IF;
return;
EXCEPTION
when NO_DATA_FOUND then
UTL_FILE.FCLOSE (v_File);
return;
END;
FUNCTION Load (
p_FileName IN FileNameType,
p_FolderName IN FolderNameType,
p_MaxLineLength IN INTEGER
)
RETURN TFile pipelined IS
v_File UTL_FILE.FILE_TYPE;
v_RowNbr Integer;
v_Line Varchar2(32767);
v_Row TRow;
BEGIN
v_File := UTL_FILE.FOPEN(p_FolderName, p_FileName,'R',32767);
v_RowNbr := 0;
IF UTL_FILE.IS_OPEN(v_File) THEN
Loop
UTL_FILE.GET_LINE(v_File,v_Line,32767);
if(Length(v_Line) <= p_MaxLineLength) then
v_RowNbr := v_RowNbr + 1;
v_Row.RowNbr := v_RowNbr;
v_Row.RowVal := v_Line;
PIPE ROW(v_Row);
end if;
END Loop;
END IF;
return;
EXCEPTION
when NO_DATA_FOUND then
UTL_FILE.FCLOSE (v_File);
return;
END;
PROCEDURE FILE_DELETE(
p_FileName IN FileNameType,
p_FolderName IN FolderNameType
)
IS
BEGIN
IF(File_Exists(p_FileName, p_FolderName)) then
UTL_FILE.FREMOVE(p_FolderName, p_FileName);
end if;
END;
FUNCTION File_Exists(
p_FileName IN FileNameType,
p_FolderName IN FolderNameType
)
RETURN BOOLEAN
As
v_FileLocation BFILE := NULL;
v_FileExists BOOLEAN;
BEGIN
v_FileLocation := BFILENAME(p_FolderName, p_FileName);
v_FileExists := DBMS_LOB.FILEEXISTS(v_FileLocation) = 1;
return v_FileExists;
END;
FUNCTION File_Backup(
p_SrcFileName IN FileNameType,
p_SrcFolderName IN FolderNameType,
p_BackupFileName IN FileNameType,
p_BackupSrcFolderName IN FolderNameType
)
RETURN BOOLEAN
AS
v_WasSuccess BOOLEAN := FALSE;
BEGIN
if(File_Exists(p_SrcFileName, p_SrcFolderName)) then
UTL_FILE.FRENAME(p_SrcFolderName, p_SrcFileName, p_BackupSrcFolderName, p_BackupFileName, TRUE);
v_WasSuccess := TRUE;
end if;
return v_WasSuccess;
END;
PROCEDURE AppendClob
(
p_file UTL_FILE.FILE_TYPE,
p_clob CLOB,
p_bufferSize BINARY_INTEGER DEFAULT 32767
)
as
v_bufferSize BINARY_INTEGER := p_bufferSize;
v_pos INTEGER := 1;
v_length number default nvl(dbms_lob.getlength(p_clob), 0);
BEGIN
if utl_file.is_open(p_file) then
while(v_pos < v_length)
LOOP
UTL_FILE.put(p_file, dbms_lob.substr(p_clob, p_bufferSize, v_pos));
UTL_FILE.FFLUSH(p_file);
v_pos := v_pos + v_bufferSize;
END LOOP;
UTL_FILE.NEW_LINE(p_file);
end if;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
FUNCTION DATE_PARAMETERIZE_FILE_NAME
(
p_FileName IN FileNameType,
p_ASOF_DT IN DATE
)
RETURN FileNameType
AS
v_ToReturn FileNameType;
v_Temp varchar(100);
BEGIN
if(TRIM(p_FileName) is not NULL) then
v_ToReturn := Trim(p_FileName);
if(p_ASOF_DT is NOT NULL) then
v_Temp := Extract(YEAR from p_ASOF_DT);
v_ToReturn := REPLACE(v_ToReturn, 'YYYY', v_Temp);
v_Temp := LPAD(Extract(Month from p_ASOF_DT), 2, '0');
v_ToReturn := REPLACE(v_ToReturn, 'MM', v_Temp);
v_Temp := LPAD(Extract(Day from p_ASOF_DT), 2, '0');
v_ToReturn := REPLACE(v_ToReturn, 'DD', v_Temp);
v_Temp := LPAD(Extract(HOUR from to_TIMESTAMP(p_ASOF_DT)), 2, '0');
v_ToReturn := REPLACE(v_ToReturn, 'HH', v_Temp);
v_Temp := LPAD(Extract(Minute from to_TIMESTAMP(p_ASOF_DT)), 2, '0');
v_ToReturn := REPLACE(v_ToReturn, 'MI', v_Temp);
v_Temp := LPAD(Extract(Second from to_TIMESTAMP(p_ASOF_DT)), 2, '0');
v_ToReturn := REPLACE(v_ToReturn, 'SS', v_Temp);
end if;
end if;
return v_ToReturn;
END;
END FILES;
commit;
--*/
--/*
CREATE OR REPLACE PACKAGE BUG_REPRODUCE AS
Type PL_TBL Is Table of VARCHAR2(4000);
FUNCTION ERROR_ON_COMPILE(
p_Rows FILES.TFile
)
RETURN PL_TBL PIPELINED;
PROCEDURE ENTRY_POINT;
END BUG_REPRODUCE;
commit;
CREATE OR REPLACE PACKAGE BODY BUG_REPRODUCE AS
----------------------------------------------------------------------
FUNCTION ERROR_ON_COMPILE(
p_Rows FILES.TFile
)
RETURN PL_TBL PIPELINED
IS
v_Str varchar2(4000);
BEGIN
if p_Rows.COUNT > 0
THEN
For indx in p_Rows.FIRST .. p_Rows.LAST
Loop
v_Str := p_Rows(indx).ROWVAL;
PIPE ROW(v_Str);
END Loop;
END IF;
return;
END;
----------------------------------------------------------------------
PROCEDURE ENTRY_POINT
IS
v_Rows_In_File INTEGER;
v_FileName FILES.FileNameType;
v_FolderName FILES.FolderNameType;
BEGIN
-- in oracle create directory with the following name
v_FolderName := 'SUBS';
-- in direction that above directoy is mapped to create file with following name
-- Note - each line in the file should have a length of less than 4000
v_FileName := 'small.txt';
DBMS_OUTPUT.PUT_LINE('this one works');
select count(*) into v_Rows_In_File
from TABLE(FILES.LOAD(v_FileName, v_FolderName));
DBMS_OUTPUT.PUT_LINE('this one works: answer' || to_char(v_Rows_In_File));
--/*
--BEGIN SECTION THAT REVEALS COMPILE TIME BUG : ORA-06553: PLS-306: wrong number or types of arguments in call to 'ERROR_ON_COMPILE'
DBMS_OUTPUT.PUT_LINE('this one cuases compile time error');
select count(*) into v_Rows_In_File
from TABLE(ERROR_ON_COMPILE(FILES.LOAD(v_FileName, v_FolderName)));
DBMS_OUTPUT.PUT_LINE('this one cuases compile time error : answer ' || to_char(v_Rows_In_File));
--*/
END;
----------------------------------------------------------------------
END BUG_REPRODUCE;
commit;
--*/
/*
-- the following statement demonstrates the FILES package is working as expected
select * from TABLE(FILES.LOAD('small.txt', 'SUBS'));
-- the following statement also demonstrates that the FILES package can be called from another package
execute BUG_REPRODUCE.ENTRY_POINT;
--BEGIN SECTION THAT REVEALS RUN TIME BUG : ORA-06553: PLS-306: wrong number or types of arguments in call to 'ERROR_ON_COMPILE'
-- NOTE: that you will first have to get the package to compile by commenting out the offending section that cause the compile time error
-- the following statement will produce error at run time BUG_REPRODUCE
select * from TABLE(BUG_REPRODUCE.ERROR_ON_COMPILE(FILES.LOAD('small.txt', 'SUBS')))
*/
Yep, it's a bug. I get the same behaviour on 12.2+
Time for you to get in touch with support...