Save oracle table data into local machine in excel sheet - oracle

I want to extract data from a table on a daily basis and save it in my local machine in a excel sheet.

I want to extract data from a table on a daily basis
You could use DBMS_SCHEDULER to create a job and schedule to run daily.
For example, the below job will run every hour:
SQL> BEGIN
2 DBMS_SCHEDULER.DROP_JOB (JOB_NAME => 'test_full_job_definition');
3 END;
4 /
PL/SQL procedure successfully completed.
SQL>
SQL> BEGIN
2 DBMS_SCHEDULER.create_job (
3 job_name => 'test_full_job_definition',
4 job_type => 'PLSQL_BLOCK',
5 job_action => 'BEGIN my_job_procedure; END;',
6 start_date => SYSTIMESTAMP,
7 repeat_interval => 'freq=hourly; byminute=0; bysecond=0;',
8 end_date => NULL,
9 enabled => TRUE,
10 comments => 'Job defined entirely by the CREATE JOB procedure.');
11 END;
12 /
PL/SQL procedure successfully completed.
SQL>
SQL> SELECT JOB_NAME, ENABLED FROM DBA_SCHEDULER_JOBS where job_name ='TEST_FULL_JOB_DEFINITION'
2 /
JOB_NAME ENABL
---------------------------------------- -----
TEST_FULL_JOB_DEFINITION TRUE
SQL>
save it in my local machine in a excel sheet
This is a frequently asked question, and people often get confused between a CSV file and a Microsoft Excel file. Generating a CSV file could be as easy as to spool it using SQL*Plus. For writing the output into an Excel file, you need to do it programmatically.
You could use the following code developed by Anton Scheffer:
CREATE OR REPLACE package as_xlsx
is
/**********************************************
**
** Author: Anton Scheffer
** Date: 19-02-2011
** Website: http://technology.amis.nl/blog
** See also: http://technology.amis.nl/blog/?p=10995
**
** Changelog:
** Date: 21-02-2011
** Added Aligment, horizontal, vertical, wrapText
** Date: 06-03-2011
** Added Comments, MergeCells, fixed bug for dependency on NLS-settings
** Date: 16-03-2011
** Added bold and italic fonts
** Date: 22-03-2011
** Fixed issue with timezone's set to a region(name) instead of a offset
** Date: 08-04-2011
** Fixed issue with XML-escaping from text
** Date: 27-05-2011
** Added MIT-license
** Date: 11-08-2011
** Fixed NLS-issue with column width
** Date: 29-09-2011
** Added font color
** Date: 16-10-2011
** fixed bug in add_string
** Date: 26-04-2012
** Fixed set_autofilter (only one autofilter per sheet, added _xlnm._FilterDatabase)
** Added list_validation = drop-down
** Date: 27-08-2013
** Added freeze_pane
**
******************************************************************************
******************************************************************************
Copyright (C) 2011, 2012 by Anton Scheffer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
******************************************************************************
******************************************** */
--
type tp_alignment is record
( vertical varchar2(11)
, horizontal varchar2(16)
, wrapText boolean
);
--
procedure clear_workbook;
--
procedure new_sheet( p_sheetname varchar2 := null );
--
function OraFmt2Excel( p_format varchar2 := null )
return varchar2;
--
function get_numFmt( p_format varchar2 := null )
return pls_integer;
--
function get_font
( p_name varchar2
, p_family pls_integer := 2
, p_fontsize number := 11
, p_theme pls_integer := 1
, p_underline boolean := false
, p_italic boolean := false
, p_bold boolean := false
, p_rgb varchar2 := null -- this is a hex ALPHA Red Green Blue value
)
return pls_integer;
--
function get_fill
( p_patternType varchar2
, p_fgRGB varchar2 := null -- this is a hex ALPHA Red Green Blue value
)
return pls_integer;
--
function get_border
( p_top varchar2 := 'thin'
, p_bottom varchar2 := 'thin'
, p_left varchar2 := 'thin'
, p_right varchar2 := 'thin'
)
/*
none
thin
medium
dashed
dotted
thick
double
hair
mediumDashed
dashDot
mediumDashDot
dashDotDot
mediumDashDotDot
slantDashDot
*/
return pls_integer;
--
function get_alignment
( p_vertical varchar2 := null
, p_horizontal varchar2 := null
, p_wrapText boolean := null
)
/* horizontal
center
centerContinuous
distributed
fill
general
justify
left
right
*/
/* vertical
bottom
center
distributed
justify
top
*/
return tp_alignment;
--
procedure cell
( p_col pls_integer
, p_row pls_integer
, p_value number
, p_numFmtId pls_integer := null
, p_fontId pls_integer := null
, p_fillId pls_integer := null
, p_borderId pls_integer := null
, p_alignment tp_alignment := null
, p_sheet pls_integer := null
);
--
procedure cell
( p_col pls_integer
, p_row pls_integer
, p_value varchar2
, p_numFmtId pls_integer := null
, p_fontId pls_integer := null
, p_fillId pls_integer := null
, p_borderId pls_integer := null
, p_alignment tp_alignment := null
, p_sheet pls_integer := null
);
--
procedure cell
( p_col pls_integer
, p_row pls_integer
, p_value date
, p_numFmtId pls_integer := null
, p_fontId pls_integer := null
, p_fillId pls_integer := null
, p_borderId pls_integer := null
, p_alignment tp_alignment := null
, p_sheet pls_integer := null
);
--
procedure hyperlink
( p_col pls_integer
, p_row pls_integer
, p_url varchar2
, p_value varchar2 := null
, p_sheet pls_integer := null
);
--
procedure comment
( p_col pls_integer
, p_row pls_integer
, p_text varchar2
, p_author varchar2 := null
, p_width pls_integer := 150 -- pixels
, p_height pls_integer := 100 -- pixels
, p_sheet pls_integer := null
);
--
procedure mergecells
( p_tl_col pls_integer -- top left
, p_tl_row pls_integer
, p_br_col pls_integer -- bottom right
, p_br_row pls_integer
, p_sheet pls_integer := null
);
--
procedure list_validation
( p_sqref_col pls_integer
, p_sqref_row pls_integer
, p_tl_col pls_integer -- top left
, p_tl_row pls_integer
, p_br_col pls_integer -- bottom right
, p_br_row pls_integer
, p_style varchar2 := 'stop' -- stop, warning, information
, p_title varchar2 := null
, p_prompt varchar := null
, p_show_error boolean := false
, p_error_title varchar2 := null
, p_error_txt varchar2 := null
, p_sheet pls_integer := null
);
--
procedure list_validation
( p_sqref_col pls_integer
, p_sqref_row pls_integer
, p_defined_name varchar2
, p_style varchar2 := 'stop' -- stop, warning, information
, p_title varchar2 := null
, p_prompt varchar := null
, p_show_error boolean := false
, p_error_title varchar2 := null
, p_error_txt varchar2 := null
, p_sheet pls_integer := null
);
--
procedure defined_name
( p_tl_col pls_integer -- top left
, p_tl_row pls_integer
, p_br_col pls_integer -- bottom right
, p_br_row pls_integer
, p_name varchar2
, p_sheet pls_integer := null
, p_localsheet pls_integer := null
);
--
procedure set_column_width
( p_col pls_integer
, p_width number
, p_sheet pls_integer := null
);
--
procedure set_column
( p_col pls_integer
, p_numFmtId pls_integer := null
, p_fontId pls_integer := null
, p_fillId pls_integer := null
, p_borderId pls_integer := null
, p_alignment tp_alignment := null
, p_sheet pls_integer := null
);
--
procedure set_row
( p_row pls_integer
, p_numFmtId pls_integer := null
, p_fontId pls_integer := null
, p_fillId pls_integer := null
, p_borderId pls_integer := null
, p_alignment tp_alignment := null
, p_sheet pls_integer := null
);
--
procedure freeze_rows
( p_nr_rows pls_integer := 1
, p_sheet pls_integer := null
);
--
procedure freeze_cols
( p_nr_cols pls_integer := 1
, p_sheet pls_integer := null
);
--
procedure freeze_pane
( p_col pls_integer
, p_row pls_integer
, p_sheet pls_integer := null
);
--
procedure set_autofilter
( p_column_start pls_integer := null
, p_column_end pls_integer := null
, p_row_start pls_integer := null
, p_row_end pls_integer := null
, p_sheet pls_integer := null
);
--
function finish
return blob;
--
procedure save
( p_directory varchar2
, p_filename varchar2
);
--
procedure query2sheet
( p_sql varchar2
, p_column_headers boolean := true
, p_directory varchar2 := null
, p_filename varchar2 := null
, p_sheet pls_integer := null
);
Note : It is a huge code with more than 90k PL/SQL lines of code, so I can't post the entire code here due to restriction of 30k characters. Only posting the important procedures, functions and the package details. Please follow the code link to get the entire code.

the least demanding way would be to daly insert table data into some temp table by some scheduled job
create table myexportable as (select sysdate exportdate, q.* from mytable q)
resp.
insert into myexportable (select sysdate exportdate, q.* from mytable q)
and then export that data using SQL Plus
set serveroutput on;
set linesize 10000;
set pagesize 10000;
set heading off;
set feed 0;
set trimspool on;
set colsep '|';
spool exptable.out;
select * from myexportable where trunc(exportdate) = trunc(sysdate)
/
quit;
and them at least import pipe delimited text file into excel.

Related

Oracle incorrect values when using DBMS_CRYPTO to decrypt a CLOB

I'm trying to encrypt and decrypt a CLOB. I have a test CASE below, which utilizes functions to accomplish this task and was taken from the following link.
Error while using DBMS_CRYPTO function to decrypt CLOB data
Once the anonymous block creates the encrypted CLOB I am using an update statement, which calls a decrypt function to ensure it matches the original string.
I've tried initializing the CLOB before encryption with a call to empty_clob() but I can't seem to get this test CASE to decrypt the CLOB and return back the original value, which I started with.
The string being generated to encrypt is small but the test CASE is a little lengthy so I can provide a step by step guide on what I'm doing.
The last step in the test is a dump() of the decrypted CLOB, which shows some unusual characters in the middle of the CLOB that weren't in the input.
While looking at the documentation I did see an example using RANDOMBYTES on a string bur that will not work for me as it would be very unlikely I will get the same random bytes for the encryption and decryption.
I'm testing this in livesql for those who want to emulate my testing environment.
I was hoping someone could tell me where the problem is and provide the necessary fixes I need to get this functioning properly.
Thanks in advance to all who respond and for your time, patience and expertise.
ALTER SESSION SET NLS_DATE_FORMAT = 'MMDDYYYY HH24:MI:SS';
CREATE TABLE encryption_values
(
NAME VARCHAR2(100 BYTE),
VALUE NVARCHAR2(100)
);
​
INSERT INTO encryption_values
SELECT 'key' NAME,
RAWTOHEX ('52AB32;^$!ER94988OPS3W21') VALUE
FROM DUAL
UNION
SELECT 'iv' NAME, RAWTOHEX ('TY54ABCX') VALUE FROM DUAL;
/
CREATE OR REPLACE FUNCTION encrypt_clob (p_clob IN CLOB) return CLOB is
l_clob CLOB;
lb_variable BLOB;
v_key RAW (320);
v_encryption_type PLS_INTEGER := DBMS_CRYPTO.AES_CBC_PKCS5;
v_iv RAW (320);
l_dest_offset PLS_INTEGER := 1;
l_src_offset PLS_INTEGER := 1;
l_lang_context PLS_INTEGER := DBMS_LOB.default_lang_ctx;
l_warning PLS_INTEGER;
l_step PLS_INTEGER := 1998;
begin
SELECT VALUE
INTO v_key
FROM encryption_values
WHERE name = 'key';
SELECT VALUE
INTO v_iv
FROM encryption_values
WHERE name = 'iv';
dbms_lob.createtemporary(lb_variable, true);
DBMS_CRYPTO.ENCRYPT(
dst => lb_variable,
src => p_clob,
typ => v_encryption_type,
key => v_key,
iv => v_iv
);
DBMS_LOB.createTemporary(
lob_loc => l_clob,
cache => TRUE);
FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(lb_variable) - 1 )/l_step) LOOP
l_clob := l_clob || UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(DBMS_LOB.substr(lb_variable, l_step, i * l_step + 1)));
END LOOP;
RETURN l_clob;
end encrypt_clob;
/
CREATE OR REPLACE FUNCTION decrypt_clob (p_clob IN CLOB) return CLOB is
lb_variable CLOB;
l_clob CLOB;
l_blob BLOB;
v_key RAW (320);
v_encryption_type PLS_INTEGER := DBMS_CRYPTO.AES_CBC_PKCS5;
v_iv RAW (320);
l_dest_offset PLS_INTEGER := 1;
l_src_offset PLS_INTEGER := 1;
l_lang_context PLS_INTEGER := DBMS_LOB.default_lang_ctx;
l_warning PLS_INTEGER;
l_raw RAW(32767);
l_amt NUMBER := 16;
l_offset NUMBER := 1;
l_temp VARCHAR2(32767);
begin
SELECT VALUE
INTO v_key
FROM encryption_values
WHERE name = 'key';
SELECT VALUE
INTO v_iv
FROM encryption_values
WHERE name = 'iv';
dbms_lob.createtemporary(l_blob, true);
-- base-64 string has line breaks; those could give an inaccurate result to the decode function below, so they are replaced with NULL.
l_clob := replace(replace(p_clob, chr(13), null), chr(10), null);
FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(l_clob) - 1 )/l_amt) LOOP
DBMS_LOB.read(l_clob, l_amt, l_offset, l_temp);
l_offset := l_offset + l_amt;
l_raw := UTL_ENCODE.base64_decode(utl_raw.cast_to_raw(l_temp));
DBMS_LOB.append (l_blob, TO_BLOB(l_raw));
END LOOP;
dbms_lob.createtemporary(lb_variable, true);
DBMS_CRYPTO.DECRYPT(
dst => lb_variable,
src => l_blob,
typ => v_encryption_type,--dbms_crypto.des_cbc_pkcs5,
key => v_key,
iv => v_iv
);
return lb_variable;
end decrypt_clob;
/
CREATE table t(
seq_num integer GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
hash_pk VARCHAR2(1000) not NULL PRIMARY KEY,
c CLOB,
encrypted VARCHAR2(1) DEFAULT 'N',
create_date DATE DEFAULT SYSDATE
);
/
CREATE or REPLACE FUNCTION HASH_SHA512 (
psINPUT IN VARCHAR2
) RETURN VARCHAR2 AS
rHash RAW (512);
BEGIN
rHash := DBMS_CRYPTO.HASH (TO_CLOB (psINPUT),
dbms_crypto.HASH_SH512);
RETURN (LOWER (RAWTOHEX (rHash)));
END HASH_SHA512;
/
CREATE OR REPLACE PROCEDURE insert_clob(
p_clob IN CLOB,
p_encrypted VARCHAR2
) AS
l_hash_pk VARCHAR2(1000);
BEGIN
SELECT HASH_SHA512(p_clob) INTO l_hash_pk from dual;
IF (p_encrypted = 'N')
THEN
insert into t (hash_pk, c, encrypted)
select l_hash_pk, p_clob, p_encrypted from dual
where not exists(select 1
from t
where (hash_pk = l_hash_pk));
ELSE
insert into t (hash_pk, c, encrypted)
select l_hash_pk, encrypt_clob (p_clob), p_encrypted from dual
where not exists(select 1
from t
where (hash_pk = l_hash_pk));
END IF;
END;
declare
c1 clob := empty_clob();
c2 varchar2(32000);
BEGIN
for i in 1 .. 3
loop
c2 := 'abcdefghijklmnopqrstuvwxyz ' || i;
dbms_output.put_line(c2);
SELECT CONCAT(c1, c2) INTO c1 FROM DUAL;
insert_clob (c1, 'Y');
c1 := empty_clob();
c2 := NULL;
end loop;
END;
UPDATE t
set c = decrypt_clob(c),encrypted = 'N' where encrypted ='Y';
-- As you can see from the dump() the decrypted CLOB doesn't match the original CLOB.
SELECT c, dump(to_char(c)) from t;
/
C DUMP(TO_CHAR(C))
abcdefgh0QKEmnopqrstuvwxyz 1 Typ=1 Len=28: 97,98,99,100,101,102,103,104,48,81,75,69,109,110,111,112,113,114,115,116,117,118,119,120,121,122,32,49
abcdefgh�klmnopqrstuvwxyz 2 Typ=1 Len=30: 97,98,99,100,101,102,103,104,239,191,189,22,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,32,50
abcdefgh�klmnopqrstuvwxyz 3 Typ=1 Len=30: 97,98,99,100,101,102,103,104,239,191,189,22,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,32,51

How do we split a CLOB (with some lines with more than 32K characters) line by line via PLSQL?

I am trying to split a huge CLOB which contains lines with more than 32K characters.
I tried to use this
SELECT REGEXP_SUBSTR(file_cont, '[^'||chr(10)||']+', 1, LEVEL) AS substr
from data_tab where interface = 'Historical'
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(file_cont, '[^'||chr(10)||']+')) + 1
The table data_tab contains some files with pipe as a separator.
The column file_cont is a clob which contains the file we are interested in.
However, when I try to execute the above query, it looks like there is an infinite loop.
For information, the CLOB contains more than 600 lines.
What I want to do is to split the clob, line by line into distinct CLOB.
Do you know a query that can display this result without falling into an infinite loop?
EDIT : The file's size is 22MB.
Thank you in advance.
I have a special package for split and PCRE regular expressions:
https://github.com/xtender/XT_REGEXP
You can find this function in https://github.com/xtender/XT_REGEXP/blob/master/xt_regexp.pck
/**
* Clob simple split
*/
function clob_split_simple(p_clob in clob,p_delim in varchar2)
return clob_table pipelined is
row clob;
l_b number:=1;
l_e number:=1;
$IF DBMS_DB_VERSION.ver_le_11 $THEN
$ELSE
pragma UDF;
$END
begin
while l_e>0
loop
l_e:=instr(p_clob,p_delim,l_b);
pipe row(substr(p_clob,l_b,case when l_e>0 then l_e-l_b else length(p_clob)+length(p_delim)-l_b end));
l_b:=l_e+length(p_delim);
end loop;
end clob_split_simple;
So you can either use this pipelined function:
select *
from table(xt_regexp.clob_split_simple(:clob,chr(10));
or take this code as an example.
clob_table is just a table of clob:
https://github.com/xtender/XT_REGEXP/blob/master/types.sql
create or replace type clob_table as table of clob;
/
create or replace type date_table as table of date;
/
create or replace type number_table as table of number;
/
create or replace type varchar2_table as table of varchar2(4000);
/
create or replace type xml_table as table of xmltype;
/
Update: fixed a bug with long matches: dbms_lob.substr which returns varchar2, replaced with substr(clob) which return clob.
You can use a PL/SQL function to read the and split the value:
If you have the data type:
CREATE TYPE clob_table AS TABLE OF CLOB;
Then the function:
CREATE FUNCTION split_clob(
p_value IN CLOB,
p_delimiter IN VARCHAR2 DEFAULT ','
) RETURN clob_table PIPELINED
IS
v_start PLS_INTEGER;
v_next PLS_INTEGER;
v_len PLS_INTEGER;
BEGIN
v_start := 1;
LOOP
v_next := DBMS_LOB.INSTR( p_value, p_delimiter, v_start );
v_len := CASE v_next WHEN 0 THEN LENGTH( p_value ) + 1 ELSE v_next END - v_start;
PIPE ROW ( SUBSTR( p_value, v_start, v_len ) );
EXIT WHEN v_next = 0;
v_start := v_next + LENGTH(p_delimiter);
END LOOP;
END;
/
For the sample data:
CREATE TABLE table_name ( value CLOB );
DECLARE
v_value TABLE_NAME.VALUE%TYPE := EMPTY_CLOB();
BEGIN
FOR ch IN 65 .. 68 LOOP
FOR i IN 1 .. 10 LOOP
v_value := v_value || RPAD( CHR(ch), 4000, CHR(ch) );
END LOOP;
IF ch < 68 THEN
v_value := v_value || CHR(10);
END IF;
END LOOP;
INSERT INTO table_name ( value ) VALUES ( v_value );
END;
/
Then the output of:
SELECT SUBSTR( s.column_value, 1, 10 ) AS value,
LENGTH( s.column_value ) AS len
FROM table_name t
CROSS APPLY TABLE( split_clob( t.value, CHR(10) ) ) s
Is:
VALUE
LEN
AAAAAAAAAA
40000
BBBBBBBBBB
40000
CCCCCCCCCC
40000
DDDDDDDDDD
40000
db<>fiddle here

Oracle procedure to create_person fails with PLS-00306 error

I have a package specification:
G_PKG_NAME CONSTANT VARCHAR2(30) := 'XX_CUST_PKG';
PROCEDURE customer_load
( errbuff OUT NOCOPY VARCHAR2
, retcode OUT NOCOPY VARCHAR2);
And body with procedure which calls to HZ_PARTY_V2PUB API. It uses cursor to take data from a table and then sends it to API :
PROCEDURE create_customer
( errbuff OUT NOCOPY VARCHAR2
, retcode OUT NOCOPY VARCHAR2)
IS
ERR_SOURCE CONSTANT VARCHAR2(100) := G_PKG_NAME ||'.create_customer';
CURSOR c_load
IS
SELECT rowid row_id
, person_first_name
, person_last_name
, title
, known_as
, person_identifier
, gender
FROM xx_customer_info
WHERE NVL(status_flag, 'X') <> 'S';
r_load c_load%ROWTYPE;
--p_init_msg_list VARCHAR2(1) := FND_API.G_TRUE;
v_gender VARCHAR2(30); --hz_parties.sex%TYPE;
v_title VARCHAR2(60); --hz_parties.title%TYPE;
--API record type
person_rec HZ_PARTY_V2PUB.PERSON_REC_TYPE;
-- API output variables
x_return_status VARCHAR2(1);
x_msg_count NUMBER;
x_msg_data VARCHAR2(2000);
x_party_id NUMBER;
x_party_number VARCHAR2(30);
x_profile_id NUMBER;
EXC_VALDN_ERR EXCEPTION;
BEGIN
errbuff := ' ';
retcode := RTN_SUCCESS;
msg_log ('Inside '||ERR_SOURCE);
FOR r_load in c_load LOOP
BEGIN
x_msg_data := NULL;
x_return_status := fnd_api.G_RET_STS_SUCCESS;
fnd_msg_pub.initialize;
-- example validation:
IF r_load.person_first_name IS NULL THEN
x_msg_data := ' "First name" cannot be null';
RAISE EXC_VALDN_ERR;
END IF;
-- Same validation for person_last_name here
-- Record Type:
person_rec.person_first_name := r_load.person_first_name;
person_rec.person_last_name := r_load.person_last_name;
person_rec.person_title := v_title;
person_rec.known_as := null;
person_rec.gender := v_gender;
person_rec.created_by_module := 'TCA_V2_API';
HZ_PARTY_V2PUB.create_person ( p_init_msg_list => FND_API.G_TRUE
, p_person_rec => person_rec
, x_party_id => x_party_id
, x_party_number => x_party_number
, x_profile_id => x_profile_id
, x_return_status => x_return_status
, x_msg_count => x_msg_count
, x_msg_data => x_msg_data);
msg_log('==========================');
msg_log('first name / last_name : '||r_load.person_first_name||' | '||r_load.person_last_name);
msg_log('x_return_status: '||x_return_status);
msg_log('x_msg_count: '||x_msg_count);
msg_log('x_msg_data: '||x_msg_data);
IF NVL(x_return_status, FND_API.G_RET_STS_ERROR) <> FND_API.G_RET_STS_SUCCESS THEN
IF NVL(x_msg_count, 0) > 1 THEN
FOR i IN 1..x_msg_count LOOP
x_msg_data := x_msg_data||i||'. '||substr(fnd_msg_pub.get(p_encoded => fnd_api.g_false ), 1, 255)||' , ';
msg_log(x_msg_data);
END LOOP;
END IF;
END IF;
msg_log('==========================');
EXCEPTION
WHEN OTHERS THEN
x_msg_data := 'EXC: '||NVL(x_msg_data, SQLERRM);
x_return_status := FND_API.G_RET_STS_ERROR;
END;
UPDATE xx_customer_info
SET status_flag = x_return_status
, error_message = x_msg_data
WHERE rowid = r_load.row_id;
END LOOP;
COMMIT;
msg_log ('Exit '||ERR_SOURCE);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
msg_log('ERROR : '||ERR_SOURCE||' : '||NVL(SQLERRM, x_msg_data));
errbuff := 'ERROR : '||ERR_SOURCE||' : '||NVL(SQLERRM, x_msg_data);
retcode := RTN_ERROR;
END create_customer;
It should return errors or success.
When I test and run this in anonymous block:
begin
XX_CUST_PKG.create_customer;
end;
I get error message PLS-00306: wrong number or types of arguments in call to 'CREATE_CUSTOMER'. I can't see clearly where this error is referring to. I only have 2 OUT parameters, it should only give errbuff (which is x_msg_data) and retcode which is RTN_SUCCESS, RTN_WARNING or RTN_ERROR (I have this declared as constants '0', '1', '2') to output.
This was rewritten from initial package to the above example code, so that it handles exceptions, and few things had to be modified, but now I'm confused when testing it.
What did I leave out?
Any help?
The error you get is a PL/SQL compilation error, as you can see the error code starts with PLS-XXXX.. So it is not returned from your procedure. You missed to send the variables to hold the values from your procedure (out arguments)
Declare
errbuf varchar2(4000);
retcode varchar2(10);
begin
XX_CUST_PKG.create_customer(errbuf,retcode);
--printing the values
DBMS_OUTPUT.PUT_LINE(retcode||' '||errbuf);
end;
/

Oracle errors ORA-00922 and ORA-06512

I was trying to run the following script:
SET serveroutput ON
DECLARE
v_nbr_part NUMBER := 2;
v_nbr_subpart NUMBER := 2;
v_table_name VARCHAR2(100) := 'XPTO';
v_table_shortname VARCHAR2(100) := 'XPTO';
v_part_first NUMBER;
v_part_last NUMBER;
v_subpart_first NUMBER;
v_subpart_last NUMBER;
v_sql CLOB := '';
v_sql_part CLOB := '';
v_sql_subpart CLOB := '';
v_part_dynam CLOB := '';
v_part_keys CLOB := '';
BEGIN
IF v_nbr_part > 0 THEN
IF v_nbr_subpart > 0 THEN
v_subpart_first := 0;
v_subpart_last := v_nbr_subpart-1;
v_part_dynam:='';
FOR i IN v_subpart_first .. v_subpart_last
LOOP
v_part_dynam := v_part_dynam || ' SUBPARTITION SP' || i ||' VALUES ('||i||')';
IF i <> v_subpart_last THEN
v_part_dynam := v_part_dynam || ',';
END IF;
END LOOP;
v_sql_subpart:= where_to_save('LDR_SUBTYPE', v_part_dynam);
v_part_keys:= ' , "LDR_SUBTYPE" NUMBER NOT NULL ENABLE ';
END IF;
v_part_first := 1;
v_part_last := v_nbr_part;
v_sql_part:= to_clob(' PARTITION BY RANGE (PART_KEY) interval(numtodsinterval(1,''day'')) ')|| v_sql_subpart ||
to_clob(' ( partition EMPTY values less than (to_date(''01-01-2013'',''DD-MM-YYYY'') ) ) ');
v_part_keys:= ', "PART_KEY" TIMESTAMP (6) NOT NULL ENABLE ' || v_part_keys;
END IF;
v_sql:=to_clob(
'CREATE OR REPLACE TABLE "'||v_table_name||'" (
"SEQUENCENUMBER" NUMBER NOT NULL ENABLE,
"LDRID" VARCHAR2(100),
"LDRTYPE" VARCHAR2(50),
"LDR_SUBTYPE" VARCHAR2(50),
"CREATIONTIMESTAMP" TIMESTAMP (6),
"CORRELATIONID" VARCHAR2(4000),
"PARENTLDRID" VARCHAR2(100),
"NUMBEROFCHILDREN" NUMBER,
"PROTOCOLSESSIONID" VARCHAR2(100),
"ACTIVITYID" VARCHAR2(100),
"ACTIVITYINITIALTIMESTAMP" TIMESTAMP (6),
"ACTIVITYELAPSEDTIME" NUMBER,
"CANCELED" CHAR(1),
"REPLACED" CHAR(1),
"INVALIDATIONTIMESTAMP" TIMESTAMP (6),
"INVALIDATEDBYLDRID" VARCHAR2(100),
"INVALIDATESLDRID" VARCHAR2(100),
"OPERATIONID" VARCHAR2(256),
"ACCOUNTID" VARCHAR2(100),
"TOPLEVELID" VARCHAR2(100),
"RESULTCODE" VARCHAR2(100),
"VERSION" NUMBER,
"LDROBJECT" BLOB,
"OBJMETADATA" BLOB,
"OBJKEY" BLOB,
"OBJKEYHASH" VARCHAR2(200) ') ||
v_part_keys ||
to_clob('
)
LOB (OBJKEY) STORE AS SECUREFILE
LOB (LDROBJECT) STORE AS SECUREFILE
LOB (OBJMETADATA) STORE AS SECUREFILE
') ||
v_sql_part || to_clob(',TABLESPACE OCS LOGGING NOCOMPRESS NOCACHE NOPARALLEL');
dbms_output.put_line(dbms_lob.substr(v_sql,4000,1)); //this is line 84!!!!!!!!!
EXECUTE IMMEDIATE v_sql;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.Put_Line(DBMS_UTILITY.Format_Error_Backtrace);
DBMS_OUTPUT.Put_Line(SQLERRM);
END;
/
CREATE OR REPLACE FUNCTION where_to_save(LDR_SUBTYPE VARCHAR2, v_part_dynam OUT CLOB)
RETURN CLOB
IS
BEGIN
CASE
WHEN LDR_SUBTYPE = ('IEC') THEN v_part_dynam := v_part_dynam || 'SUBPARTITION SP0 VALUES (IEC)';
ELSE v_part_dynam := v_part_dynam || 'SUBPARTITION SP1 VALUES (OTHER)';
END CASE;
RETURN v_part_dynam;
END where_to_save;
The script look good to me, but every time I try to run it I get the following errors:
ORA-06512: line 84
ORA-00922: missing or invalid option
I've searched a lot and the only thing I've found about fixing this was "contact your DBA".
What is wrong with my script? How can I fix this?
P.S.: I've commented line 84 !
Tables can't be created or replaced, try dropping it first or build a pl that drops table if exists.
'CREATE TABLE "'||v_table_name||'" (
Create or replace table
Create or replace view --> yes
but not create or replace table. This Option does not exist.

Modify multiple oracle triggers

I have a task that involves updating many triggers which are exactly the same query but applied to several different tables. Is there a way to update all these TRIGGERS using a FOR or similar statement? Actually what I need to do is modify the WHEN clause for all this triggers.
you can use dbms_metadat for this.
for example:
declare
type arr_tab is table of varchar2(30);
v_arr arr_tab;
v_trig clob;
begin
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM,
'SQLTERMINATOR', FALSE );
v_arr := arr_tab('TEST_TRIG', 'TEST2_TRIG'); -- change these triggers.
for idx in 1..v_arr.count
loop
v_trig := dbms_metadata.get_ddl('TRIGGER',v_arr(idx), user);
execute immediate regexp_replace(regexp_replace(v_trig, 'ALTER TRIGGER.*', ''), 'WHEN ([^\)]*\))', 'WHEN (1=1)', 1, 1, 'mi');
end loop;
end;
/
the 'WHEN ([^\)]*\))', 'WHEN (1=1)' part replaces the WHEN clause with (in my case) WHEN (1=1).
You can use dba_triggers to extract the text of the trigger into CREATE or replace statements. But due to some of the columns being LONG datatype you will have trouble extracting them as VARCHAR2. This can be resolved by using Tom Kytes package which is lost somewhere on the oracle site. I include my own version which you may have to modify to meet your needs.
Run the select, insert your when clause and then run the create or replace statements.
This won't work due to the trigger_body being a long datatype
select 'CREATE OR REPLACE TRIGGER '|| description
||trigger_body
from dba_triggers
where owner = 'Your schema'
but this should work if your triggers are not more than 4000 characters
select 'CREATE OR REPLACE TRIGGER '|| description
|| ADMIN.LONG_HELP.SUBSTR_OF('select trigger_body from dba_triggers where trigger_name = :0',
1,4000,'0',dt.trigger_name)
from dba_triggers dt
where owner = 'YourSchema';
CREATE OR REPLACE PACKAGE ADMIN.LONG_HELP
/******************************************************************************
NAME: LONG_HELP
PURPOSE: Read fields of type long. (commonly found in data dictionary)
REVISIONS:
Ver Date Author Description
--------- ---------- --------------- ------------------------------------
1.0 10/27/2011 1. Created this package. based on Tom Kyte's column here
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:839298816582
note that it only retrieves the first 4000 characters of any LONG column
USAGE in a WHERE
INSTR(
ADMIN.LONG_HELP.SUBSTR_OF('SELECT text from all_views where view_name =:o ',
1,4000,'o',m2.obj_name),m1.FK_ID) > 0
******************************************************************************/
--AUTHID CURRENT_USER
--removed to get around ORA-29470: Effective userid or roles are not the same as when cursor was parsed
--restrict usage to admin schema for Oracle 11g
AS
FUNCTION substr_of (p_query IN VARCHAR2,
p_from IN NUMBER,
p_for IN NUMBER,
p_name1 IN VARCHAR2 DEFAULT NULL ,
p_bind1 IN VARCHAR2 DEFAULT NULL ,
p_name2 IN VARCHAR2 DEFAULT NULL ,
p_bind2 IN VARCHAR2 DEFAULT NULL ,
p_name3 IN VARCHAR2 DEFAULT NULL ,
p_bind3 IN VARCHAR2 DEFAULT NULL ,
p_name4 IN VARCHAR2 DEFAULT NULL ,
p_bind4 IN VARCHAR2 DEFAULT NULL )
RETURN VARCHAR2;
END LONG_HELP;
/
CREATE OR REPLACE PACKAGE BODY ADMIN.LONG_HELP
AS
g_cursor NUMBER := DBMS_SQL.open_cursor;
g_query VARCHAR2 (32765);
PROCEDURE bind_variable (p_name IN VARCHAR2, p_value IN VARCHAR2)
IS
BEGIN
IF (p_name IS NOT NULL)
THEN
DBMS_SQL.bind_variable (g_cursor, p_name, p_value);
END IF;
END BIND_VARIABLE;
FUNCTION substr_of (p_query IN VARCHAR2,
p_from IN NUMBER,
p_for IN NUMBER,
p_name1 IN VARCHAR2 DEFAULT NULL ,
p_bind1 IN VARCHAR2 DEFAULT NULL ,
p_name2 IN VARCHAR2 DEFAULT NULL ,
p_bind2 IN VARCHAR2 DEFAULT NULL ,
p_name3 IN VARCHAR2 DEFAULT NULL ,
p_bind3 IN VARCHAR2 DEFAULT NULL ,
p_name4 IN VARCHAR2 DEFAULT NULL ,
p_bind4 IN VARCHAR2 DEFAULT NULL )
RETURN VARCHAR2
AS
/******************************************************************************
NAME: LONG_HELP.SUBSTR_OF
PURPOSE: CONVERT long data fields into VARCHAR2
WHOSE DATA IS CHANGED: none
WHAT USES THIS:
WHERE ARE THE RESOURCES NEEDED:
******************************************************************************/
l_buffer VARCHAR2 (4000);
l_buffer_len NUMBER;
BEGIN
IF (NVL (p_from, 0) <= 0)
THEN
raise_application_error (-20002,
'From must be >= 1 (positive numbers)');
END IF;
IF (NVL (p_for, 0) NOT BETWEEN 1 AND 4000)
THEN
raise_application_error (-20003, 'For must be between 1 and 4000');
END IF;
IF (p_query <> g_query OR g_query IS NULL)
THEN
IF (UPPER (TRIM (NVL (p_query, 'x'))) NOT LIKE 'SELECT%')
THEN
raise_application_error (-20001, 'This must be a select only');
END IF;
DBMS_SQL.parse (g_cursor, p_query, DBMS_SQL.native);
g_query := p_query;
END IF;
bind_variable (p_name1, p_bind1);
bind_variable (p_name2, p_bind2);
bind_variable (p_name3, p_bind3);
bind_variable (p_name4, p_bind4);
DBMS_SQL.define_column_long (g_cursor, 1);
IF (DBMS_SQL.execute_and_fetch (g_cursor) > 0)
THEN
DBMS_SQL.column_value_long (g_cursor,
1,
p_for,
p_from - 1,
l_buffer,
l_buffer_len);
END IF;
RETURN l_buffer;
END substr_of;
END LONG_HELP;
/

Resources