I got this error when I tried to write more than 1024 characters on a line.
Before:
fileXrxHandle := UTL_FILE.FOPEN('LOG', lv_xrx_file_name, 'W');
Here I've opened a file without specifying the maximum number of characters on a line.
After:
fileXrxHandle := UTL_FILE.FOPEN('LOG', lv_xrx_file_name, 'W',32767);
Here I've opened a file specifying the maximum number of characters on a line.The max value that oracle accepts is 32767.
This change resolved ORA-29285: File Write Error.
Document my experience using Oracle pro*c/c++,pl/sql and vi editor. Blog examples,tips and general information.
Showing posts with label pl/sql. Show all posts
Showing posts with label pl/sql. Show all posts
Wednesday, September 26, 2012
Thursday, June 17, 2010
Using BULK COLLECT
Use the BULK COLLECT feature when you need to fetch large amounts of data. This will increase the speed of excution of the pl/sql but consume more memory. The amount of memory consumed can be controlled through the LIMIT clause.
Below is an example that fetches all the rows at once.
declare
TYPE v_codes_type
IS TABLE OF v_codes%ROWTYPE
INDEX BY PLS_INTEGER;
l_code v_codes_type; --You can also use a view/cursor instead of a table
BEGIN
SELECT *
BULK COLLECT INTO l_code
FROM v_codes;
FOR indx IN 1 .. l_code.COUNT --indx variable need not be declared
LOOP
dbms_output.put_line('Code_id ' || l_code(indx).code_id || 'code_type '|| l_code(indx).code_type);
--use of l_code(indx) like a structure to display the values
END LOOP;
END;
/
Rather than fetching all the rows and consuming memory you can use the LIMIT clause.
You need to utilise a cursor to use the LIMIT clause.
Below is an example with LIMIT clause
declare
cursor v_codes_cur is
select * from v_codes;
TYPE v_codes_type IS TABLE OF v_codes_cur%ROWTYPE
INDEX BY PLS_INTEGER;
l_code v_codes_type;
BEGIN
Open v_codes_cur;
LOOP
FETCH v_codes_cur
BULK COLLECT into l_code LIMIT 100;
FOR indx IN 1 .. l_code.COUNT LOOP
dbms_output.put_line('Code_id ' || l_code(indx).code_id || 'code_type ' || l_code(indx).code_type);
END LOOP;
EXIT WHEN 1_code.count =0 ;
END LOOP;
close v_codes_cur;
END;
/
According to an article by Steve the performance doesn't improve much when the limit clause is more than 25.The performance pretty much remains the same for a limit clause value more than 25.
Note: Use of %NOTFOUND with BULK COLLECT
Don't use %NOTFOUND with BULK COLLECT because some of the rows will not get selected.
Instead use the
EXIT WHEN l_code.COUNT=0 value to determine if all the rows have been selected.
The EXIT WHEN v_codes_cur%NOTFOUND is suitable when fetching a single row at a time.
Here are a few important points on BULK COLLECT.
1) The collection is filled sequentially starting with index 1
2) The collection is empty when no data is selected.
3) Always check the contents of collection with the COUNT to see if any rows are selected.
4) Ignore the other cursor attrributes like %NOTFOUNd when using BULK COLLECT.
Below is an example that fetches all the rows at once.
declare
TYPE v_codes_type
IS TABLE OF v_codes%ROWTYPE
INDEX BY PLS_INTEGER;
l_code v_codes_type; --You can also use a view/cursor instead of a table
BEGIN
SELECT *
BULK COLLECT INTO l_code
FROM v_codes;
FOR indx IN 1 .. l_code.COUNT --indx variable need not be declared
LOOP
dbms_output.put_line('Code_id ' || l_code(indx).code_id || 'code_type '|| l_code(indx).code_type);
--use of l_code(indx) like a structure to display the values
END LOOP;
END;
/
Rather than fetching all the rows and consuming memory you can use the LIMIT clause.
You need to utilise a cursor to use the LIMIT clause.
Below is an example with LIMIT clause
declare
cursor v_codes_cur is
select * from v_codes;
TYPE v_codes_type IS TABLE OF v_codes_cur%ROWTYPE
INDEX BY PLS_INTEGER;
l_code v_codes_type;
BEGIN
Open v_codes_cur;
LOOP
FETCH v_codes_cur
BULK COLLECT into l_code LIMIT 100;
FOR indx IN 1 .. l_code.COUNT LOOP
dbms_output.put_line('Code_id ' || l_code(indx).code_id || 'code_type ' || l_code(indx).code_type);
END LOOP;
EXIT WHEN 1_code.count =0 ;
END LOOP;
close v_codes_cur;
END;
/
According to an article by Steve the performance doesn't improve much when the limit clause is more than 25.The performance pretty much remains the same for a limit clause value more than 25.
Note: Use of %NOTFOUND with BULK COLLECT
Don't use %NOTFOUND with BULK COLLECT because some of the rows will not get selected.
Instead use the
EXIT WHEN l_code.COUNT=0 value to determine if all the rows have been selected.
The EXIT WHEN v_codes_cur%NOTFOUND is suitable when fetching a single row at a time.
Here are a few important points on BULK COLLECT.
1) The collection is filled sequentially starting with index 1
2) The collection is empty when no data is selected.
3) Always check the contents of collection with the COUNT to see if any rows are selected.
4) Ignore the other cursor attrributes like %NOTFOUNd when using BULK COLLECT.
Wednesday, April 7, 2010
UTL_FILE GET_LINE ORA-29284 File Read Error
While reading a file using UTL_FILE .GET_LINE the procedure kept failing after reading a few line with a ORA-29284 error.
The file and directory had all full permissions [777].
The reason for the error was found to be due to the OCFS [oracle cluster file system] filesystem. Due to the mismatch in the version of the linux kernel and Oracle version.The physical path of 'VECTOR_DP500_ARCHIVE' was mapped to a shared folder on the oracle server.
The error was resolved after changing the physical path to non shared directory
The sql script.
declare
ptempFileName VARCHAR2(30) :='dpps_temp_file.dpps';
tempFileHandle UTL_FILE.FILE_TYPE;
lv_message VARCHAR2(500) := NULL;
lv_log_message VARCHAR2(500) := NULL;
line number:=0;
BEGIN
tempFileHandle := UTL_FILE.FOPEN('VECTOR_DP500_ARCHIVE',ptempFileName, 'R');
LOOP
lv_message:=NULL;
UTL_FILE.get_line(tempFileHandle,lv_message);
line:=line+1;
dbms_output.put_line(line||'='||lv_message||'\n');
END LOOP;
UTL_FILE.FCLOSE(tempFileHandle);
exception
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('no data found');
UTL_FILE.fclose_all();
WHEN OTHERS THEN
UTL_FILE.FCLOSE(tempFileHandle);
lv_log_message:='ERROR: COPY_DPPS_TEMP_FILE--'sqlerrm;
dbms_output.put_line(lv_log_message);
RAISE;
END ;
/
The file and directory had all full permissions [777].
The reason for the error was found to be due to the OCFS [oracle cluster file system] filesystem. Due to the mismatch in the version of the linux kernel and Oracle version.The physical path of 'VECTOR_DP500_ARCHIVE' was mapped to a shared folder on the oracle server.
The error was resolved after changing the physical path to non shared directory
The sql script.
declare
ptempFileName VARCHAR2(30) :='dpps_temp_file.dpps';
tempFileHandle UTL_FILE.FILE_TYPE;
lv_message VARCHAR2(500) := NULL;
lv_log_message VARCHAR2(500) := NULL;
line number:=0;
BEGIN
tempFileHandle := UTL_FILE.FOPEN('VECTOR_DP500_ARCHIVE',ptempFileName, 'R');
LOOP
lv_message:=NULL;
UTL_FILE.get_line(tempFileHandle,lv_message);
line:=line+1;
dbms_output.put_line(line||'='||lv_message||'\n');
END LOOP;
UTL_FILE.FCLOSE(tempFileHandle);
exception
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('no data found');
UTL_FILE.fclose_all();
WHEN OTHERS THEN
UTL_FILE.FCLOSE(tempFileHandle);
lv_log_message:='ERROR: COPY_DPPS_TEMP_FILE--'sqlerrm;
dbms_output.put_line(lv_log_message);
RAISE;
END ;
/
Subscribe to:
Posts (Atom)