DBMS_OUTPUT vs UTL_FILE
In calling PL/SQL stored procedures from UNIX c-scripts, we want to write messages to the logfile defined in, and used by, the script. Will DBMS_OUTPUT get there through the UNIX re-direct or another way, or do we need to open the logfile for append with UTL_FILE? If we do this, will the c-script still be able to write to the logfile after the PL/SQL proc has run?
UTL_FILE should be used when you want to log information to a file, DBMS_OUTPUT should be used when you want to provide feedback to an interactive user once their procedure call is done-- things like telling the user what the procedure just did. DBMS_OUTPUT writes to a limited-size buffer and cannot be read asynchronously-- you get all the messages after the code finishes. While you probably could jury-rig something where DBMS_OUTPUT calls were piped to a file, you're far better off going with UTL_FILE from the start.
Assuming that the stored procedure has closed the file (UTL_FILE.CLOSE), the C-shell script or any other process should be able to write to the file.
Justin
Distributed Database Consulting, Inc.
http://www.ddbcinc.com/askDDBC
Similar Messages
-
Any relation b/w set serveroutput on size 1000000 and utl_file
Hi All,
pls tell is any relation b/w set serveroutput on size 1000000 and utl_file
Thank u.there is no relation between them
one is used to output text on the screen
where as the other is used to output text on the file.
dbms_output->Screen
utl_file->file -
제품 : PL/SQL
작성날짜 : 2002-11-22
(8.0.5+) UTL_FILE PACKAGE사용시 READ_ERROR/WRITE_ERROR
===================================================
Problem Description
PLSQL에서 UTL_FILE package을 사용하여 text file를 read 하고 write할때
1023 byte 이상의 파일을 읽고 쓰고자 할때 다음의 ERROR을 만나게 된다.
UTL_FILE.WRITE_ERROR
UTL_FILE.READ_ERROR
User-defined exception
8.0.5 이전에는 UTL_FILE package을 사용하여 file을 다룰때 1023 byte이상의
데이터를 읽지 못하는 제한이 있었다. 하지만 8.0.5 이후에는 32,767 까지
사용 가능하다. 디폴트 최대 라인 싸이즈는 1023이지만 이것을 UTL_FILE.FOPEN
function에 MAX_LINESIZE 파라메터를 이용하여 해결 가능하다.
Default:
FUNCTION fopen(location IN VARCHAR2,
filename IN VARCHAR2,
open_mode IN VARCHAR2)
RETURN file_type;
최대 라인 싸이즈를 지정하고자 할때:
FUNCTION fopen(location IN VARCHAR2,
filename IN VARCHAR2,
open_mode IN VARCHAR2,
max_linesize IN BINARY_INTEGER)
RETURN file_type;
Solution Description:
MAX_LINESIZE 파라메터를 추가한 예이다.
CREATE OR REPLACE PROCEDURE file_test IS
file_handle UTL_FILE.FILE_TYPE; -- file handle of OS flat file
retrieved_buffer VARCHAR2(32767); -- Line retrieved from flat file
BEGIN
-- Open the same file to read from
file_handle :=
UTL_FILE.FOPEN('/home/ora920/product/9.2.0/utldir','myfile.txt','R',32767);
-- UTL_FILE.FOPEN('/home/ora920/product/9.2.0/utldir','myfile.txt','R'); -- READ_ERROR
-- Read a line from the file.
UTL_FILE.GET_LINE (file_handle, retrieved_buffer);
-- Print fetched line out to the SQL*PLUS prompt.
DBMS_OUTPUT.PUT_LINE('File size is : '||LENGTH(retrieved_buffer));
-- CLose the file.
UTL_FILE.FCLOSE(file_handle);
file_handle :=
UTL_FILE.FOPEN('/home/ora920/product/9.2.0/utldir','out.txt','W',32767);
-- UTL_FILE.FOPEN('/home/ora920/product/9.2.0/utldir','out.txt','W'); --WRITE_ERROR
UTL_FILE.PUT_LINE (file_handle, retrieved_buffer);
UTL_FILE.FCLOSE(file_handle);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('no_data_found');
UTL_FILE.FCLOSE(file_handle);
WHEN UTL_FILE.INVALID_PATH THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.INVALID_PATH');
UTL_FILE.FCLOSE(file_handle);
WHEN UTL_FILE.READ_ERROR THEN
DBMS_OUTPUT.PUT_LINE(' UTL_FILE.READ_ERROR');
UTL_FILE.FCLOSE(file_handle);
WHEN UTL_FILE.WRITE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.WRITE_ERROR');
UTL_FILE.FCLOSE(file_handle);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('other stuff');
UTL_FILE.FCLOSE(file_handle);
END;
아래와 같이 1023 byte 이상의 record임에도 잘 읽히는 것을 볼수 있다.
SQL> set serveroutput on
SQL> exec file_test
File size is : 1921
PL/SQL procedure successfully completed.
Reference Ducumment
<Note:1026951.6>
KOREAN Bulletin : 11532제품 : PL/SQL
작성날짜 : 2002-11-22
(8.0.5+) UTL_FILE PACKAGE사용시 READ_ERROR/WRITE_ERROR
===================================================
Problem Description
PLSQL에서 UTL_FILE package을 사용하여 text file를 read 하고 write할때
1023 byte 이상의 파일을 읽고 쓰고자 할때 다음의 ERROR을 만나게 된다.
UTL_FILE.WRITE_ERROR
UTL_FILE.READ_ERROR
User-defined exception
8.0.5 이전에는 UTL_FILE package을 사용하여 file을 다룰때 1023 byte이상의
데이터를 읽지 못하는 제한이 있었다. 하지만 8.0.5 이후에는 32,767 까지
사용 가능하다. 디폴트 최대 라인 싸이즈는 1023이지만 이것을 UTL_FILE.FOPEN
function에 MAX_LINESIZE 파라메터를 이용하여 해결 가능하다.
Default:
FUNCTION fopen(location IN VARCHAR2,
filename IN VARCHAR2,
open_mode IN VARCHAR2)
RETURN file_type;
최대 라인 싸이즈를 지정하고자 할때:
FUNCTION fopen(location IN VARCHAR2,
filename IN VARCHAR2,
open_mode IN VARCHAR2,
max_linesize IN BINARY_INTEGER)
RETURN file_type;
Solution Description:
MAX_LINESIZE 파라메터를 추가한 예이다.
CREATE OR REPLACE PROCEDURE file_test IS
file_handle UTL_FILE.FILE_TYPE; -- file handle of OS flat file
retrieved_buffer VARCHAR2(32767); -- Line retrieved from flat file
BEGIN
-- Open the same file to read from
file_handle :=
UTL_FILE.FOPEN('/home/ora920/product/9.2.0/utldir','myfile.txt','R',32767);
-- UTL_FILE.FOPEN('/home/ora920/product/9.2.0/utldir','myfile.txt','R'); -- READ_ERROR
-- Read a line from the file.
UTL_FILE.GET_LINE (file_handle, retrieved_buffer);
-- Print fetched line out to the SQL*PLUS prompt.
DBMS_OUTPUT.PUT_LINE('File size is : '||LENGTH(retrieved_buffer));
-- CLose the file.
UTL_FILE.FCLOSE(file_handle);
file_handle :=
UTL_FILE.FOPEN('/home/ora920/product/9.2.0/utldir','out.txt','W',32767);
-- UTL_FILE.FOPEN('/home/ora920/product/9.2.0/utldir','out.txt','W'); --WRITE_ERROR
UTL_FILE.PUT_LINE (file_handle, retrieved_buffer);
UTL_FILE.FCLOSE(file_handle);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('no_data_found');
UTL_FILE.FCLOSE(file_handle);
WHEN UTL_FILE.INVALID_PATH THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.INVALID_PATH');
UTL_FILE.FCLOSE(file_handle);
WHEN UTL_FILE.READ_ERROR THEN
DBMS_OUTPUT.PUT_LINE(' UTL_FILE.READ_ERROR');
UTL_FILE.FCLOSE(file_handle);
WHEN UTL_FILE.WRITE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.WRITE_ERROR');
UTL_FILE.FCLOSE(file_handle);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('other stuff');
UTL_FILE.FCLOSE(file_handle);
END;
아래와 같이 1023 byte 이상의 record임에도 잘 읽히는 것을 볼수 있다.
SQL> set serveroutput on
SQL> exec file_test
File size is : 1921
PL/SQL procedure successfully completed.
Reference Ducumment
<Note:1026951.6>
KOREAN Bulletin : 11532 -
UTL_FILE - Write to a file on a mapped network drive
Hello,
I am trying to get the UTL_FILE package to write a file to a mapped network drive on
Windows NT. We have the following definition in the init<SID>.ora file pointing to the
network drive:
UTL_FILE_DIR=v:\hawkrpt
Here is the code to write to the file:
CREATE OR REPLACE PACKAGE pkgUtlFileTest AS -- package spec
PROCEDURE isp_UtlFileTest ( vcDir IN VARCHAR2,
vcFileName IN VARCHAR2,
vcOpenType IN VARCHAR2,
vcMessage1 IN VARCHAR2 );
END pkgUtlFileTest;
CREATE OR REPLACE PACKAGE BODY pkgUtlFileTest AS -- package body
PROCEDURE isp_UtlFileTest ( vcDir IN VARCHAR2,
vcFileName IN VARCHAR2,
vcOpenType IN VARCHAR2,
vcMessage1 IN VARCHAR2 ) IS
-- vcDir is the utl file directory
-- vcOpenTpye is the open type a = append, w = write or r = read
-- vcFileName is any file name you want.
-- vcmessage is the entry you want placed into the file
vcUtlFile UTL_FILE.FILE_TYPE;
BEGIN
IF LOWER(vcOpenType) = 'a' OR LOWER(vcOpenType) = 'w' THEN
vcUtlFile := UTL_FILE.FOPEN(vcDir, vcFileName, vcOpenType);
UTL_FILE.PUT_LINE(vcUtlFile, vcMessage1);
UTL_FILE.FCLOSE(vcUtlFile);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('no_data_found');
UTL_FILE.FCLOSE_ALL ();
WHEN UTL_FILE.INVALID_PATH THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.INVALID_PATH');
UTL_FILE.FCLOSE_ALL ();
WHEN UTL_FILE.READ_ERROR THEN
DBMS_OUTPUT.PUT_LINE(' UTL_FILE.READ_ERROR');
UTL_FILE.FCLOSE_ALL ();
WHEN UTL_FILE.WRITE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.WRITE_ERROR');
UTL_FILE.FCLOSE_ALL ();
WHEN UTL_FILE.INVALID_OPERATION THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.INVALID_OPERATION');
UTL_FILE.FCLOSE_ALL ();
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('OTHER ERROR' );
UTL_FILE.FCLOSE_ALL ();
END isp_UtlFileTest;
END pkgUtlFileTest;
Here is the code to execute the stored procedure:
Begin
pkgUtlFileTest.ISP_UTLFILETEST('v:\hawkrpt','test.txt','w','This is a test');
End;
When the stored procedure is executed, the following error is returned:
UTL_FILE.INVALID_OPERATION
Can someone tell me how to get the UTL_FILE package to write a file to a network drive
on a Windows NT server?
Your help will be greatly appreciated!
MikeDid you restart the database after changing the init.ora parameter? Make sure that you have this new value in v$parameter view.
-
PL/SQL Mail Utility :: Binary/Ascii/Cc/Bcc/FileDump
I was working on my mail package and decided it was overtly complicated and
stripped it down to its bare bones. Here is what I came up with. Built on a previous
foundation of anothers work, I expanded the functionality considerably. You will find all
the features I think that you will need regarding a mail routine. There is also a nice
filedump routine included which makes very easy to create flat file dumps that you can
then attach to your emails. There are a few pre-reqs in using this though :
- 9iR2+
- DBA_Directories defined as opposed to utl_file paths
- Java Virtual Machine. Document can be found in Note :105472.1 Setup, Configuration,
and Use of the Java Virtual Machine on metalink.
As always, I welcome feedback and suggestions for improvement.
Barry C
http://www.myoracleportal.com
CREATE OR REPLACE PACKAGE mail_tools
AS
-- SENDMAIL supports variable message length with/without attachments
-- QUERY_SERVER allows you to check the status of a mail server to see if it is running
-- DUMP_FLATFILE allows you to dump flat file data from query submitted
-- Query Server to verify that the server is up and running.
-- Connects, Noop Command is executed, Disconnect.
-- GET_MAIL_ADDRESS is utilized in the SENDMAIL procedure
-- Table 100-3 SMTP Reply Codes
-- Reply Code
-- Meaning
-- 211 System status, or system help reply
-- 214 Help message [Information on how to use the receiver or the meaning of a particular non-standard command; this reply is useful only to the human user]
-- 220 <domain> Service ready
-- 221 <domain> Service closing transmission channel
-- 250 Requested mail action okay, completed
-- 251 User not local; will forward to <forward-path>
-- 252 OK, pending messages for node <node> started. Cannot VRFY user (e.g., info is not local), but will take message for this user and attempt delivery.
-- 253 OK, <messages> pending messages for node <node> started
-- 354 Start mail input; end with <CRLF>.<CRLF>
-- 355 Octet-offset is the transaction offset
-- 421 <domain> Service not available, closing transmission channel (This may be a reply to any command if the service knows it must shut down.)
-- 450 Requested mail action not taken: mailbox unavailable [for example, mailbox busy]
-- 451 Requested action aborted: local error in processing
-- 452 Requested action not taken: insufficient system storage
-- 453 You have no mail.
-- 454 TLS not available due to temporary reason. Encryption required for requested authentication mechanism.
-- 458 Unable to queue messages for node <node>
-- 459 Node <node> not allowed: reason
-- 500 Syntax error, command unrecognized (This may include errors such as command line too long.)
-- 501 Syntax error in parameters or arguments
-- 502 Command not implemented
-- 503 Bad sequence of commands
-- 504 Command parameter not implemented
-- 521 <Machine> does not accept mail.
-- 530 Must issue a STARTTLS command first. Encryption required for requested authentication mechanism.
-- 534 Authentication mechanism is too weak.
-- 538 Encryption required for requested authentication mechanism.
-- 550 Requested action not taken: mailbox unavailable [for , mailbox not found, no access]
-- 551 User not local; please try <forward-path>
-- 552 Requested mail action aborted: exceeded storage allocation
-- 553 Requested action not taken: mailbox name not allowed [for example, mailbox syntax incorrect]
-- 554 Transaction failed
This version allows for a customized seperator value. Using this function will allow you to
perform fixed width flat files by defining '' for no seperator and then RPAD/LPAD your columns as necessary.
Or use whatever seperator you wish to use, pipe, space, zeros, etc.
-- Example : This will generate a flat file which tabbed seperated
-- DECLARE
-- l_rows NUMBER;
-- l_sql VARCHAR2(32000);
-- BEGIN
-- l_sql := '
-- SELECT rpad(hou.NAME,70) udn_desc
-- , rpad(pcak.segment1,6) coid
-- , rpad(pcak.segment2,4) udn
-- FROM hr_all_organization_units hou, hr.pay_cost_allocation_keyflex pcak
-- WHERE TRUNC (SYSDATE) BETWEEN hou.date_from
-- AND NVL (hou.date_to, ''31-DEC-4712'')
-- AND pcak.cost_allocation_keyflex_id = hou.cost_allocation_keyflex_id
-- GROUP BY pcak.segment1, pcak.segment2, hou.NAME
-- ORDER BY 1, 2, 3
-- l_rows :=
-- dump_flatfile
-- (p_query =>
-- , p_dir => 'INTF000_TABLES'
-- , p_filename => 'test.csv'
-- , p_separator => ' ' -- <= tabbed 5 spaces between each column
-- , p_max_linesize => 32000
-- , p_mode => 'w' -- (w)rite mode or (a)ppend mode
-- END;
FUNCTION dump_flatfile (
p_query IN VARCHAR2
, p_dir IN VARCHAR2
, p_filename IN VARCHAR2
, p_separator IN VARCHAR2
, p_headers IN BOOLEAN DEFAULT FALSE
, p_trailing_separator IN BOOLEAN DEFAULT FALSE
, p_max_linesize IN NUMBER DEFAULT 32000
, p_mode IN VARCHAR2 DEFAULT 'w' )
RETURN NUMBER;
FUNCTION get_mail_address (
addr_list IN OUT VARCHAR2 )
RETURN VARCHAR2;
FUNCTION smtp_command (
command IN VARCHAR2
, ok IN VARCHAR2 DEFAULT '250'
, code OUT VARCHAR2
, DEBUG NUMBER DEFAULT 0 )
RETURN BOOLEAN;
FUNCTION query_server (
smtp_server VARCHAR2
, smtp_server_port PLS_INTEGER DEFAULT 25
, DEBUG NUMBER DEFAULT 0 )
RETURN BOOLEAN;
This procedure uses the UTL_TCP package to send an email message.
Up to three file names may be specified as attachments.
Written: Dave Wotton, 14/6/01 (Cambridge UK)
This script comes with no warranty or support. You are free to
modify it as you wish, but please retain an acknowledgement of
my original authorship.
Amended: Dave Wotton, 10/7/01
Now uses the utl_smtp.write_data() method to send the message,
eliminating the 32Kb message size constraint imposed by the
utl_smtp.data() procedure.
Amended: Dave Wotton, 20/7/01
Increased the v_line variable, which holds the file attachment
lines from 400 to 1000 bytes. This is the maximum supported
by RFC2821, The Simple Mail Transfer Protocol specification.
Amended: Dave Wotton, 24/7/01
Now inserts a blank line before each MIME boundary line. Some
mail-clients require this.
Amended: Dave Wotton, 4/10/01
Introduced a 'debug' parameter. Defaults to 0. If set to
non-zero then errors in opening files for attaching are
reported using dbms_output.put_line.
Include code to hand MS Windows style pathnames.
Amended: Barry Chase, 4/29/03
Added Priority to procedure and also X-Mailer ID.
Removed restrictions for email size limitation as well.
Emails are now formatted text messages, meaning you can
write your message in html format.
And finally, changed from using UTL_SMTP to UTL_TCP instead.
Amended: Barry Chase 11/10/2003
Added session timeout of 4 minutes to prevent hanging server connections
Amended: Barry Chase 12/04/2003
Added Date String so that it represents timezone of originating server
p_datestring
Amended: Barry Chase 03/01/2004
Added functionality to support binary attachments and remote attachments.
Its about 98% complete. Not work perfectly yet. Still trying to figure out
encoding to base64 or mime. Have a good start on it though.
04/12/2004
BCHASE :: Binary Support is fully functional now.
09/01/2005
BCHASE :: Modified attachment directories to use DBA_DIRECTORIES instead
of UTL_DIR in the Oracle initialization file.
02/22/2006
BCHASE :: Added variable length message email support (CLOB)
04/21/2006
BCHASE :: Expanded functionality to include Cc and Bcc
Also removed redundant calls from package. The single
mail_files command will handle flat files and binary files such as zip/pdf/etc.
SMTP Server and SMTP Server Port are parameters on the sendmail procedure now
as well.
Refer to http://home.clara.net/dwotton/dba/oracle_smtp.htm for more
details on the original source code.
For information on the enhanced mail_tools package as provided by Barry
Chase, refer to http://www.myoracleportal.com
/* Retrieves local binary file from database server.
* using DBMS_LOB commands and stores into BLOB
* return BLOB
FUNCTION get_local_binary_data (
p_dir IN VARCHAR2
, p_file IN VARCHAR2 )
RETURN BLOB;
/* Supports binary attachments and message of variable length. Uses CLOB.*/
-- DECLARE
-- t_blob BLOB;
-- BEGIN
-- Use the get_local_binary_data to collect your BLOB from the filesystem
-- or just load from a table where your BLOB is stored at, then just pass
-- as t_blob on the binaryfile parameter below. Remember to provide an
-- appropriate filename. Optionally, you can leave filename NULL and pass
-- the binaryfile parameter as EMPTY_BLOB() to send an email without an
-- attachment.
-- t_blob :=
-- mail_tools.get_local_binary_data
-- ( p_dir => 'INTF0047_TABLES'
--, p_file => 'test_file1.csv' );
-- mail_tools.sendmail
-- ( smtp_server => 'your.smtp.server'
-- , smtp_server_port => 25
-- , from_name => 'Email Address of Sender'
-- , to_name => 'list of TO email addresses separated by commas (,)'
-- , cc_name => 'list of CC email addresses separated by commas (,)'
-- , bcc_name => 'list of BCC email addresses separated by commas (,)'
-- , subject => 'Some brief Subject'
-- , MESSAGE => 'Your message goes here. Can include HTML code.'
-- , priority => '1-5 1 being the highest priority and 3 normal priority'
-- , filename => 'your.filename.txt or leave NULL'
-- , binaryfile => 'your blob is passed here otherwise leave as EMPTY_BLOB()
-- , DEBUG => 'Default is DBMS output otherwise pass a 1 to disable );
-- END;
PROCEDURE sendmail (
smtp_server VARCHAR2
, smtp_server_port PLS_INTEGER DEFAULT 25
, from_name VARCHAR2
, to_name VARCHAR2
, cc_name VARCHAR2 DEFAULT NULL
, bcc_name VARCHAR2 DEFAULT NULL
, subject VARCHAR2
, MESSAGE CLOB
, priority PLS_INTEGER DEFAULT NULL
, filename VARCHAR2 DEFAULT NULL
, binaryfile BLOB DEFAULT EMPTY_BLOB ( )
, DEBUG NUMBER DEFAULT 0 );
v_parm_value VARCHAR2 ( 4000 );
lbok BOOLEAN;
v_smtp_server VARCHAR2 ( 50 );
v_smtp_server_port NUMBER := 25;
crlf VARCHAR2 ( 10 ) := utl_tcp.crlf;
conn utl_tcp.connection;
p_debug_marker PLS_INTEGER := 0;
rc INTEGER;
p_from_name VARCHAR2 ( 100 );
p_to_name VARCHAR2 ( 4000 );
p_cc_name VARCHAR2 ( 4000 );
p_bcc_name VARCHAR2 ( 4000 );
p_subject VARCHAR2 ( 150 );
tx_timeout PLS_INTEGER := 240;
-- 240 Seconds (4 minutes);
p_datestring VARCHAR2 ( 100 )
:= 'Date: '
|| TO_CHAR ( SYSDATE, 'MM/DD/RR HH:MI AM' )
|| ' '
|| DBTIMEZONE
|| ' '
|| '(GMT'
|| DBTIMEZONE
|| ')';
-- Customize the signature that will appear in the email's MIME header.
-- Useful for versioning.
mailer_id CONSTANT VARCHAR2 ( 256 ) := 'Mailer by Oracle UTL_TCP';
max_base64_line_width CONSTANT PLS_INTEGER := 76 / 4 * 3;
END;
CREATE OR REPLACE PACKAGE BODY mail_tools
IS
PROCEDURE print_output (
p_message IN VARCHAR2 )
IS
BEGIN
dbms_output.put_line ( SUBSTR ( p_message
, 1
, 250 ));
IF LENGTH ( p_message ) > 250
THEN
dbms_output.put_line ( SUBSTR ( p_message
, 251
, 500 ));
END IF;
IF LENGTH ( p_message ) > 500
THEN
dbms_output.put_line ( SUBSTR ( p_message
, 501
, 750 ));
END IF;
IF LENGTH ( p_message ) > 750
THEN
dbms_output.put_line ( SUBSTR ( p_message
, 751
, 1000 ));
END IF;
EXCEPTION
WHEN OTHERS
THEN
NULL; -- Ignore errors... protect buffer overflow's etc.
END print_output;
FUNCTION dump_flatfile (
p_query IN VARCHAR2
, p_dir IN VARCHAR2
, p_filename IN VARCHAR2
, p_separator IN VARCHAR2
, p_headers IN BOOLEAN DEFAULT FALSE
, p_trailing_separator IN BOOLEAN DEFAULT FALSE
, p_max_linesize IN NUMBER DEFAULT 32000
, p_mode IN VARCHAR2 DEFAULT 'w' )
RETURN NUMBER
IS
l_output utl_file.file_type;
l_thecursor INTEGER DEFAULT dbms_sql.open_cursor;
l_columnvalue VARCHAR2 ( 4000 );
l_status INTEGER;
l_colcnt NUMBER DEFAULT 0;
l_cnt NUMBER DEFAULT 0;
l_separator VARCHAR2 ( 10 ) DEFAULT '';
l_line LONG;
l_desctbl dbms_sql.desc_tab;
v_sqlerrm VARCHAR2 ( 32000 );
l_mode CHAR ( 1 ) := 'w';
BEGIN
IF p_mode NOT IN ( 'w', 'a' )
THEN
l_mode := 'w';
ELSE
l_mode := p_mode;
END IF;
l_output := utl_file.fopen ( p_dir
, p_filename
, l_mode
, p_max_linesize );
dbms_sql.parse ( l_thecursor
, p_query
, dbms_sql.native );
dbms_sql.describe_columns ( l_thecursor
, l_colcnt
, l_desctbl );
FOR i IN 1 .. l_colcnt
LOOP
dbms_sql.define_column ( l_thecursor
, i
, l_columnvalue
, 4000 );
IF ( l_desctbl ( i ).col_type = 2 ) /* number type */
THEN
l_desctbl ( i ).col_max_len := l_desctbl ( i ).col_precision + 2;
ELSIF ( l_desctbl ( i ).col_type = 12 ) /* date type */
THEN
/* length of my date format */
l_desctbl ( i ).col_max_len := 20;
ELSIF ( l_desctbl ( i ).col_type = 8 ) /* LONG type */
THEN
l_desctbl ( i ).col_max_len := 2000;
END IF;
IF p_headers
THEN
utl_file.put ( l_output, l_separator || l_desctbl ( i ).col_name );
l_separator := p_separator;
END IF;
END LOOP;
IF p_trailing_separator
THEN
utl_file.put ( l_output, l_separator );
END IF;
IF p_headers
THEN
utl_file.new_line ( l_output );
END IF;
l_status := dbms_sql.EXECUTE ( l_thecursor );
LOOP
EXIT WHEN ( dbms_sql.fetch_rows ( l_thecursor ) <= 0 );
l_line := NULL;
l_separator := '';
FOR i IN 1 .. l_colcnt
LOOP
dbms_sql.COLUMN_VALUE ( l_thecursor
, i
, l_columnvalue );
IF NVL ( INSTR ( l_columnvalue, ',' ), 0 ) = 0
THEN
NULL;
ELSE
l_columnvalue := '"' || l_columnvalue || '"';
END IF;
utl_file.put ( l_output, l_separator || l_columnvalue );
l_separator := p_separator;
END LOOP;
IF p_trailing_separator
THEN
utl_file.put ( l_output, l_separator );
END IF;
utl_file.new_line ( l_output );
l_cnt := l_cnt + 1;
END LOOP;
dbms_sql.close_cursor ( l_thecursor );
utl_file.fclose ( l_output );
RETURN l_cnt;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
dbms_output.put_line ( 'NO_DATA_FOUND' );
utl_file.fclose ( l_output );
RETURN l_cnt;
WHEN utl_file.invalid_path
THEN
dbms_output.put_line ( 'UTL_FILE.INVALID_PATH' );
utl_file.fclose ( l_output );
RETURN l_cnt;
WHEN utl_file.read_error
THEN
dbms_output.put_line ( 'UTL_FILE.READ_ERROR' );
utl_file.fclose ( l_output );
RETURN l_cnt;
WHEN utl_file.write_error
THEN
dbms_output.put_line ( 'UTL_FILE.WRITE_ERROR' );
utl_file.fclose ( l_output );
RETURN l_cnt;
WHEN utl_file.invalid_mode
THEN
dbms_output.put_line ( 'UTL_FILE.INVALID_MODE' );
utl_file.fclose ( l_output );
RETURN l_cnt;
WHEN utl_file.invalid_filehandle
THEN
dbms_output.put_line ( 'UTL_FILE.INVALID_FILEHANDLE' );
utl_file.fclose ( l_output );
RETURN l_cnt;
WHEN utl_file.invalid_operation
THEN
dbms_output.put_line ( 'UTL_FILE.INVALID_OPERATION' );
utl_file.fclose ( l_output );
RETURN l_cnt;
WHEN utl_file.internal_error
THEN
dbms_output.put_line ( 'UTL_FILE.INTERNAL_ERROR' );
utl_file.fclose ( l_output );
RETURN l_cnt;
WHEN utl_file.invalid_maxlinesize
THEN
dbms_output.put_line ( 'UTL_FILE.INVALID_MAXLINESIZE' );
utl_file.fclose ( l_output );
RETURN l_cnt;
WHEN VALUE_ERROR
THEN
dbms_output.put_line ( 'UTL_FILE.VALUE_ERROR' );
utl_file.fclose ( l_output );
RETURN l_cnt;
WHEN OTHERS
THEN
hum_do.default_exception ( 'ERROR in dump_csv : ' );
utl_file.fclose ( l_output );
RETURN l_cnt;
END dump_flatfile;
-- Return the next email address in the list of email addresses, separated
-- by either a "," or a ";". The format of mailbox may be in one of these:
-- someone@some-domain
-- "Someone at some domain" <someone@some-domain>
-- Someone at some domain <someone@some-domain>
FUNCTION get_mail_address (
addr_list IN OUT VARCHAR2 )
RETURN VARCHAR2
IS
addr VARCHAR2 ( 256 );
i PLS_INTEGER;
FUNCTION lookup_unquoted_char (
str IN VARCHAR2
, chrs IN VARCHAR2 )
RETURN PLS_INTEGER
AS
c VARCHAR2 ( 5 );
i PLS_INTEGER;
len PLS_INTEGER;
inside_quote BOOLEAN;
BEGIN
inside_quote := FALSE;
i := 1;
len := LENGTH ( str );
WHILE ( i <= len )
LOOP
c := SUBSTR ( str
, i
, 1 );
IF ( inside_quote )
THEN
IF ( c = '"' )
THEN
inside_quote := FALSE;
ELSIF ( c = '\' )
THEN
i := i + 1;
-- Skip the quote character
END IF;
GOTO next_char;
END IF;
IF ( c = '"' )
THEN
inside_quote := TRUE;
GOTO next_char;
END IF;
IF ( INSTR ( chrs, c ) >= 1 )
THEN
RETURN i;
END IF;
<<next_char>>
i := i + 1;
END LOOP;
RETURN 0;
END;
BEGIN
addr_list := LTRIM ( addr_list );
i := lookup_unquoted_char ( addr_list, ',;' );
IF ( i >= 1 )
THEN
addr := SUBSTR ( addr_list
, 1
, i - 1 );
addr_list := SUBSTR ( addr_list, i + 1 );
ELSE
addr := addr_list;
addr_list := '';
END IF;
i := lookup_unquoted_char ( addr, '<' );
IF ( i >= 1 )
THEN
addr := SUBSTR ( addr, i + 1 );
i := INSTR ( addr, '>' );
IF ( i >= 1 )
THEN
addr := SUBSTR ( addr
, 1
, i - 1 );
END IF;
END IF;
RETURN addr;
END;
FUNCTION smtp_command (
command IN VARCHAR2
, ok IN VARCHAR2 DEFAULT '250'
, code OUT VARCHAR2
, DEBUG NUMBER DEFAULT 0 )
RETURN BOOLEAN
IS
response VARCHAR2 ( 3 );
p_output_message VARCHAR2 ( 255 );
len PLS_INTEGER;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
len := utl_tcp.write_line ( conn, command );
p_output_message := SUBSTR ( utl_tcp.get_line ( conn, TRUE )
, 1
, 255 );
response := SUBSTR ( p_output_message
, 1
, 3 );
p_output_message :=
SUBSTR ( command || ' - ' || p_output_message
, 1
, 255 );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
IF ( response <> ok )
THEN
code := response;
RETURN FALSE;
ELSE
code := response;
RETURN TRUE;
END IF;
EXCEPTION
WHEN OTHERS
THEN
p_output_message := SQLCODE || ' - ' || SQLERRM;
code := p_output_message;
RETURN FALSE;
END smtp_command;
FUNCTION query_server (
smtp_server VARCHAR2
, smtp_server_port PLS_INTEGER DEFAULT 25
, DEBUG NUMBER DEFAULT 0 )
RETURN BOOLEAN
IS
p_output_message VARCHAR2 ( 255 );
PRAGMA AUTONOMOUS_TRANSACTION;
err_noop EXCEPTION; -- SMTP code 250 not received
err_server_reject EXCEPTION;
-- SMTP code 421 means rejected
BEGIN
v_smtp_server := smtp_server;
v_smtp_server_port := smtp_server_port;
-- Open the SMTP connection ...
conn :=
utl_tcp.open_connection ( remote_host => v_smtp_server
, remote_port => v_smtp_server_port
, tx_timeout => tx_timeout );
----- OPEN SMTP PORT CONNECTION
rc := utl_tcp.write_line ( conn, 'HELO ' || v_smtp_server );
-- This will return a 250 OK response if your connection is valid
-- Initial handshaking ...
----- PERFORMS HANDSHAKING WITH SMTP SERVER
p_output_message := utl_tcp.get_line ( conn, TRUE );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
IF SUBSTR ( p_output_message
, 1
, 3 ) = '421'
THEN
RAISE err_server_reject;
END IF;
-- NOOP THE SERVER
rc := utl_tcp.write_line ( conn, 'NOOP' );
-- This will return a 250 OK response if your connection is valid
-- Initial handshaking ...
----- PERFORMS NOOP WITH SMTP SERVER
p_output_message := utl_tcp.get_line ( conn, TRUE );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
IF SUBSTR ( p_output_message
, 1
, 3 ) <> '250'
THEN
RAISE err_noop;
END IF;
rc := utl_tcp.write_line ( conn, 'QUIT' );
----- ENDS EMAIL TRANSACTION
BEGIN
FOR i_idx IN 1 .. 100
LOOP
p_output_message := utl_tcp.get_line ( conn, TRUE );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
END;
utl_tcp.close_connection ( conn ); ----- CLOSE SMTP PORT CONNECTION
RETURN TRUE;
EXCEPTION
WHEN err_server_reject
THEN
print_output ( 'ERROR -'
|| ' Server Rejected Connection ::'
|| ' SERVER_MSG := '
|| p_output_message );
RETURN FALSE;
WHEN err_noop
THEN
print_output ( 'ERROR -'
|| ' NOOP Check Failed ::'
|| ' SERVER_MSG := '
|| p_output_message );
utl_tcp.close_connection ( conn ); ----- CLOSE SMTP PORT CONNECTION
RETURN FALSE;
END query_server;
FUNCTION get_local_binary_data (
p_dir IN VARCHAR2
, p_file IN VARCHAR2 )
RETURN BLOB
IS
l_bfile BFILE;
l_data BLOB;
l_dbdir VARCHAR2 ( 100 ) := p_dir;
BEGIN
dbms_lob.createtemporary ( lob_loc => l_data
, CACHE => TRUE
, dur => dbms_lob.CALL );
l_bfile := BFILENAME ( l_dbdir, p_file );
dbms_lob.fileopen ( l_bfile, dbms_lob.file_readonly );
dbms_lob.loadfromfile ( l_data
, l_bfile
, dbms_lob.getlength ( l_bfile ));
dbms_lob.fileclose ( l_bfile );
RETURN l_data;
EXCEPTION
WHEN OTHERS
THEN
print_output ( 'Error during GET_LOCAL_BINARY_DATA :: '
|| SQLCODE
|| ' - '
|| SQLERRM );
dbms_lob.fileclose ( l_bfile );
RAISE;
END get_local_binary_data;
PROCEDURE attach_base64 (
conn IN OUT NOCOPY utl_tcp.connection
, DATA IN BLOB )
IS
i PLS_INTEGER;
len PLS_INTEGER;
l_result PLS_INTEGER;
l_buffer RAW ( 32767 );
l_pos INTEGER := 1;
l_blob_len INTEGER;
l_amount BINARY_INTEGER := 32767;
req utl_http.req;
resp utl_http.resp;
pdata RAW ( 200 );
BEGIN
-- Split the Base64-encoded attachment into multiple lines
-- In writing Base-64 encoded text following the MIME format below,
-- the MIME format requires that a long piece of data must be splitted
-- into multiple lines and each line of encoded data cannot exceed
-- 80 characters, including the new-line characters. Also, when
-- splitting the original data into pieces, the length of each chunk
-- of data before encoding must be a multiple of 3, except for the
-- last chunk. The constant MAX_BASE64_LINE_WIDTH
-- (76 / 4 * 3 = 57) is the maximum length (in bytes) of each chunk
-- of data before encoding.
l_blob_len := dbms_lob.getlength ( DATA );
WHILE l_pos < l_blob_len
LOOP
l_amount := max_base64_line_width;
dbms_lob.READ ( DATA
, l_amount
, l_pos
, l_buffer );
rc := utl_tcp.write_raw ( conn, utl_encode.base64_encode ( l_buffer ));
utl_tcp.FLUSH ( conn );
l_pos := l_pos + max_base64_line_width;
rc := utl_tcp.write_line ( conn, crlf );
END LOOP;
END attach_base64;
PROCEDURE sendmail (
smtp_server VARCHAR2
, smtp_server_port PLS_INTEGER DEFAULT 25
, from_name VARCHAR2
, to_name VARCHAR2
, cc_name VARCHAR2 DEFAULT NULL
, bcc_name VARCHAR2 DEFAULT NULL
, subject VARCHAR2
, MESSAGE CLOB
, priority PLS_INTEGER DEFAULT NULL
, filename VARCHAR2 DEFAULT NULL
, binaryfile BLOB DEFAULT EMPTY_BLOB ( )
, DEBUG NUMBER DEFAULT 0 )
IS
pos PLS_INTEGER := 1;
bytes_o_data CONSTANT PLS_INTEGER := 32767;
offset PLS_INTEGER := bytes_o_data;
msg_length CONSTANT PLS_INTEGER
:= dbms_lob.getlength ( MESSAGE );
v_line VARCHAR2 ( 32767 );
i BINARY_INTEGER;
v_slash_pos NUMBER;
my_recipients VARCHAR2 ( 32767 );
p_recipient_count PLS_INTEGER := 0;
p_output_message VARCHAR2 ( 2000 );
PRAGMA AUTONOMOUS_TRANSACTION;
err_server_reject EXCEPTION;
-- SMTP code 421 means rejected
err_message_send EXCEPTION; -- SMTP code must be 250
err_end_of_input EXCEPTION;
-- Used to signify last line of input retrieved
l_result PLS_INTEGER;
l_buffer_b RAW ( 32767 );
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
l_blob_len INTEGER;
l_blob BLOB;
g_debug BOOLEAN := TRUE;
i_base64 PLS_INTEGER;
len_base64 PLS_INTEGER;
BEGIN
v_smtp_server := smtp_server;
v_smtp_server_port := smtp_server_port;
l_blob := binaryfile;
-- Open the SMTP connection ...
conn :=
utl_tcp.open_connection ( remote_host => v_smtp_server
, remote_port => v_smtp_server_port
, tx_timeout => tx_timeout );
----- OPEN SMTP PORT CONNECTION
rc := utl_tcp.write_line ( conn, 'HELO ' || v_smtp_server );
-- Initial handshaking ...
----- PERFORMS HANDSHAKING WITH SMTP SERVER
p_output_message := utl_tcp.get_line ( conn, TRUE );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
IF SUBSTR ( p_output_message
, 1
, 3 ) = '421'
THEN
RAISE err_server_reject;
ELSE
-- DBMS_OUTPUT.put_line (UTL_TCP.get_line (conn, TRUE));
rc := utl_tcp.write_line ( conn, 'MAIL FROM: ' || from_name );
----- MBOX SENDING THE EMAIL
p_output_message := utl_tcp.get_line ( conn, TRUE );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
-- DBMS_OUTPUT.put_line (UTL_TCP.get_line (conn, TRUE));
-- rc := UTL_TCP.write_line (conn, 'RCPT TO: ' || to_name);
-- Specify recipient(s) of the email.
my_recipients := to_name;
WHILE ( my_recipients IS NOT NULL )
LOOP
BEGIN
rc :=
utl_tcp.write_line ( conn
, 'RCPT TO: '
|| get_mail_address ( my_recipients ));
p_recipient_count := p_recipient_count + 1;
END;
END LOOP;
-- DBMS_OUTPUT.put_line ('RCPT TO: COUNT ' || p_recipient_count);
----- MBOX RECV THE EMAIL
p_output_message := utl_tcp.get_line ( conn, TRUE );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
-- DBMS_OUTPUT.put_line (UTL_TCP.get_line (conn, TRUE));
-- rc := UTL_TCP.write_line (conn, 'RCPT TO: ' || cc_name);
-- Specify cc recipient(s) of the email.
my_recipients := cc_name;
WHILE ( my_recipients IS NOT NULL )
LOOP
BEGIN
rc :=
utl_tcp.write_line ( conn
, 'RCPT TO: '
|| get_mail_address ( my_recipients ));
p_recipient_count := p_recipient_count + 1;
END;
END LOOP;
-- DBMS_OUTPUT.put_line ('RCPT TO: COUNT ' || p_recipient_count);
----- MBOX RECV THE EMAIL
p_output_message := utl_tcp.get_line ( conn, TRUE );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
-- DBMS_OUTPUT.put_line (UTL_TCP.get_line (conn, TRUE));
-- rc := UTL_TCP.write_line (conn, 'RCPT TO: ' || bcc_name);
-- Specify bcc recipient(s) of the email.
my_recipients := bcc_name;
WHILE ( my_recipients IS NOT NULL )
LOOP
BEGIN
rc :=
utl_tcp.write_line ( conn
, 'RCPT TO: '
|| get_mail_address ( my_recipients ));
p_recipient_count := p_recipient_count + 1;
END;
END LOOP;
-- DBMS_OUTPUT.put_line ('RCPT TO: COUNT ' || p_recipient_count);
----- MBOX RECV THE EMAIL
p_output_message := utl_tcp.get_line ( conn, TRUE );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
-- DBMS_OUTPUT.put_line (UTL_TCP.get_line (conn, TRUE));
rc := utl_tcp.write_line ( conn, 'DATA' );
----- EMAIL MSG BODY START
p_output_message := utl_tcp.get_line ( conn, TRUE );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
-- DBMS_OUTPUT.put_line (UTL_TCP.get_line (conn, TRUE));
-- build the start of the mail message ...
rc := utl_tcp.write_line ( conn, p_datestring );
rc := utl_tcp.write_line ( conn, 'From: ' || from_name );
rc := utl_tcp.write_line ( conn, 'Subject: ' || subject );
rc := utl_tcp.write_line ( conn, 'To: ' || to_name );
IF cc_name IS NOT NULL
THEN
rc := utl_tcp.write_line ( conn, 'Cc: ' || cc_name );
END IF;
IF bcc_name IS NOT NULL
THEN
rc := utl_tcp.write_line ( conn, 'Bcc: ' || bcc_name );
END IF;
rc := utl_tcp.write_line ( conn, 'Mime-Version: 1.0' );
-- Set priority:
-- High Normal Low
-- 1 2 3 4 5
IF ( priority IS NOT NULL )
THEN
rc := utl_tcp.write_line ( conn, 'X-Priority: ' || priority );
END IF;
rc := utl_tcp.write_line ( conn, 'X-Mailer: ' || mailer_id );
rc :=
utl_tcp.write_line
( conn
, 'Content-Type: multipart/mixed; boundary="=_mixed 0052287A85256E75_="' );
rc := utl_tcp.write_line ( conn, '' );
rc :=
utl_tcp.write_line
( conn
, 'This is a Mime message, which your current mail reader may not' );
rc :=
utl_tcp.write_line
( conn
, 'understand. Parts of the message will appear as text. If the remainder' );
rc :=
utl_tcp.write_line
( conn
, 'appears as random characters in the message body, instead of as' );
rc :=
utl_tcp.write_line
( conn
, 'attachments, then you''ll have to extract these parts and decode them' );
rc := utl_tcp.write_line ( conn, 'manually.' );
rc := utl_tcp.write_line ( conn, '' );
rc := utl_tcp.write_line ( conn, '--=_mixed 0052287A85256E75_=' );
rc :=
utl_tcp.write_line ( conn
, 'Content-Type: text/html; charset=8859-1' );
rc := utl_tcp.write_line ( conn, '' );
rc := utl_tcp.write_line ( conn, '<html>' );
rc := utl_tcp.write_line ( conn, '<head>' );
rc :=
utl_tcp.write_line
( conn
, '<meta http-equiv="Content-Type" content="text/html;charset=8859-1">' );
rc := utl_tcp.write_line ( conn, '<title>' );
rc := utl_tcp.write_line ( conn, subject );
rc := utl_tcp.write_line ( conn, '</title>' );
rc := utl_tcp.write_line ( conn, '</head>' );
rc := utl_tcp.write_line ( conn, '<body>' );
WHILE pos < msg_length
LOOP
rc :=
utl_tcp.write_line ( conn
, dbms_lob.SUBSTR ( MESSAGE
, offset
, pos ));
pos := pos + offset;
offset := LEAST ( bytes_o_data, msg_length - offset );
END LOOP;
rc := utl_tcp.write_line ( conn, '<BR><BR>' );
rc := utl_tcp.write_line ( conn, '</body></html>' );
rc := utl_tcp.write_line ( conn, '' );
rc := utl_tcp.write_line ( conn, crlf );
-- Append the file BLOB ...
-- If the filename has been supplied ... it will fail if the BLOB is empty
IF filename IS NOT NULL
THEN
BEGIN
-- generate the MIME boundary line ...
rc :=
utl_tcp.write_line ( conn, '--=_mixed 0052287A85256E75_=' );
rc :=
utl_tcp.write_line
( conn
, 'Content-Type: application/octet-stream; name="'
|| filename
|| '"' );
rc :=
utl_tcp.write_line
( conn
, 'Content-Disposition: attachment; filename="'
|| filename
|| '"' );
rc :=
utl_tcp.write_line ( conn
, 'Content-Transfer-Encoding: base64' );
rc := utl_tcp.write_line ( conn, '' );
rc := utl_tcp.write_line ( conn, '' );
-- and append the file contents to the end of the message ...
-- Go get the file and the loop through blob and attach data
-- and append the file contents to the end of the message ...
attach_base64 ( conn => conn
, DATA => l_blob );
EXCEPTION
WHEN OTHERS
THEN
p_output_message :=
'Error in attaching file '
|| filename
|| ' :: '
|| SQLCODE
|| ' - '
|| SQLERRM;
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
RAISE err_message_send;
END;
END IF;
rc := utl_tcp.write_line ( conn, '' );
-- append the final boundary line ...
rc := utl_tcp.write_line ( conn, '' );
rc := utl_tcp.write_line ( conn, '--=_mixed 0052287A85256E75_=--' );
rc := utl_tcp.write_line ( conn, '' );
-- and close the SMTP connection ...
rc := utl_tcp.write_line ( conn, '.' );
----- EMAIL MESSAGE BODY END
p_output_message := utl_tcp.get_line ( conn, TRUE );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
-- DBMS_OUTPUT.put_line (UTL_TCP.get_line (conn, TRUE));
rc := utl_tcp.write_line ( conn, 'QUIT' );
----- ENDS EMAIL TRANSACTION
p_output_message := utl_tcp.get_line ( conn, TRUE );
-- Capture '.' Message sent dialog
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
BEGIN
FOR i_idx IN 1 .. 100
LOOP
p_output_message := utl_tcp.get_line ( conn, TRUE );
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
IF DEBUG = 1
THEN -- No Output
NULL;
ELSE -- Then DBMS_OUTPUT messages
print_output ( p_output_message );
END IF;
END;
END IF; -- err_server_reject
utl_tcp.close_connection ( conn ); ----- CLOSE SMTP PORT CONNECTION
EXCEPTION
WHEN err_message_send
THEN
print_output ( CHR ( 10 )
|| CHR ( 10 )
|| 'ERROR -'
|| ' Message was not submitted for delivery' );
print_output ( ' [FROM_NAME := ' || from_name || '] ' );
print_output ( ' [TO_NAME := ' || to_name || '] ' );
print_output ( ' [CC_NAME := ' || cc_name || '] ' );
print_output ( ' [BCC_NAME := ' || bcc_name || '] ' );
print_output ( ' [SUBJECT := ' || subject || '] ' );
print_output ( ' SERVER_MSG := ' || p_output_message );
utl_tcp.close_connection ( conn ); ----- CLOSE SMTP PORT CONNECTION
WHEN err_server_reject
THEN
print_output ( CHR ( 10 )
|| CHR ( 10 )
|| 'ERROR -'
|| ' Server Rejected Email' );
print_output ( ' [FROM_NAME := ' || from_name || '] ' );
print_output ( ' [TO_NAME := ' || to_name || '] ' );
print_output ( ' [CC_NAME := ' || cc_name || '] ' );
print_output ( ' [BCC_NAME := ' || bcc_name || '] ' );
print_output ( ' [SUBJECT := ' || subject || '] ' );
print_output ( ' SERVER_MSG := ' || p_output_message );
WHEN OTHERS
THEN
print_output ( CHR ( 10 )
|| CHR ( 10 )
|| 'ERROR :: '
|| SQLCODE
|| ' - '
|| SQLERRM );
print_output ( ' [FROM_NAME := ' || from_name || '] ' );
print_output ( ' [TO_NAME := ' || to_name || '] ' );
print_output ( ' [CC_NAME := ' || cc_name || '] ' );
print_output ( ' [BCC_NAME := ' || bcc_name || '] ' );
print_output ( ' [SUBJECT := ' || subject || '] ' );
print_output ( ' SERVER_MSG := ' || p_output_message );
END sendmail;
END;
/Perhaps your new SMTP server requires a more secure form of authentication than AUTH LOGIN. If you telnet to this new SMTP server on port 25 you should be issue the HELO or EHLO command to find out what AUTH mechanisms the server supports. You could then alter your code to use one of the supported authentication mechanisms.
-
Problem in using CLOB Data from a Data and exporting into File
Hi,
UTL_FILE Error Occured while using UTL_FILE with CLOB Data.
UTL_FILE: A write error occurred.
The Below Code is for reference:
DECLARE
C_AMOUNT CONSTANT BINARY_INTEGER := 32767;
L_BUFFER VARCHAR2(32767);
L_CHR10 PLS_INTEGER;
L_CLOBLEN PLS_INTEGER;
L_FHANDLER UTL_FILE.FILE_TYPE;
L_POS PLS_INTEGER := 1;
BEGIN
FILE_NAME:=UTL_FILE.FOPEN('EXPORT_DIR','EXPORT_FILE'||'.sql','W');
FOR C1_EXP IN (SELECT INSERT_STRING FROM EXPORTED_DUMP) LOOP
L_CLOBLEN := DBMS_LOB.GETLENGTH(C1_EXP.INSERT_STRING);
DBMS_OUTPUT.PUT_LINE('THE CLOB LEN '||L_CLOBLEN);
DBMS_OUTPUT.PUT_LINE('THE POSITION '||L_POS);
WHILE L_POS < L_CLOBLEN LOOP
L_BUFFER := DBMS_LOB.SUBSTR(C1_EXP.INSERT_STRING, C_AMOUNT, L_POS);
DBMS_OUTPUT.PUT_LINE('THE BUFFER IS '||L_BUFFER);
EXIT WHEN L_BUFFER IS NULL;
UTL_FILE.PUT_LINE(FILE_NAME, C1_EXP.INSERT_STRING);
L_POS := L_POS + LEAST(LENGTH(L_BUFFER)+1,c_amount);
END LOOP;
END LOOP;
UTL_FILE.FCLOSE(FILE_NAME);
EXCEPTION
WHEN UTL_FILE.INTERNAL_ERROR THEN
DBMS_OUTPUT.PUT_LINE ('UTL_FILE: An internal error occurred.');
UTL_FILE.FCLOSE_ALL;
WHEN UTL_FILE.INVALID_FILEHANDLE THEN
DBMS_OUTPUT.PUT_LINE ('UTL_FILE: The file handle was invalid.');
UTL_FILE.FCLOSE_ALL;
WHEN UTL_FILE.INVALID_MODE THEN
DBMS_OUTPUT.PUT_LINE ('UTL_FILE: An invalid open mode was given.');
UTL_FILE.FCLOSE_ALL;
WHEN UTL_FILE.INVALID_OPERATION THEN
DBMS_OUTPUT.PUT_LINE ('UTL_FILE: An invalid operation was attempted.');
UTL_FILE.FCLOSE_ALL;
WHEN UTL_FILE.INVALID_PATH THEN
DBMS_OUTPUT.PUT_LINE ('UTL_FILE: An invalid path was give for the file.');
UTL_FILE.FCLOSE_ALL;
WHEN UTL_FILE.READ_ERROR THEN
DBMS_OUTPUT.PUT_LINE ('UTL_FILE: A read error occurred.');
UTL_FILE.FCLOSE_ALL;
WHEN UTL_FILE.WRITE_ERROR THEN
DBMS_OUTPUT.PUT_LINE ('UTL_FILE: A write error occurred.');
UTL_FILE.FCLOSE_ALL;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('Some other error occurred.');
UTL_FILE.FCLOSE_ALL;
END;Hi user598986!
OK, I understood that there is a problem with your code. But please would you be so kindly to tell us here what error exactly happens (the errormessage). Mabay after that someone will be able to help you.
yours sincerely
Florian W.
P.S. If you enclose your code into tags it will be shown formated. -
How to count number of rows as well as the sum of a column in a procedure
Hi, i need to count the number of rows a sql returns in a procedure.
as well as i need to sum up a different column.
i need the following output:
count the number of rows output
and sum the total column
code:
procedure samba_extraction (p_errmsg IN out varchar2
,p_errcode IN out NUMBER
,p_filename in varchar2
,p_start_date varchar2
,p_end_date varchar2)
is
file_handle utl_file.file_type; -- file handle of os flat file
-- cursor to select the c_samba_resources
cursor c_samba is
select
lpad(h.contract_number,15,'0') contract_number
,h.short_description description
,h.attribute_category context_value
,h.attribute7 samba
,h.attribute8 samba_number
,h.start_date start_date
,h.end_date end_date
,h.sts_code active_inactive
,l.price_negotiated price
,l.tax_amount tax
,LTRIM(to_char((l.price_negotiated + l.tax_amount),'00000000.00')) total
from
oks_auth_headers_v h
,oks_auth_lines_v l
where h.id = l.chr_id
and ((h.start_date <= (p_end_date))
and (h.end_date >= (p_start_date)))
and h.attribute7 = 'SAMBA'
-- and h.sts_code = 'ACTIVE'
and ((h.attribute_category = 'SUBSCRIPTION.DURATION')
or (h.attribute_category = 'SUBSCRIPTION.VALUE')
or (h.attribute_category ='SUBSCRIPTION.QUANTITY'));
l_output varchar2(1000);
l_counter varchar2(11);
l_total varchar2(11);
l_filename varchar2(30);
begin
if p_filename IS NOT NULL then
-- l_batch_no := 'T';
l_filename := p_filename || '.txt';
-- open file to write into and obtain its file_handle.
file_handle := utl_file.fopen('/usr/tmp',l_filename,'W');
fnd_file.put_line(fnd_file.log,'The '|| l_filename||' file you have requested has been placed in the usr/tmp directory');
for l_info in c_samba
loop
-- l_output := null;
l_output := l_info.samba_number||'+'||l_info.total||l_info.contract_number;
utl_file.put_line(file_handle,l_output);
fnd_file.put_line(fnd_file.output, l_output);
dbms_output.put_line(l_output);
end loop;
else
p_errmsg := ('Please enter a filename for this file ');
write_log('UPDATE : ' ||p_errmsg);
end if;
-- close the file.
utl_file.fclose(file_handle);
exception
when no_data_found then
dbms_output.put_line('no_data_found');
utl_file.fclose(file_handle);
when utl_file.invalid_path then
dbms_output.put_line('UTL_FILE.INVALID_PATH');
utl_file.fclose(file_handle);
when utl_file.read_error then
dbms_output.put_line(' UTL_FILE.READ_ERROR');
utl_file.fclose(file_handle);
when utl_file.write_error then
dbms_output.put_line('UTL_FILE.WRITE_ERROR');
utl_file.fclose(file_handle);
when others then
dbms_output.put_line('other stuff');
utl_file.fclose(file_handle);
end samba_extraction;
end xx_samba;Hi,
Initialise one variable TOT_ROWS to 0.
Then in the for loop
tot_rows := tot_rows + +1 ;
so after for loop the value in the tot_rows will be the total records..
If u want it to get this value in the calling procedure of this , just declare tot_rows parameter as out parameter.
For sum of a column:
Initialise a variable sum_col to 0.
In the for loop
sum_col := sum_col+I_info.column_name
aprameter if u wish return this value as out..
I think this wil give u the o/p..
cheers,
Sivarama -
Create file, and export it to Network drive?
Ok. I have said this a few times - I am a java developer, and I am not that great at writing procedures, or function, but I try. Here is my situation. I would like a procedure that will query a table, and output this data into a file based on the queries. So for example. I would like to output something like this:
Report Name: Date:
Total Number of Proposals Missing PSR: 247
Proposals missing PSR pending credit check: 147
proposal id prospect id psr/document_number credit check description
======== ======== ================ ============= =============
818356 434345 fail credit check failed
634466 134556 fail credit check failed
etc.....
Proposals missing PSR but credit check passed: 46
proposal id prospect id psr/document_number credit check description
======== ======== ================ ============= =============
345345 345453 pass credit check passed
but missing psr
345653 864564 pass credit check failed
but missing psr
Proposals update with missing psr/document_number: 26
proposal id prospect id psr/document_number credit check description
======== ======== ================ ============= =============
778978 456473 345366 pass proposal id [778978]
updated with psr [345366]
944564 457756 64332 pass proposal id [944564]
updated with psr [345366]Now I would like to put this data in a file.
Once I get the file I would like to put it out on the network drive.
Now I have done this with java, but I think there is a way to do it in oracle.
I found this code
create or replace
PROCEDURE PR_OUTPUT_TOFILE IS
file_handle UTL_FILE.FILE_TYPE; -- file handle of OS flat file
prop_id NUMBER;
c1 NUMBER(9); -- C1 retrieved from testtab table
retrieved_buffer VARCHAR2(100); -- Line retrieved from flat file
BEGIN
-- Open file to write into and get its file_handle
file_handle :=
UTL_FILE.FOPEN('/tmp','myTestfile.txt','W');
-- Write a line of text out to the file.
UTL_FILE.PUT_LINE(file_handle, 'this is line 1 as a test');
-- Select the c1 from the sat_proposal table
SELECT c1 INTO prop_id FROM pon_user.sat_proposal
WHERE proposal_id > 838300 and proposal_id < 840000;
-- Using PUTF write text with the col1 argument out to the file.
UTL_FILE.PUTF (file_handle,
'This is the c1 %s.\n', prop_id);
-- Close the file.
UTL_FILE.FCLOSE(file_handle);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('no_data_found');
UTL_FILE.FCLOSE(file_handle);
WHEN UTL_FILE.INVALID_PATH THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.INVALID_PATH');
UTL_FILE.FCLOSE(file_handle);
WHEN UTL_FILE.WRITE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.WRITE_ERROR');
UTL_FILE.FCLOSE(file_handle);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('other stuff');
UTL_FILE.FCLOSE(file_handle);
END PR_OUTPUT_TOFILE;and it puts a file out their on the oracle server in the /tmp directory that I am running from. Is there a way to get a network connection and upload this file to the mapped drive?
you know like \\nvlplace\SAT\Reports\etc
orozcomorozcom,
Are you running on a unix/linux server or a windows server?
If you are running on a Linux or unix server, then I would look at SAMBA mapping and mounting the SAMBA drive to a mount point and then you can properly reference it.
If you are running on Windows, you will need to go to underlying service in the services manager and change the running service from the system account to the Oracle NT account that has network privileges. Restart the service and then you can reference network drives from the database.
Take caution and read your documentation, review security concerns, before changing the Oracle background service. I have done it before, but I do not know if it is supported of hand.
Thanks,
Bryan -
I created apackage to
1) Explode BOM model based on Demand data
2) Save into temp table
3) Adding additional info from original records
This involves 400,000 + records and before this it tooks around 3-4 hours
but now it seems running forever. Please help me to tune this
CREATE OR REPLACE PACKAGE ZZ_SCHEDULED_BOMEXPLODE
AS
PROCEDURE main (
errbuf OUT VARCHAR2,
retcode OUT VARCHAR2--,
END ZZ_SCHEDULED_BOMEXPLODE;
CREATE OR REPLACE PACKAGE BODY ZZ_SCHEDULED_BOMEXPLODE
AS
PROCEDURE main (
errbuf OUT VARCHAR2,
retcode OUT VARCHAR2--,
IS
v_explodemodel VARCHAR2(30);
v_explodemodel_id NUMBER;
v_plan_id NUMBER;
v_qty_rate NUMBER;
v_mrp_date DATE;
v_comp_id NUMBER;
v_item_cost NUMBER;
l_assembly_item_id NUMBER;
l_organization_id NUMBER := 101;
l_group_id NUMBER := -1111;
l_session_id NUMBER := -1111;
l_levels_to_explode NUMBER := 60;
l_revision_date DATE := null;
l_err_msg VARCHAR2(80);
l_err_code NUMBER;
CURSOR c_isp_models IS
SELECT DISTINCT mov.ITEM_SEGMENTS,mov.PLAN_ID, sum(mov.QUANTITY_RATE), trunc(mov.CREATION_DATE)
FROM MSC_ORDERS_V mov,msc_plans mp
WHERE mov.ORDER_TYPE_TEXT IN ('Manual MDS')
AND mov.CATEGORY_SET_ID = 13
AND mov.PLAN_ID in (66,366,387,406,587,288)
and mov.quantity_rate <> 0
and mov.order_number='MDS_MRP'
and mov.PLAN_ID = mp.PLAN_ID
GROUP BY mov.ITEM_SEGMENTS, mov.PLAN_ID, trunc(mov.CREATION_DATE);
CURSOR c_frozen_cost IS
select msi.inventory_item_id, cic.item_cost from cst_item_costs cic, mtl_system_items_b msi
where msi.organization_id = 101
and cic.cost_type_id = 1
and msi.inventory_item_id in (select distinct(component_item_id) from zz_bom_explosion_temp_save)
and cic.organization_id = msi.organization_id
and cic.inventory_item_id = msi.inventory_item_id;
BEGIN
EXECUTE IMMEDIATE 'drop table APPS.ZZ_BOM_EXPLOSION_TEMP_SAVE';
EXECUTE IMMEDIATE 'create table APPS.ZZ_BOM_EXPLOSION_TEMP_SAVE as select * from APPS.BOM_EXPLOSION_TEMP';
EXECUTE IMMEDIATE 'delete from APPS.ZZ_BOM_EXPLOSION_TEMP_SAVE';
EXECUTE IMMEDIATE 'alter table APPS.ZZ_BOM_EXPLOSION_TEMP_SAVE add(PLAN_ID NUMBER, QTY_RATE NUMBER, MRP_DATE DATE)';
COMMIT;
-- Starting Explosion prosess
OPEN c_isp_models;
LOOP
FETCH c_isp_models INTO v_explodemodel, v_plan_id, v_qty_rate, v_mrp_date; -- Updated on 2nd Mar 2007
--FETCH c_isp_models INTO v_explodemodel;
EXIT WHEN c_isp_models%NOTFOUND;
select inventory_item_id into v_explodemodel_id
from mtl_system_items_b
where segment1 = v_explodemodel
and organization_id = l_organization_id;
fnd_file.put_line (fnd_file.LOG, v_explodemodel);
select bom_explosion_temp_s.nextval into l_group_id from dual;
bompexpl.exploder_userexit
0,
l_organization_id,
1,
l_group_id,
l_session_id,
l_levels_to_explode,
1,
1,
2,
3,
2,
1,
2,
1,
v_explodemodel_id,
l_revision_date,
l_err_msg,
l_err_code
COMMIT;
insert into ZZ_BOM_EXPLOSION_TEMP_SAVE
select
TOP_BILL_SEQUENCE_ID,
BILL_SEQUENCE_ID,
ORGANIZATION_ID,
COMPONENT_SEQUENCE_ID,
COMPONENT_ITEM_ID,
PLAN_LEVEL,
EXTENDED_QUANTITY,
SORT_ORDER,
REQUEST_ID,
PROGRAM_APPLICATION_ID,
PROGRAM_ID,
PROGRAM_UPDATE_DATE,
GROUP_ID,
SESSION_ID,
SELECT_FLAG,
SELECT_QUANTITY,
EXTEND_COST_FLAG,
TOP_ALTERNATE_DESIGNATOR,
TOP_ITEM_ID,
CONTEXT,
ATTRIBUTE1,
ATTRIBUTE2,
ATTRIBUTE3,
ATTRIBUTE4,
ATTRIBUTE5,
ATTRIBUTE6,
ATTRIBUTE7,
ATTRIBUTE8,
ATTRIBUTE9,
ATTRIBUTE10,
ATTRIBUTE11,
ATTRIBUTE12,
ATTRIBUTE13,
ATTRIBUTE14,
ATTRIBUTE15,
HEADER_ID,
LINE_ID,
LIST_PRICE,
SELLING_PRICE,
COMPONENT_YIELD_FACTOR,
ITEM_COST,
INCLUDE_IN_ROLLUP_FLAG,
BASED_ON_ROLLUP_FLAG,
ACTUAL_COST_TYPE_ID,
COMPONENT_QUANTITY,
SHRINKAGE_RATE,
SO_BASIS,
OPTIONAL,
MUTUALLY_EXCLUSIVE_OPTIONS,
CHECK_ATP,
SHIPPING_ALLOWED,
REQUIRED_TO_SHIP,
REQUIRED_FOR_REVENUE,
INCLUDE_ON_SHIP_DOCS,
INCLUDE_ON_BILL_DOCS,
LOW_QUANTITY,
HIGH_QUANTITY,
PICK_COMPONENTS,
PRIMARY_UOM_CODE,
PRIMARY_UNIT_OF_MEASURE,
BASE_ITEM_ID,
ATP_COMPONENTS_FLAG,
ATP_FLAG,
BOM_ITEM_TYPE,
PICK_COMPONENTS_FLAG,
REPLENISH_TO_ORDER_FLAG,
SHIPPABLE_ITEM_FLAG,
CUSTOMER_ORDER_FLAG,
INTERNAL_ORDER_FLAG,
CUSTOMER_ORDER_ENABLED_FLAG,
INTERNAL_ORDER_ENABLED_FLAG,
SO_TRANSACTIONS_FLAG,
MTL_TRANSACTIONS_ENABLED_FLAG,
STOCK_ENABLED_FLAG,
DESCRIPTION,
ASSEMBLY_ITEM_ID,
CONFIGURATOR_FLAG,
PRICE_LIST_ID,
ROUNDING_FACTOR,
PRICING_CONTEXT,
PRICING_ATTRIBUTE1,
PRICING_ATTRIBUTE2,
PRICING_ATTRIBUTE3,
PRICING_ATTRIBUTE4,
PRICING_ATTRIBUTE5,
PRICING_ATTRIBUTE6,
PRICING_ATTRIBUTE7,
PRICING_ATTRIBUTE8,
PRICING_ATTRIBUTE9,
PRICING_ATTRIBUTE10,
PRICING_ATTRIBUTE11,
PRICING_ATTRIBUTE12,
PRICING_ATTRIBUTE13,
PRICING_ATTRIBUTE14,
PRICING_ATTRIBUTE15,
COMPONENT_CODE,
LOOP_FLAG,
INVENTORY_ASSET_FLAG,
PLANNING_FACTOR,
OPERATION_SEQ_NUM,
PARENT_BOM_ITEM_TYPE,
WIP_SUPPLY_TYPE,
ITEM_NUM,
EFFECTIVITY_DATE,
DISABLE_DATE,
IMPLEMENTATION_DATE,
SUPPLY_SUBINVENTORY,
SUPPLY_LOCATOR_ID,
COMPONENT_REMARKS,
CHANGE_NOTICE,
OPERATION_LEAD_TIME_PERCENT,
REXPLODE_FLAG,
COMMON_BILL_SEQUENCE_ID,
PRIMARY_PATH_FLAG,
AUTO_REQUEST_MATERIAL,
v_plan_id,
v_qty_rate,
v_mrp_date
from BOM_EXPLOSION_TEMP;
delete from BOM_EXPLOSION_TEMP;
commit;
END LOOP;
CLOSE c_isp_models;
--insert into ZZ_BOM_EXPLOSION_TEMP_SAVE select * from BOM_EXPLOSION_TEMP;
COMMIT;
-- Ending of Explosion proxess
-- Updated on 5th Mar 2007 to populate missing frozen item cost
OPEN c_frozen_cost;
LOOP
FETCH c_frozen_cost INTO v_comp_id, v_item_cost;
EXIT WHEN c_frozen_cost%NOTFOUND;
update zz_bom_explosion_temp_save
set item_cost = v_item_cost
where component_item_id = v_comp_id;
commit;
END LOOP;
CLOSE c_frozen_cost;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No_data_found');
WHEN UTL_FILE.INVALID_PATH THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.INVALID_PATH');
WHEN UTL_FILE.READ_ERROR THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.READ_ERROR');
WHEN UTL_FILE.WRITE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.WRITE_ERROR');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Other stuff');
END main;
END ZZ_SCHEDULED_BOMEXPLODE;
/Statistics have been updated? Any missing indices? Any explain plans / tkprof outputs on this one?
Why don't you put
select inventory_item_id into v_explodemodel_id
from mtl_system_items_b
where segment1 = v_explodemodel
and organization_id = l_organization_id;inside c_isp_models?
BULK processing that cursor could also be an option.
Those were the thoughts that came up first when I saw your code.
C. -
Hallo,
I am trying to generate xml from oracle. I tried through differrent approaches and i have finally ended up using XSU for PL/SQL, generating XML with DBMS_XMLQuery().
The stored procedure i am running from Application Developement SQLPlus Worksheet follows right after. I use it to generate XML from tables holding spatial polygon information as well.It works just fine for tables containing up to 30-40 records but produces not well-formed xml documents for tables whose records exceed this number.In such cases, it repeats previously extracted row tags. For example after tag <row num="41"> it goes on with <row num="30"> again, until it reaches <row num="41"> again and goes on.Does anyone have any idea about the cause of this
problem?
At first i thought it might be a memory problem so i tried increasing the shared pool size from Initialization parameters from approximately 50 MB to 100 MB, but Oracle responded with an error:applying dynamic parameters failed ORA-02097-This parameter cannot be modified because there is inneficient memory for increasing shared pool size parameter.I also tried increasing memory used by applications from performance options - virtual memory but nothing changed.It still does not accept the modification of shared pool size parameter, producing the same error.
I am working on a PC with Windows 2000, 29 Gb free hard disk and 256 ram. Can the the operating system or the computer memory be the cause??
The stored PL/SQL procedure:
(tablename varchar2)
as
queryCtx DBMS_XMLquery.ctxType;
result CLOB;
errorNum NUMBER;
errorMsg VARCHAR2(200);
PROCEDURE printClobOut(result IN OUT NOCOPY CLOB, flname IN varchar2) IS
xmlstr varchar2(32767);
line varchar2(2000);
offset number;
counter number;
flag boolean;
filename SYS.UTL_FILE.FILE_TYPE;
PROCEDURE recNgo(str IN VARCHAR2) IS
BEGIN
DBMS_OUTPUT.PUT_LINE('UTL_FILE error'||str);
UTL_FILE.FCLOSE(filename);
END;
BEGIN
filename:=SYS.UTL_FILE.FOPEN('c:\TEMP', flname, 'W');
offset:=1;
flag:=false;
loop
xmlstr:=dbms_lob.SUBSTR(result,32767,offset);
exit when xmlstr is null;
DBMS_OUTPUT.PUT_LINE(DBMS_LOB.GETLENGTH(result));
loop
exit when xmlstr is null;
line:=substr(xmlstr,1,instr(xmlstr,chr(10))-1);
if instr(xmlstr,chr(10))=0 then
line:=xmlstr;
flag:=true;
else
flag:=false;
end if;
if flag then
SYS.UTL_FILE.PUT(filename, line);
else
SYS.UTL_FILE.PUT_LINE(filename, line);
end if;
xmlstr:=substr(xmlstr,instr(xmlstr,chr(10))+1);
if flag then
xmlstr:=null;
end if;
end loop;
offset:=offset+16383;
end loop;
UTL_FILE.FCLOSE(filename);
EXCEPTION
WHEN UTL_FILE.INVALID_PATH THEN recNgo('invalid_path');
WHEN UTL_FILE.INVALID_MODE THEN recNgo('invalid_mode');
WHEN UTL_FILE.INVALID_FILEHANDLE THEN recNgo('invalid_filehandle');
WHEN UTL_FILE.INVALID_OPERATION THEN recNgo('invalid_operation');
WHEN UTL_FILE.READ_ERROR THEN recNgo('read_error');
WHEN UTL_FILE.WRITE_ERROR THEN recNgo('write_error');
WHEN UTL_FILE.INTERNAL_ERROR THEN recNgo('internal_error');
END;
begin
queryCtx:=DBMS_XMLQUERY.newContext('select * from '||tablename);
DBMS_XMLquery.setRaiseException(queryCtx, true);
DBMS_XMLquery.setRaiseNoRowsException(queryCtx, true);
result:=DBMS_XMLQUERY.getXML(queryCtx);
printClobOut(result, tablename||'.xml');
DBMS_XMLQUERY.closeContext(queryCtx);
exception
when others then
DBMS_XMLquery.getExceptionContent(queryCtx, errorNum, errorMsg);
dbms_output.put_line('Exception caught '||TO_CHAR(errorNum)||errorMsg);
end;
Is there anything wrong with the code?
Another problem that i am facing, is that i want my generated xml, to start with the xml declaration and a specific encoding. To be more specific, i need the first line of the generated xml to be like:
<?xml version="1.0" encoding="ISO-8859-7"?>
I need this in order for the greek characters to get recognised by the used parser.The problem is that i haven't found a way to produce the encoding attribute as well, through the PL/SQL procedure.Any suggestions??
Regards
Manousos
AthensEric, I cannot find a specific documentation reference to guarantee this, but in every sample I've run, the result has been in the native "order" of the collection if an ORDER BY clause is not specified in the query.
-
Help to optimize file load (clobs involved) via pl/sql
Hello.
I have written a procedure that loads a table from a file, this table has five clob columns and the file has 7024 rows (which means 5*7024 clobs are loaded in the table). Every record in the file ends in "\r\n\r\n" (I mean chr(13)||chr(10)||chr(13)||chr(10))
The complete load of the file has taken around 5 hours, I wonder if the procedure can be optimized as I am new to the dmbs_lob package.
The procuedure is called carga_t_pets_respuestas_emisor and belongs to a package called carga_tablas.
I load the whole file in a temporary clob and then I get every line into another temporary clob (I look for the end of record separator (chr(13)||chr(10)||chr(13)||chr(10)) for each line).
Here I post the whole body of tha package (the code is long because the table has 25 columns, but the treatement is the same for every column):
CREATE OR REPLACE PACKAGE BODY MAPV4_MIGRATION.carga_tablas
AS
NAME: CARGA_TABLAS
PURPOSE:
REVISIONS:
Ver Date Author Description
1.0 07/12/2009 1. Created this package.
PROCEDURE tratar_linea (
p_lin IN CLOB,
contlin IN INTEGER,
p_log IN UTL_FILE.file_type,
msg IN OUT VARCHAR2
IS
v_id_peticion t_peticiones_respuestas_emisor.id_peticion%TYPE;
v_id_transaccion t_peticiones_respuestas_emisor.id_transaccion%TYPE;
v_fecha_recepcion VARCHAR2 (50);
v_cod_certificado t_peticiones_respuestas_emisor.cod_certificado%TYPE;
v_cif_requirente t_peticiones_respuestas_emisor.cif_requirente%TYPE;
v_num_elementos t_peticiones_respuestas_emisor.num_elementos%TYPE;
v_fichero_peticion t_peticiones_respuestas_emisor.fichero_peticion%TYPE;
v_ter t_peticiones_respuestas_emisor.ter%TYPE;
v_fecha_ini_proceso VARCHAR2 (50);
v_fecha_fin_proceso VARCHAR2 (50);
v_fichero_respuesta t_peticiones_respuestas_emisor.fichero_respuesta%TYPE;
v_cn t_peticiones_respuestas_emisor.cn%TYPE;
v_contador_enviados t_peticiones_respuestas_emisor.contador_enviados%TYPE;
v_signature t_peticiones_respuestas_emisor.signature%TYPE;
v_caducidad VARCHAR2 (50);
v_descompuesta t_peticiones_respuestas_emisor.descompuesta%TYPE;
v_estado t_peticiones_respuestas_emisor.estado%TYPE;
v_error t_peticiones_respuestas_emisor.error%TYPE;
v_cod_municipio_volante t_peticiones_respuestas_emisor.cod_municipio_volante%TYPE;
v_peticion_solicitud_respuesta t_peticiones_respuestas_emisor.peticion_solicitud_respuesta%TYPE;
v_id_fabricante_ve t_peticiones_respuestas_emisor.id_fabricante_ve%TYPE;
v_fecha_respuesta VARCHAR2 (50);
v_codigo_error t_peticiones_respuestas_emisor.codigo_error%TYPE;
v_serial t_peticiones_respuestas_emisor.serial%TYPE;
v_inicio_col INTEGER;
v_fin_col INTEGER;
v_timestamp_format VARCHAR2 (50)
:= 'yyyy-mm-dd hh24:mi:ss';
BEGIN
UTL_FILE.put_line (p_log, 'INICIO tratar_linea');
-- Columna ID_PETICION
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', 1, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', 1, 1) - 1;
UTL_FILE.put_line (p_log,
'v_inicio_col: '
|| v_inicio_col
|| '; v_fin_col: '
|| v_fin_col
UTL_FILE.fflush (p_log);
v_id_peticion :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_id_peticion: ' || v_id_peticion);
UTL_FILE.fflush (p_log);
-- Columna ID_TRANSACCION
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_id_transaccion :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_id_transaccion: ' || v_id_transaccion);
UTL_FILE.fflush (p_log);
-- Columna FECHA_RECEPCION
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_fecha_recepcion :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_fecha_recepcion: ' || v_fecha_recepcion);
UTL_FILE.fflush (p_log);
-- Columna COD_CERTIFICADO
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_cod_certificado :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_cod_certificado: ' || v_cod_certificado);
UTL_FILE.fflush (p_log);
-- Columna CIF_REQUIRENTE
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_cif_requirente :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_cif_requirente: ' || v_cif_requirente);
UTL_FILE.fflush (p_log);
-- Columna NUM_ELEMENTOS
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_num_elementos :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_num_elementos: ' || v_num_elementos);
UTL_FILE.fflush (p_log);
-- Columna FICHERO_PETICION
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_fichero_peticion :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log,
'Longitud v_fichero_peticion: '
|| DBMS_LOB.getlength (v_fichero_peticion)
UTL_FILE.fflush (p_log);
--UTL_FILE.put_line (p_log, 'v_fichero_peticion: ' || v_fichero_peticion);
-- Columna TER
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_ter :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_ter: ' || v_ter);
UTL_FILE.fflush (p_log);
-- Columna FECHA_INI_PROCESO
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_fecha_ini_proceso :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log,
'v_fecha_ini_proceso: ' || v_fecha_ini_proceso);
UTL_FILE.fflush (p_log);
-- Columna FECHA_FIN_PROCESO
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_fecha_fin_proceso :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log,
'v_fecha_fin_proceso: ' || v_fecha_fin_proceso);
UTL_FILE.fflush (p_log);
-- Columna FICHERO_RESPUESTA
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_fichero_respuesta :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log,
'Longitud v_fichero_respuesta: '
|| DBMS_LOB.getlength (v_fichero_respuesta)
UTL_FILE.fflush (p_log);
--UTL_FILE.put_line (p_log,
-- 'v_fichero_respuesta: ' || v_fichero_respuesta);
-- Columna CN
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_cn :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_cn: ' || v_cn);
UTL_FILE.fflush (p_log);
-- Columna CONTADOR_ENVIADOS
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_contador_enviados :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log,
'v_CONTADOR_ENVIADOS: ' || v_contador_enviados);
UTL_FILE.fflush (p_log);
-- Columna SIGNATURE
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_signature :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log,
'Longitud v_signature: '
|| DBMS_LOB.getlength (v_signature)
UTL_FILE.fflush (p_log);
--UTL_FILE.put_line (p_log, 'v_SIGNATURE: ' || v_signature);
-- Columna CADUCIDAD
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_caducidad :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_CADUCIDAD: ' || v_caducidad);
UTL_FILE.fflush (p_log);
-- Columna DESCOMPUESTA
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_descompuesta :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_DESCOMPUESTA: ' || v_descompuesta);
UTL_FILE.fflush (p_log);
-- Columna ESTADO
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_estado :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_ESTADO: ' || v_estado);
UTL_FILE.fflush (p_log);
-- Columna ERROR
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_error :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log,
'Longitud v_ERROR: ' || DBMS_LOB.getlength (v_error)
UTL_FILE.fflush (p_log);
--UTL_FILE.put_line (p_log, 'v_ERROR: ' || v_error);
-- Columna COD_MUNICIPIO_VOLANTE
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_cod_municipio_volante :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log,
'v_COD_MUNICIPIO_VOLANTE: '
|| v_cod_municipio_volante
UTL_FILE.fflush (p_log);
-- Columna PETICION_SOLICITUD_RESPUESTA
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_peticion_solicitud_respuesta :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log,
'Longitud v_PETICION_SOLICITUD_RESPUESTA: '
|| DBMS_LOB.getlength (v_peticion_solicitud_respuesta)
UTL_FILE.fflush (p_log);
--UTL_FILE.put_line (p_log,
-- 'v_PETICION_SOLICITUD_RESPUESTA: '
-- || v_peticion_solicitud_respuesta
-- Columna ID_FABRICANTE_VE
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_id_fabricante_ve :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_ID_FABRICANTE_VE: ' || v_id_fabricante_ve);
UTL_FILE.fflush (p_log);
-- Columna FECHA_RESPUESTA
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_fecha_respuesta :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_FECHA_RESPUESTA: ' || v_fecha_respuesta);
UTL_FILE.fflush (p_log);
-- Columna CODIGO_ERROR
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_codigo_error :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_CODIGO_ERROR: ' || v_codigo_error);
-- Columna SERIAL
UTL_FILE.fflush (p_log);
v_inicio_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 1) + 1;
--La ultima columna puede no llevar '",' sino '"'
--v_fin_col := DBMS_LOB.INSTR (p_lin, '",', v_fin_col + 2, 1) - 1;
v_fin_col := DBMS_LOB.INSTR (p_lin, '"', v_fin_col + 2, 2) - 1;
--DBMS_OUTPUT.put_line ( 'v_inicio_col: '
-- || v_inicio_col
-- || '; v_fin_col: '
-- || v_fin_col
v_serial :=
DBMS_LOB.SUBSTR (p_lin, v_fin_col - v_inicio_col + 1, v_inicio_col);
UTL_FILE.put_line (p_log, 'v_SERIAL: ' || v_serial);
UTL_FILE.fflush (p_log);
-- Insercion en tabla
INSERT INTO t_histo_ptcions_rspstas_emisor
(id_peticion, id_transaccion,
fecha_recepcion,
cod_certificado, cif_requirente, num_elementos,
fichero_peticion, ter,
fecha_ini_proceso,
fecha_fin_proceso,
fichero_respuesta, cn, contador_enviados,
signature,
caducidad,
descompuesta, estado, error,
cod_municipio_volante, peticion_solicitud_respuesta,
id_fabricante_ve,
fecha_respuesta,
codigo_error, serial
VALUES (v_id_peticion, v_id_transaccion,
TO_TIMESTAMP (v_fecha_recepcion, v_timestamp_format),
v_cod_certificado, v_cif_requirente, v_num_elementos,
v_fichero_peticion, v_ter,
TO_TIMESTAMP (v_fecha_ini_proceso, v_timestamp_format),
TO_TIMESTAMP (v_fecha_fin_proceso, v_timestamp_format),
v_fichero_respuesta, v_cn, v_contador_enviados,
v_signature,
TO_TIMESTAMP (v_caducidad, v_timestamp_format),
v_descompuesta, v_estado, v_error,
v_cod_municipio_volante, v_peticion_solicitud_respuesta,
v_id_fabricante_ve,
TO_TIMESTAMP (v_fecha_respuesta, v_timestamp_format),
v_codigo_error, v_serial
-- Se valida la transaccion
--COMMIT;
UTL_FILE.put_line (p_log, 'FIN tratar_linea');
EXCEPTION
WHEN OTHERS
THEN
msg := SQLERRM;
--ROLLBACK;
RAISE;
END;
PROCEDURE carga_t_pets_respuestas_emisor (
p_dir IN VARCHAR2,
p_filename IN VARCHAR2,
p_os IN VARCHAR2,
msg OUT VARCHAR2
IS
no_fin_linea EXCEPTION;
v_srcfile BFILE;
v_tmpclob CLOB;
v_warning INTEGER;
v_dest_offset INTEGER := 1;
v_src_offset INTEGER := 1;
v_lang INTEGER := 0;
posfinlinea NUMBER;
posiniciolinea NUMBER;
cad VARCHAR2 (30000);
v_lin CLOB;
v_tamfich NUMBER;
contlin INTEGER := 0;
v_log UTL_FILE.file_type;
BEGIN
msg := NULL;
-- abrimos el log
v_log :=
UTL_FILE.fopen (p_dir, 'carga_t_pets_respuestas_emisor.log', 'w');
UTL_FILE.put_line (v_log, 'INICIO carga_t_pets_respuestas_emisor');
UTL_FILE.fflush (v_log);
v_srcfile := BFILENAME (p_dir, p_filename);
DBMS_LOB.createtemporary (v_tmpclob, TRUE, DBMS_LOB.CALL);
DBMS_LOB.OPEN (v_srcfile);
DBMS_LOB.loadclobfromfile (dest_lob => v_tmpclob,
src_bfile => v_srcfile,
amount => DBMS_LOB.lobmaxsize,
dest_offset => v_dest_offset,
src_offset => v_src_offset,
bfile_csid => 0,
lang_context => v_lang,
warning => v_warning
-- Una vez cargado el CLOB se puede cerrar el BFILE
DBMS_LOB.CLOSE (v_srcfile);
v_tamfich := DBMS_LOB.getlength (v_tmpclob);
--DBMS_OUTPUT.put_line ('v_tamfich: ' || v_tamfich);
UTL_FILE.put_line (v_log, 'v_tamfich: ' || v_tamfich);
UTL_FILE.fflush (v_log);
posfinlinea := 0;
posiniciolinea := posfinlinea + 1;
-- Despreciamos el último fin de linea (tiene que existir)
IF (UPPER (p_os) = 'WINDOWS')
THEN
v_tamfich := v_tamfich - 4;
ELSE
v_tamfich := v_tamfich - 2;
END IF;
contlin := 1;
WHILE (v_tamfich + 1 - posfinlinea > 0)
LOOP
--contlin := contlin + 1;
IF (UPPER (p_os) = 'WINDOWS')
THEN
posfinlinea :=
DBMS_LOB.INSTR (v_tmpclob,
CHR (13) || CHR (10) || CHR (13) || CHR (10),
posiniciolinea
ELSE
posfinlinea :=
DBMS_LOB.INSTR (v_tmpclob, CHR (13) || CHR (13),
posiniciolinea);
END IF;
IF (posfinlinea = 0)
THEN
RAISE no_fin_linea;
END IF;
--DBMS_OUTPUT.put_line ('posfinlinea: ' || posfinlinea);
UTL_FILE.put_line (v_log, 'posfinlinea: ' || posfinlinea);
UTL_FILE.fflush (v_log);
IF (DBMS_LOB.getlength (v_lin) != 0)
THEN
DBMS_LOB.freetemporary (v_lin);
UTL_FILE.put_line (v_log,
'Se ha reinicializado el temporary clob v_lin'
UTL_FILE.fflush (v_log);
END IF;
DBMS_LOB.createtemporary (v_lin, TRUE, DBMS_LOB.CALL);
DBMS_LOB.COPY (dest_lob => v_lin,
src_lob => v_tmpclob,
amount => posfinlinea,
dest_offset => 1,
src_offset => posiniciolinea
-- Tratamos la linea
--DBMS_OUTPUT.put_line
UTL_FILE.put_line
(v_log,
UTL_FILE.fflush (v_log);
tratar_linea (v_lin, contlin, v_log, msg);
posiniciolinea := posfinlinea + 1;
contlin := contlin + 1;
--DBMS_OUTPUT.put_line ('posiniciolinea: ' || posiniciolinea);
UTL_FILE.put_line (v_log, 'posiniciolinea: ' || posiniciolinea);
UTL_FILE.fflush (v_log);
END LOOP;
-- Se valida la transaccion
COMMIT;
--Se cierra el fichero
--DBMS_LOB.CLOSE (v_srcfile);
DBMS_LOB.freetemporary (v_tmpclob);
UTL_FILE.put_line (v_log, 'FIN carga_t_pets_respuestas_emisor');
UTL_FILE.fclose (v_log);
EXCEPTION
WHEN no_fin_linea
THEN
ROLLBACK;
msg := 'Fichero mal formateado, no se encuentra el fin de linea';
IF (DBMS_LOB.ISOPEN (v_srcfile) = 1)
THEN
DBMS_LOB.fileclose (v_srcfile);
END IF;
IF UTL_FILE.is_open (v_log)
THEN
UTL_FILE.fclose (v_log);
END IF;
WHEN OTHERS
THEN
ROLLBACK;
msg := SQLERRM;
IF (DBMS_LOB.ISOPEN (v_srcfile) = 1)
THEN
DBMS_LOB.fileclose (v_srcfile);
END IF;
IF UTL_FILE.is_open (v_log)
THEN
UTL_FILE.fclose (v_log);
END IF;
END carga_t_pets_respuestas_emisor;
END carga_tablas;
/Thanks in advance.Thank you again for answering.
I am reading from the file in the procedure carga_t_pets_respuestas_emisor I posted above (the procedure is able to load the whole file in the table but takes very long).
What I am doing is loading the whole file in a BFILE and then loading it in a CLOB variable using loadclobfromfile (it is not taking very long because I can see that early in the log):
v_srcfile := BFILENAME (p_dir, p_filename);
DBMS_LOB.createtemporary (v_tmpclob, TRUE, DBMS_LOB.CALL);
DBMS_LOB.OPEN (v_srcfile);
DBMS_LOB.loadclobfromfile (dest_lob => v_tmpclob,
src_bfile => v_srcfile,
amount => DBMS_LOB.lobmaxsize,
dest_offset => v_dest_offset,
src_offset => v_src_offset,
bfile_csid => 0,
lang_context => v_lang,
warning => v_warning
);Then I read in a loop all the records (I cannot call them lines because the CLOB columns can contain line feeds) from the file and load them it in another CLOB variable:
WHILE (v_tamfich + 1 - posfinlinea > 0)
LOOP
--contlin := contlin + 1;
IF (UPPER (p_os) = 'WINDOWS')
THEN
posfinlinea :=
DBMS_LOB.INSTR (v_tmpclob,
CHR (13) || CHR (10) || CHR (13) || CHR (10),
posiniciolinea
ELSE
posfinlinea :=
DBMS_LOB.INSTR (v_tmpclob, CHR (13) || CHR (13),
posiniciolinea);
END IF;
IF (posfinlinea = 0)
THEN
RAISE no_fin_linea;
END IF;
--DBMS_OUTPUT.put_line ('posfinlinea: ' || posfinlinea);
UTL_FILE.put_line (v_log, 'posfinlinea: ' || posfinlinea);
UTL_FILE.fflush (v_log);
IF (DBMS_LOB.getlength (v_lin) != 0)
THEN
DBMS_LOB.freetemporary (v_lin);
UTL_FILE.put_line (v_log,
'Se ha reinicializado el temporary clob v_lin'
UTL_FILE.fflush (v_log);
END IF;
DBMS_LOB.createtemporary (v_lin, TRUE, DBMS_LOB.CALL);
DBMS_LOB.COPY (dest_lob => v_lin,
src_lob => v_tmpclob,
amount => posfinlinea,
dest_offset => 1,
src_offset => posiniciolinea
-- Tratamos la linea
--DBMS_OUTPUT.put_line
UTL_FILE.put_line
(v_log,
UTL_FILE.fflush (v_log);
tratar_linea (v_lin, contlin, v_log, msg);
posiniciolinea := posfinlinea + 1;
contlin := contlin + 1;
--DBMS_OUTPUT.put_line ('posiniciolinea: ' || posiniciolinea);
UTL_FILE.put_line (v_log, 'posiniciolinea: ' || posiniciolinea);
UTL_FILE.fflush (v_log);
END LOOP;(I have also loaded the whole file using sql*loader, but I have asked to try to do it with pl/sql)
Thanks again and regards. -
Hi,
I have two questions..
1)I have a table called accounts with a column accountid. I have an index with accountid which is also the primary key.
Is accessing a record faster with rowid or accountid?
2)How can I trap DML statements in a PL/SQL block? Even if the particular record is not found, it does not return any error?
Any help greatly appreciated?
Thanks,
JyotiAccess through ROWID is the fastest way because the ROWID contains the physical address of the row. The disadvantage is that the ROWID can change without you knowing it. You must not use this method unless you are a 100% sure that the table is really static (even then, an export and import can change the ROWID).
To trap DML statements in PL/SQL you can use the packages dbms_output or utl_file. Those packages allow you to write to screen or file. For error handling you must use the EXCEPTION clause.
null -
Assign a specific privilege in a user
I have created a user and add him to the deployers group but that user can not monitor JMS queues through the console. ONLY if i add the Administrators group to that user it has that capability.
But i do not want to give to that specific user all those privileges. How can i add that specific privilege to that user????I try with :
FOR c_table IN C_TABLES
LOOP
EXECUTE IMMEDIATE 'UPDATE ' || c_table.table_name || ' SET ATT = :1 WHERE ATT= :2 ' USING v_nouveau_nom, v_ancien_nom;
END LOOP;And I get a error not handle by the bloc EXCEPTION :
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No_data_found - FIN DU FicIN');
UTL_FILE.FCLOSE(FicIN);
WHEN UTL_FILE.INVALID_FILEHANDLE THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.INVALID_FILEHANDLE');
UTL_FILE.FCLOSE(FicIN);
WHEN UTL_FILE.INVALID_PATH THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.INVALID_PATH');
UTL_FILE.FCLOSE(FicIN);
WHEN UTL_FILE.READ_ERROR THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.READ_ERROR');
UTL_FILE.FCLOSE(FicIN);
WHEN UTL_FILE.WRITE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('UTL_FILE.WRITE_ERROR');
UTL_FILE.FCLOSE(FicIN);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Autres erreurs');
UTL_FILE.FCLOSE(FicIN);
END;SQL trace :
SQL> @renommer_att
Autres erreurs -
hi all,
I am using Oracle XE and forms 6i and am facing the above error when i try to use the utl_file utility.
WHEN BUTTOn PRESSED
IF (:EXPORT_IMPORT_DATA = 'E') THEN
message(lc_status);
SECURITY.PKG_gen_trnsfr_data_flat_file.PROC_gen_trnsfr_data_flat_file(:DATA_FILE_PATH, :DATA_FILE_NAME, lc_status);
PKG_GEN_TRNSFR_DATA_FLAT_FILE body
create or replace PACKAGE BODY PKG_gen_trnsfr_data_flat_file IS
PROCEDURE proc_gen_trnsfr_data_flat_file(p_file_location IN VARCHAR2, p_file_name IN VARCHAR2, po_status OUT VARCHAR2) IS
lh_filename UTL_FILE.FILE_TYPE;
ls_data VARCHAR2(2000);
ln_count NUMBER;
lc_error VARCHAR2(10000);
CURSOR cur_FPM_DAMAGE_COMPENSATION IS SELECT RPAD(nvl(PDCO_CASE_CLASS,' '),1) || RPAD(nvl(PDCO_CASE_DISPOSAL_PENDING,' '),1) || RPAD(nvl(PDCO_CASE_DISPOSAL_TYPE,' '),1) || RPAD(nvl(PDCO_CC_NO,0),9) || RPAD(nvl(PDCO_CF_NO,0),9) || RPAD(nvl(PDCO_COMPEN_REALISED,0),18) || RPAD(nvl(PDCO_CONFISCATED_PRODUCE,' '),25) || RPAD(nvl(PDCO_CR_NO,0),9) || RPAD(nvl(PDCO_DAMAGE_DETAILS,' '),90) || RPAD(nvl(PDCO_DAMAGE_REPORT_NO,0),13) || RPAD(NVL(TO_CHAR(PDCO_DATE_ORDER_COMPOUNDING,'DD-MON-RRRR'),' '),15) || RPAD(NVL(TO_CHAR(PDCO_DATE_PROSECUTION,'DD-MON-RRRR'),' '),15) || RPAD(NVL(TO_CHAR(PDCO_DISPOSAL_DATE,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PDCO_DR_NO,0),9) || RPAD(nvl(PDCO_FOREST_NAME,' '),50) || RPAD(NVL(TO_CHAR(PDCO_ISSUE_DATE,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PDCO_LASTUPDATE_BY,' '),30) || RPAD(NVL(TO_CHAR(PDCO_LASTUPDATE_ON,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PDCO_NO_OF_PERSONS_IN_THE_CASE,0),6) || RPAD(nvl(PDCO_NO_ORDER_FOR_COMPOUNDING,' '),15) || RPAD(nvl(PDCO_OFFENCE_DETAILS,' '),90) || RPAD(nvl(PDCO_OFFENCE_TYPE,' '),1) || RPAD(nvl(PDCO_OFFENDER_ADDRESS,' '),90) || RPAD(nvl(PDCO_OFFENDER_NAME,' '),200) ||
RPAD(nvl(PDCO_OFFICIAL_NAME,' '),30) || RPAD(nvl(PDCO_RA_SIGN,' '),30) || RPAD(NVL(TO_CHAR(PDCO_RA_SIGN_DATE,'DD-MON-RRRR'),' '),15) || RPAD(NVL(TO_CHAR(PDCO_RECEIPT_DATE,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PDCO_RR_NO,0),18) || RPAD(nvl(PDCO_TOOLS,0),18) || RPAD(nvl(PDCO_TOTAL,0),18) || RPAD(nvl(PDCO_VALUE_CONFISCATED_PROD,0),18) || RPAD(nvl(PDCO_VFP,0),18) || RPAD(nvl(PDCO_YDIV_DIVISION_CODE,' '),8) || RPAD(nvl(PDCO_YRAN_RANGE_CODE,' '),8) outstring FROM FPM_DAMAGE_COMPENSATION;
CURSOR cur_FPM_DAMAGE_COMPENSATION_R IS SELECT RPAD(nvl(CIRCLE,' '),90) || RPAD(nvl(DIVISION,' '),90) || RPAD(nvl(PREV_A,0),9) || RPAD(nvl(PREV_B,0),9) || RPAD(nvl(PREV_TOTAL,0),11) || RPAD(nvl(TOT_A,0),11) || RPAD(nvl(TOT_B,0),11) || RPAD(nvl(TOT_C,0),11) || RPAD(nvl(T_A,0),9) || RPAD(nvl(T_B,0),9) || RPAD(nvl(T_C,0),9) || RPAD(nvl(X_A,0),9) || RPAD(nvl(X_B,0),9) || RPAD(nvl(X_C,0),9) || RPAD(nvl(Y_A,0),9) || RPAD(nvl(Y_B,0),9) || RPAD(nvl(Y_C,0),9) || RPAD(nvl(Z_A,0),9) || RPAD(nvl(Z_B,0),9) || RPAD(nvl(Z_C,0),9) outstring FROM fpm.FPM_DAMAGE_COMPENSATION_R;
CURSOR cur_FPM_ENCROACHMENT IS SELECT RPAD(nvl(PENC_AREA_UNDER_ENCROACH,0),18) || RPAD(nvl(PENC_BALANCE_AREA_UN_ENC,0),18) || RPAD(nvl(PENC_ENCROACH_ID,' '),8) || RPAD(nvl(PENC_FOREST_NAME,' '),50) || RPAD(nvl(PENC_LASTUPDATE_BY,' '),30) || RPAD(NVL(TO_CHAR(PENC_LASTUPDATE_ON,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PENC_LEGAL_STATUS_OF_FOREST,' '),90) || RPAD(NVL(TO_CHAR(PENC_PERIOD_FROM_UNDER_ENC,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PENC_PRESENT_STATUS,' '),90) || RPAD(nvl(PENC_YDIV_DIVISION_CODE,' '),8) outstring FROM FPM_ENCROACHMENT;
CURSOR cur_FPM_ENCROACHMENT_REMOVALS IS SELECT RPAD(nvl(PENR_ACTION_TAKEN,' '),90) || RPAD(nvl(PENR_AREA_REMOVED_ENCMNT,0),18) || RPAD(NVL(TO_CHAR(PENR_DATE,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PENR_LASTUPDATE_BY,' '),30) || RPAD(NVL(TO_CHAR(PENR_LASTUPDATE_ON,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PENR_PENC_ENCROACHMENT_ID,' '),8) || RPAD(nvl(PENR_PENC_YDIV_DIVISION_CODE,' '),8) outstring FROM FPM_ENCROACHMENT_REMOVALS;
CURSOR cur_FPM_FIRE IS SELECT RPAD(nvl(PFIR_ACTION_TAKEN,' '),90) || RPAD(nvl(PFIR_AREA_EFFECTED,0),18) || RPAD(nvl(PFIR_CAUSE_OF_FIRE,' '),2) || RPAD(nvl(REPLACE(REPLACE(PFIR_DAMAGE_DETAILS,CHR(13),' '),CHR(10),' '),' '),200) || RPAD(nvl(PFIR_DAMAGE_VALUE,0),18) || RPAD(NVL(TO_CHAR(PFIR_DATE_OF_FIRE,'DD-MON-RRRR'),' '),15) || RPAD(NVL(TO_CHAR(PFIR_DATE_VISIT_DFO,'DD-MON-RRRR'),' '),15) || RPAD(NVL(TO_CHAR(PFIR_DATE_VISIT_RANGEOFFICER,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PFIR_DFO_COMMENTS,' '),90) || RPAD(nvl(PFIR_DFO_SIGN,' '),30) || RPAD(NVL(TO_CHAR(PFIR_DFO_SIGN_DATE,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PFIR_FIRE_NO,' '),10) || RPAD(nvl(PFIR_FOREST_NAME,' '),50) || RPAD(nvl(PFIR_LASTUPDATE_BY,' '),30) || RPAD(NVL(TO_CHAR(PFIR_LASTUPDATE_ON,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PFIR_NO_OF_TREES,0),18) || RPAD(nvl(PFIR_QTY_OTH_FORST_PROD_BRNT,0),18) || RPAD(nvl(PFIR_RANGEOFFICER_COMMENTS,' '),90) || RPAD(nvl(PFIR_REPORTING_PERSON,' '),30) || RPAD(nvl(PFIR_VALUE_OTH_FORST_PROD_BRNT,0),18) || RPAD(nvl(PFIR_VALUE_TREES_BURNT,0),18) || RPAD(nvl(PFIR_VOLUME_TREES_BURNT,0),18) || RPAD(nvl(PFIR_YDIV_DIVISION_CODE,' '),8) || RPAD(nvl(PFIR_YRAN_RANGE_CODE,' '),8) outstring FROM FPM_FIRE;
CURSOR cur_FPM_JFM_MASTER IS SELECT RPAD(nvl(PJFM_BSCM_SCHEME_CODE,' '),8) || RPAD(nvl(PJFM_JFM_ID,0),13) || RPAD(nvl(PJFM_LASTUPDATE_BY,' '),30) || RPAD(NVL(TO_CHAR(PJFM_LASTUPDATE_ON,'DD-MON-RRRR'),' '),15) || RPAD(NVL(TO_CHAR(PJFM_LAUNCH_DATE,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PJFM_LOCATION,' '),20) || RPAD(nvl(PJFM_YDIV_DIVISION_CODE,' '),8) outstring FROM FPM_JFM_MASTER;
CURSOR cur_FPM_JFM_DETAILS IS SELECT RPAD(NVL(TO_CHAR(PJFD_DATE,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PJFD_EXPENDITURE,0),18) || RPAD(nvl(PJFD_LASTUPDATE_BY,' '),30) || RPAD(NVL(TO_CHAR(PJFD_LASTUPDATE_ON,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PJFD_NO_OF_FPS,0),13) || RPAD(nvl(PJFD_OTHER_AREA_INCLUDED,0),18) || RPAD(nvl(PJFD_OVERALL_AREA_REGENERATED,0),18) || RPAD(nvl(PJFD_PF_AREA_INCLUDED,0),18) || RPAD(nvl(PJFD_PJFM_JFM_ID,0),13) || RPAD(nvl(PJFD_RF_AREA_INCLUDED,0),18) || RPAD(nvl(PJFD_VALUE_BENEFIT_CASH,0),18) || RPAD(nvl(PJFD_VALUE_BENEFIT_GOODS,0),18) outstring FROM FPM_JFM_DETAILS;
CURSOR cur_FPM_PROTECTION_FIRE_MASTER IS SELECT RPAD(nvl(PPFM_AREA_ATTEM_TO_BE_PROT,0),18) || RPAD(nvl(PPFM_FINANCIAL_YEAR,' '),9) || RPAD(nvl(PPFM_LASTUPDATE_BY,' '),30) || RPAD(NVL(TO_CHAR(PPFM_LASTUPDATE_ON,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PPFM_YDIV_DIVISION_CODE,' '),8) outstring FROM FPM_PROTECTION_FIRE_MASTER;
CURSOR cur_FPM_PROTECTION_FIRE_DET IS SELECT RPAD(nvl(PPFD_AREA_ACTUALLY_PROTECTED,0),18) || RPAD(nvl(PPFD_COST,0),18) || RPAD(nvl(PPFD_FAILURE,0),18) || RPAD(nvl(PPFD_LASTUPDATE_BY,' '),30) || RPAD(NVL(TO_CHAR(PPFD_LASTUPDATE_ON,'DD-MON-RRRR'),' '),15) || RPAD(nvl(PPFD_PPFM_FINANCIAL_YEAR,' '),9) || RPAD(nvl(PPFD_PPFM_YDIV_DIVISIN_CODE,' '),8) outstring FROM FPM_PROTECTION_FIRE_DETAILS;
BEGIN
lc_error := 'begin';
lc_error := p_file_location || p_file_name ;
lh_filename := UTL_FILE.FOPEN(p_file_location, p_file_name, 'w',32767);
lc_error := 'filename';
SELECT COUNT(*) INTO ln_count FROM FPM_DAMAGE_COMPENSATION;
lc_error := 'line 1';
UTL_FILE.PUT_LINE(lh_filename, RPAD(ln_count,10) || 'FPM_DAMAGE_COMPENSATION');
lc_error := 'line2';
FOR i IN cur_FPM_DAMAGE_COMPENSATION LOOP
UTL_FILE.PUT_LINE(lh_filename, i.outstring);
END LOOP;
SELECT COUNT(*) INTO ln_count FROM fpm.FPM_DAMAGE_COMPENSATION_R;
UTL_FILE.PUT_LINE(lh_filename, RPAD(ln_count,10));
FOR i IN cur_FPM_DAMAGE_COMPENSATION_R LOOP
UTL_FILE.PUT_LINE(lh_filename, i.outstring);
END LOOP;
SELECT COUNT(*) INTO ln_count FROM FPM_FIRE;
UTL_FILE.PUT_LINE(lh_filename, RPAD(ln_count,10)||'FPM_FIRE');
FOR i IN cur_FPM_FIRE LOOP
UTL_FILE.PUT_LINE(lh_filename, i.outstring);
END LOOP;
SELECT COUNT(*) INTO ln_count FROM FPM_JFM_MASTER;
UTL_FILE.PUT_LINE(lh_filename, RPAD(ln_count,10));
FOR i IN cur_FPM_JFM_MASTER LOOP
UTL_FILE.PUT_LINE(lh_filename, i.outstring);
END LOOP;
SELECT COUNT(*) INTO ln_count FROM FPM_JFM_DETAILS;
UTL_FILE.PUT_LINE(lh_filename, RPAD(ln_count,10));
FOR i IN cur_FPM_JFM_DETAILS LOOP
UTL_FILE.PUT_LINE(lh_filename, i.outstring);
END LOOP;
SELECT COUNT(*) INTO ln_count FROM FPM_PROTECTION_FIRE_MASTER;
UTL_FILE.PUT_LINE(lh_filename, RPAD(ln_count,10));
FOR i IN cur_FPM_PROTECTION_FIRE_MASTER LOOP
UTL_FILE.PUT_LINE(lh_filename, i.outstring);
END LOOP;
SELECT COUNT(*) INTO ln_count FROM FPM_PROTECTION_FIRE_DETAILS;
UTL_FILE.PUT_LINE(lh_filename, RPAD(ln_count,10));
FOR i IN cur_FPM_PROTECTION_FIRE_DET LOOP
UTL_FILE.PUT_LINE(lh_filename, i.outstring);
END LOOP;
SELECT COUNT(*) INTO ln_count FROM FPM_ENCROACHMENT;
UTL_FILE.PUT_LINE(lh_filename, RPAD(ln_count,10));
FOR i IN cur_FPM_ENCROACHMENT LOOP
UTL_FILE.PUT_LINE(lh_filename, i.outstring);
END LOOP;
SELECT COUNT(*) INTO ln_count FROM FPM_ENCROACHMENT_REMOVALS;
UTL_FILE.PUT_LINE(lh_filename, RPAD(ln_count,10));
FOR i IN cur_FPM_ENCROACHMENT_REMOVALS LOOP
UTL_FILE.PUT_LINE(lh_filename, i.outstring);
END LOOP;
UTL_FILE.FCLOSE_ALL;
po_status := 'NO ERROR';
EXCEPTION
WHEN UTL_FILE.INVALID_PATH OR UTL_FILE.INVALID_MODE THEN
po_status := 'I 1';
WHEN UTL_FILE.INVALID_FILEHANDLE OR UTL_FILE.INVALID_OPERATION OR UTL_FILE.INTERNAL_ERROR OR UTL_FILE.WRITE_ERROR THEN
po_status := 'I 2';
WHEN OTHERS THEN
po_status := lc_error;
LC_ERROR:='I 4';
dbms_output.put_line(LC_ERROR);
END;
END;
If i uncomment UTL_FIle.Fopen statement, the error text will be the path name and file name.
Can anyone advise as to what should be done to resolve this on XE. It worked fine on 8i.
I have runcatproc.sql and utlfile.sql also
regards
kunalHi
On 8i you would have set the UTL_DIR_PATH parameter
in the init.ora file. Did you do this for your XE
database? I hope you are referring to the UTL_FILE_DIR parameter. I have set this parameter to value *.
Although the better approach would be to
create a directory object for the file path, an
option which was introduced in 9i..
Can you please elaborate me on this. I tried declaring the create directory statement in the package, but that didnt help. I have already created one through sql command line. How can i use this directory as an alternative to utl_file -
Problem with UTL_FILE (please see my last post on this thread)
Hi all,
I'm trying to get the code (procedures, functions, etc) of my schemas. I've tried it using DBMS_METADATA.GET_DDL but it fails with many objects. Finally, I'm trying to create a procedure to extract the code.
I've created this two procedures:
CREATE OR REPLACE PROCEDURE spool_code (code IN varchar2, propi IN varchar2) is
CURSOR codigo is
select text from dba_source where name = code and owner = propi order by line;
line varchar2(4000);
BEGIN
open codigo;
loop
fetch codigo into line;
exit when codigo%notfound;
dbms_output.put_line(line);
end loop
close;
END;
CREATE OR REPLACE PROCEDURE ext_codigo is
CURSOR objeto is
select object_name, owner from dba_objects where object_type in ('PROCEDURE','FUNCTION','PACKAGE')
and owner not in ('OUTLN','DBSNMP','SYSTEM','SYS','REPADMIN','PERFSTAT','SPOTLIGHT','MONITOR','PRUEBAS','TOAD')
and status='VALID';
nom varchar2(128);
owner varchar2(30);
BEGIN
open objeto;
loop
fetch objeto into nom, owner;
exit when objeto%notfound;
spool_code(nom, owner);
end loop;
close objeto;
END;
And I'm calling from sqlplus to spool it:
SQL> spool Users_code.sql
SQL> exec ext_codigo;
But it don't bring me results...
where is the problem??
Thanks in advance for your support!
dbajug
Edited by: dbajug on Aug 29, 2012 6:36 AMHi,
yes guys, I've set serverout on using the max limit but, always fails with:
ERROR at line 1:
ORA-20000: ORU-10027: buffer overflow, limit of 1000000 bytes
ORA-06512: at "SYS.DBMS_OUTPUT", line 35
ORA-06512: at "SYS.DBMS_OUTPUT", line 198
ORA-06512: at "SYS.DBMS_OUTPUT", line 139
ORA-06512: at "SYS.SPOOL_CODE", line 15
ORA-06512: at "SYS.EXT_CODIGO", line 17
ORA-06512: at line 1
I'm working with a 9i version trying to extract the code to migrate it to a 11g.
In order to avoid the buffer error, I've decide use the UTL_FILE package but I'm having another problem: my procedure now is this
CREATE OR REPLACE PROCEDURE spool_code (code IN varchar2, propi IN varchar2) is
CURSOR codigo is
select text from dba_source where name = code and owner = propi order by line;
line varchar2(4000);
out_file UTL_FILE.File_Type;
BEGIN
begin
out_file := UTL_FILE.Fopen('/export/home/oracle', 'Users_code.sql', 'w');
exception
when others then
dbms_output.put_line('Error opening file');
end;
open codigo;
loop
fetch codigo into line;
exit when codigo%notfound;
UTL_FILE.Put_Line(out_file, line);
end loop;
close codigo;
UTL_FILE.Fclose(out_file);
END;
The directory exists and the file too but fails with this error:
ERROR at line 1:
**ORA-29282: invalid file ID**
ORA-06512: at "SYS.UTL_FILE", line 714
ORA-06512: at "SYS.SPOOL_CODE", line 23
ORA-06512: at "SYS.EXT_CODIGO", line 17
ORA-06512: at line 1
any idea? about the reason? The file is a text file on the server:
ls -lrt /export/home/oracle/Users_code.sql
-rw-rw-r-- 1 oracle dba 0 Aug 29 14:43 /export/home/oracle/Users_code.sql
best regards,
dbajug
Maybe you are looking for
-
Calculating Capacity Requirements
Dear Friends , To calculate capacity for a workcenter , we need to assign any standard value key or simply we can use the work and duration to calculate the capacity . Please advice.
-
What's a good HD camera to use with Premiere Pro CS4
I've used Premiere Pro CS4 for a while now and most of the time I don't have any problems, but recently, I've been buying HD cameras, shooting some AVCHD and then having a hell of a time getting them to play nice with Premiere Pro (or WMindows Media
-
Project created in Flash CS3 & Flash CS5 crashes both Safari & Firefox
I have a user with a brand new image including Snow Leopard 10.6.6 and the Adobe CS5. When creating a project in Flash CS5 and then trying to view it in Safari & Firefox the plug-in crashes which then brings down the browser with it. I went and ins
-
Connecting DVD player, speakers and stereo receiver to mac pro
I'd like to 'integrate' my living room system with my Mac Pro. This entails connecting my living room speakers and digital DVD player to my Mac. My stereo receiver is outdated so I plan to buy a new one. The reason I want to connect the DVD player is
-
Enable customer clearing in vendor master
Dear All I have assinged customer code in my vendor master, but I also want to enable this vendor for customer clearing.Where in vendor master I can do this to enable customer clearing for this vendor. Reagdrs SK