Clob out of an anonymous block 10g
ver 10.2
trying to get a clob value out of an anonymous block. Been looking at examples but no luck yet ..
Here's a simple example:
*public void doTest2() throws Exception{*
CLOB tempClob = null;
*final String ab ="" +*
*"declare" +*
*" c clob := 'this is a clob';" +*
*"begin" +*
*" :1 := c;" +*
*"end;";*
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
conn = DriverManager.getConnection(connString,user,pwd);
System.out.println("made connection");
tempClob = CLOB.createTemporary(conn, true, CLOB.DURATION_SESSION);
tempClob.open(CLOB.MODE_READWRITE);
CallableStatement cs = conn.prepareCall(ab);
cs.execute();
cs.close();
conn.close();
my goal is to get the clob from the anonymous block.
Thanks
Ox
Connection connection = null;
CallableStatement cStmt = null;
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
connection = DriverManager.getConnection
("jdbc:oracle:thin:@<host>:<port>:<sid>", "scott", "tiger");
cStmt = connection.prepareCall
("declare c clob := 'This is a CLOB'; begin ? := c; end;");
cStmt.registerOutParameter(1, Types.CLOB);
cStmt.execute();
Clob clob = (Clob)cStmt.getObject(1);
System.out.println("Clob: " + clob.getSubString(1L, (int)clob.length()));
} catch (Exception e) {
e.printStackTrace();
} finally {
try { cStmt.close(); connection.close(); } catch (Exception ex) { }
}
Similar Messages
-
Calling a function which has a CLOB parameter via an anonymous block.
OK,
we are moving a lot of exports currently done by Crystal to just be done by stored procs.
So we have a load of existing, some extremely length SQL statements used for these exports.
IN the exports, we have meaningful column headings, so we have a 'lookup' file where all the column names are listed with the desired column name text listed against it.
So - to make our lives easier(i thought) , I have written a Oracle function to extract al;l of the column names as a list (see below).
It works fine except for when I am trying to pass in a SQL treatment that is longer than 4000 character.
What I want to be able to do is simply have an anonymous block that callls my function, I will be running this via SQL explorer.
Something like......
DECLARE
theSQL CLOB;
BEGFIN
theSQL := 'SELECT * FROM ORDERS WHERE 1=0';
SELECT GET_COLUNS_AS_LIST( theSQL, 0 ) FROM DUAL;
END;
However, when I run this I get the error................
PLS-00428: an INTO clause is expected in this SELECT statement
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
If I hard code the SQL like this, SELECT GET_COLUNS_AS_LIST( 'SELECT * FROM ORDERS WHERE 1=0', 0 ) FROM DUAL; all is well.
Also, I am going to need to be able to pass in SQL ststement longer that 4000 characters as weel so please bear that in mind.
I am not an Oracle guy, so I guess I am missing something fundamental - Please enlighten me with regards to this.
Any help extremely appreciated.
CREATE OR REPLACE FUNCTION GET_COLUNS_AS_LIST( P_SQL IN VARCHAR2, Add_Equals_Sign Number := 0)
RETURN CLOB
IS
fResult VARCHAR2(32000);
HNDL NUMBER;
d NUMBER;
colCount INTEGER;
i INTEGER;
rec_tab DBMS_SQL.DESC_TAB;
cCRLF VARCHAR(2) := CHR(13) || CHR(10);
LONG_SQL dbms_sql.varchar2s;
n INTEGER;
l INTEGER;
u INTEGER;
StartPos INTEGER;
BEGIN
--INITIIALISE RESULT
fResult := '';
HNDL := DBMS_SQL.OPEN_CURSOR;
l := Length( P_SQL );
u := ( l / 1000 ) + 1;
FOR n IN 1..u
LOOP
StartPos := ( n - 1 ) + 1;
LONG_SQL( n ) := SubStr( P_SQL, StartPos, 1000 );
END LOOP;
if HNDL <> 0 THEN
DBMS_SQL.PARSE ( c => HNDL,
statement => LONG_SQL,
lb => 1,
ub => u,
lfflg => false,
language_flag => DBMS_SQL.NATIVE );
--DBMS_SQL.PARSE( HNDL, P_SQL, DBMS_SQL.NATIVE);
d := DBMS_SQL.EXECUTE( HNDL );
DBMS_SQL.DESCRIBE_COLUMNS( HNDL, colCount, rec_tab);
FOR i in 1..colCount
LOOP
IF Add_Equals_Sign > 0 AND i > 1 THEN
fResult := ltrim( fResult || '=' || cCRLF || UPPER( rec_tab( i ).col_name ), cCRLF );
ELSE
fResult := ltrim( fResult || cCRLF || UPPER( rec_tab( i ).col_name ), cCRLF );
END IF;
END LOOP;
IF Add_Equals_Sign > 0 THEN
fResult := fResult ||'=';
END IF;
ELSE
fResult := '!!COULD NOT OPEN CURSOR!!';
fResult := P_SQL;
END IF;
RETURN fResult;
--Tidy Up
DBMS_SQL.CLOSE_CURSOR(HNDL);
Return 'EGG';
END;
--EXAMPLE USAGE
--Select GET_COLUNS_AS_LIST
--Select * from SALES_TYPE
--', 1) FROM DUAL;So I have ended up with this.
When I next get some time, I'd like to be able to strip out the table and simply output the results to an SQL Developer script window without having to go through the table.
Now this works - but if you see that I am doing something wrong - please point it out.
Many thanks,
Ant
CREATE OR REPLACE FUNCTION GET_COLUNS_AS_LIST( P_SQL IN CLOB, Add_Equals_Sign Number := 0)
RETURN VARCHAR2
IS
fResult VARCHAR2(32000);
HNDL NUMBER;
d NUMBER;
colCount INTEGER;
i INTEGER;
ChunkSize INTEGER;
rec_tab DBMS_SQL.DESC_TAB;
cCRLF VARCHAR(2) := CHR(13) || CHR(10);
LONG_SQL dbms_sql.varchar2s;
n INTEGER;
l INTEGER;
u INTEGER;
StartPos INTEGER;
BEGIN
--INITIIALISE RESULT
HNDL := 0;
ChunkSize := 4;
fResult := '';
--fResult := fResult|| 'A';
HNDL := DBMS_SQL.OPEN_CURSOR;
--l := Length( P_SQL );
l := dbms_lob.getLength( P_SQL );
--l := 50;
u := Round( l / ChunkSize ) + 1;
--fResult := fResult|| 'B';
FOR n IN 1..u
LOOP
StartPos := ( ( n - 1 ) * ChunkSize ) + 1;
IF StartPos = 0 THEN
StartPos := 1;
END IF;
--LONG_SQL( n ) := SubStr( P_SQL, StartPos, ChunkSize );
LONG_SQL( n ) := DBMS_LOB.SUBSTR( P_SQL, ChunkSize, StartPos );
END LOOP;
--fResult := fResult|| 'C';
if HNDL <> 0 THEN
DBMS_SQL.PARSE ( c => HNDL,
statement => LONG_SQL,
lb => 1,
ub => u,
lfflg => false,
language_flag => DBMS_SQL.NATIVE );
--DBMS_SQL.PARSE( HNDL, P_SQL, DBMS_SQL.NATIVE);
d := DBMS_SQL.EXECUTE( HNDL );
DBMS_SQL.DESCRIBE_COLUMNS( HNDL, colCount, rec_tab);
--fResult := fResult|| 'D';
FOR i in 1..colCount
LOOP
IF Add_Equals_Sign > 0 AND i > 1 THEN
fResult := ltrim( fResult || '=' || cCRLF || UPPER( rec_tab( i ).col_name ), cCRLF );
ELSE
fResult := ltrim( fResult || cCRLF || UPPER( rec_tab( i ).col_name ), cCRLF );
END IF;
END LOOP;
IF Add_Equals_Sign > 0 THEN
fResult := fResult ||'=';
END IF;
ELSE
fResult := '!!COULD NOT OPEN CURSOR!!';
END IF;
RETURN fResult;
--Tidy Up
IF HNDL <> 0 THEN
DBMS_SQL.CLOSE_CURSOR(HNDL);
END IF;
END;
-- !!!!HOW TO USE THIS FUNCTION!!!!
BEGIN
EXECUTE IMMEDIATE ('DROP TABLE RPT_COLNAME_LOOKUPS;');
COMMIT;
EXECUTE IMMEDIATE ('CREATE TABLE RPT_COLNAME_LOOKUPS( COLUMN_NAME CLOB );');
COMMIT;
EXCEPTION WHEN OTHERS THEN NULL;
END;
DECLARE
theSQL Clob;
myresult CLOB;
BEGIN
--CLEAR OUT PREVIOUS RWS
DELETE FROM RPT_COLNAME_LOOKUPS; COMMIT;
--ASSIGN THE SQL TO RUN IT FOR
theSQL := '
SELECT
EVENT.EVENT_ID AS COCK_SUCKER,
EVENT.EVENT_CODE, BLAH, BLAH, VERY LONG SQL STATEMENT';
--CALL THE FUNCTION PASSING IN THE SQL AND IF I WANT THE = OR NOT
SELECT GET_COLUNS_AS_LIST( theSQL, 1 ) INTO myresult FROM DUAL;
--INSERT THE RESULTS INTO A TABLE SO WE CAN GRAB THEM
INSERT INTO RPT_COLNAME_LOOKUPS SELECT myresult FROM DUAL;
COMMIT;
END;
--THEN LOOK AT THE COLUMNS NAMES IN THIS TABLE
--SELECT * FROM RPT_COLNAME_LOOKUPS;
--############################################################################# -
Can select resource content in anonymous block, but not in stored procedure
I know the problem relates to the ACLs but am curious about the following behaviour:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
running on Windows XP sp2
Trying to access an existing resource '/home/test/test.dtd'
/home is owned by SYS
/home/test is owned by me
/home/test.test.dtd is owned by me
The following SQL and anonymous block retrieve the content of the resource:
select extract(p.res,'/*').getClobVal()
from resource_view p
where p.any_path = '/home/test/test.dtd'
declare
alldata clob;
begin
select extract(p.res,'/*').getClobVal()
into alldata
from resource_view p
where p.any_path = '/home/test/test.dtd'
dbms_output.put_line(substr(alldata, 1, 255));
end;
BUT when I encapsulate the anonymous block in a stored procedure, I am told that the folder '/home/test/' does not exist.
As said, the problem related to the ACL on the folders, what I cannot understand, and caused me considerable confusion, is why I was unable to get the content from a stored procedure when I was able to do so from an anonymous block.
regards
RichardUse equals_path(res,'/home/test/test.dtd') = 1OK, OK, but how do you use wildcards (if you want to) since any_path like '/home/test%' works?
Who was the stored procedure owned by. Was it a stand-alone stored procedure or a
method on a package. If it was a method on a package is it AUTHID creator or AUTHID
definer.Everything apart from the '/home' folder is owned by the current user.
The PL/SQL was in a packaged procedure, a stand-alone stored procedure, and an anonymous block. It exhibited the same behaviour in each. All were defined with default AUTHID which is definers rights which is the same as the current user in this case. -
PL anonymous block does everything, but then gets stuck
We have a PL/SQL block that loops through a cursor, and inserts data into another table. We're having a strange issue with it... Every single line of code within it appears to function correctly... It does everything we want it to. The last line on it calls a simple function that writes a record to a table we made, to indicate it has completed. It does that, and we can see the record is inserted successfully.
The problem: even though we can see it did everything, it gets "stuck". If we run it as a anonymous block, the sql plus session will just stay stuck. Same thing if we turn it into a procedure and invoke it. It just stays stuck. Viewing it from OEM... We can see the session as "active", but it doesn't show that it's currently executing anything.
How can we go about figuring out what the problem is?
We've tried it on four databases... All windows platforms.. Three were oracle 10g, one was Oracle 11g. One more interesting note: one of the 10g ones... the problem does not occur... the script finishes fine. But, we don't know what is different about this database from the others.
We also notice the problem doesn't happen if we limit the amount of records... the initial cursor we process, if we limit it using "rownum < 100" or something like that, it will also always finish fine.
This is the script:
set echo on
set serveroutput on
declare
n_notes_count number;
n_records_read number;
dt_today date;
MYDATE DATE;
dt_comment_date date;
dt_updated_date date;
t_conv_exceptions "ODB"."CONVERSION_EXCEPTIONS" %ROWTYPE;
t_conv_exceptions_default "ODB"."CONVERSION_EXCEPTIONS" %ROWTYPE;
t_note_pad "ODB"."NOTE_PAD"%ROWTYPE;
t_note_pad_clear "ODB"."NOTE_PAD"%ROWTYPE;
t_pfcomm "PMI"."PFCOMM"%ROWTYPE;
c_created_by "ODB"."NOTE_PAD"."CREATED_BY" % type ;
-- Exceptions to be raised
ex_notes_number_blank EXCEPTION;
--ex_category_not_exists EXCEPTION;
--....more to come.....
CURSOR cur_notes IS
SELECT PF."MMNUM",
PF."MMLIN",
PF."MMDES",
PF."MMUSR",
PF."MMMM",
PF."MMDD",
PF."MMYY",
PF."MMCC",
--"pfcomm"."mmchr",
--"pfcomm"."mncmn",
--"pfcomm"."mmtype",
PF."MMUSRU",
PF."MMMMU",
PF."MMDDU",
PF."MMYYU",
PF."MMCCU"
FROM PMI."PFCOMM" PF
WHERE TRIM(PF."MMDES") IS NOT NULL
ORDER BY PF."MMNUM", PF."MMLIN";
BEGIN
-- Initialize variables
dt_today := "ODB"."PKG_APPLICATION_FUNCTION"."CURRENTDATETIME";
c_created_by :='PFCOMM';
-- Setup defaults for exceptions table
t_conv_exceptions_default."SCRIPT" := 'atlas_notes';
t_conv_exceptions_default."EXECUTION_DATE" := dt_Today;
t_conv_exceptions_default."CREATED_BY" := c_created_by;
-- Set up header record for exception
t_conv_exceptions := t_conv_exceptions_default;
t_conv_exceptions.column_01 := 'NOTES';
t_conv_exceptions.header := 'Y';
ODB.PKG_CONVERSIONS_EXCEPTIONS.writeException(t_conv_exceptions, false);
-- Count records in table
SELECT COUNT(*)
INTO n_records_read
FROM PMI."PFCOMM";
-- Delete previously inserted records
DELETE FROM "ODB"."NOTE_PAD" NP
WHERE NP."CREATED_BY" = c_created_by or NP."MODIFIED_BY" = c_created_by;
DELETE FROM "ODB"."NOTE_PAD" NP
WHERE NP."CREATED_BY" = 'PFCOMM2' or NP."MODIFIED_BY" = 'PFCOMM2';
DELETE FROM "ODB"."CONVERSION_EXCEPTIONS" CV
WHERE CV."CREATED_BY" IN (c_created_by,'PFCOMM2');
COMMIT;
/* Do Fetch here */
OPEN cur_notes;
LOOP
FETCH cur_notes
INTO t_pfcomm."MMNUM",
t_pfcomm."MMLIN",
t_pfcomm."MMDES",
t_pfcomm."MMUSR",
t_pfcomm."MMMM",
t_pfcomm."MMDD",
t_pfcomm."MMYY",
t_pfcomm."MMCC",
--"t_pfcommcomm"."mmchr",
--"t_pfcommcomm"."mncmn",
--"t_pfcommcomm"."mmtype",
t_pfcomm."MMUSRU",
t_pfcomm."MMMMU",
t_pfcomm."MMDDU",
t_pfcomm."MMYYU",
t_pfcomm."MMCCU";
EXIT
WHEN cur_notes % NOTFOUND;
-- Clear Variables
t_note_pad := t_note_pad_clear;
dt_comment_date := null;
dt_updated_date := null;
-- Begin variable assignments
t_conv_exceptions."COLUMN_01" := t_note_pad."NOTES";
t_note_pad."NOTES" := t_pfcomm."MMNUM";
t_note_pad."NOTES_TEXT" := t_pfcomm."MMDES";
-- Validate required fields
If t_note_pad."NOTES" is null Then
raise ex_notes_number_blank;
End if;
-- Sequence lines correctly
SELECT NVL( MAX("ODB"."NOTE_PAD"."NOTES_LINE"), 0)
INTO t_note_pad."NOTES_LINE"
FROM "ODB"."NOTE_PAD"
WHERE "ODB"."NOTE_PAD"."NOTES" = t_note_pad."NOTES"
-- Next note line number to insert
If t_note_pad."NOTES_LINE" is null Then
t_note_pad."NOTES_LINE" := 1;
Else
t_note_pad."NOTES_LINE" := t_note_pad."NOTES_LINE" + 1;
End if;
-- MMDDCCYY - Comment Date
If t_pfcomm."MMMM" > 0 Or t_pfcomm."MMDD" > 0 Or t_pfcomm."MMCC" > 0 Or t_pfcomm."MMYY" > 0 Then
SELECT TO_DATE(LPAD(t_pfcomm."MMMM",2,'0') || LPAD(t_pfcomm."MMDD",2,'0') || LPAD(t_pfcomm."MMCC",2,'0')|| LPAD( t_pfcomm."MMYY",2,'0'),'MMDDYYYY') INTO dt_comment_date FROM DUAL;
End if;
-- MMDDCCYY - Updated Date
If t_pfcomm."MMMMU" > 0 Or t_pfcomm."MMDDU" > 0 Or t_pfcomm."MMCCU" > 0 Or t_pfcomm."MMYYU" > 0 Then
SELECT TO_DATE(LPAD(t_pfcomm."MMMMU",2,'0') || LPAD(t_pfcomm."MMDDU",2,'0') || LPAD(t_pfcomm."MMCCU",2,'0')|| LPAD( t_pfcomm."MMYYU",2,'0'),'MMDDYYYY') INTO dt_updated_date FROM DUAL;
End if;
-- Updated user information
IF dt_updated_date is not null Then
t_note_pad."CREATED_BY" := TRIM(t_pfcomm."MMUSRU");
t_note_pad."CREATED_DATE" := dt_updated_date;
Elsif dt_comment_date is not null Then
t_note_pad."CREATED_BY" := TRIM(t_pfcomm."MMUSR");
t_note_pad."CREATED_DATE" := dt_comment_date;
Else
t_note_pad."CREATED_BY" := c_created_by;
t_note_pad."CREATED_DATE" := dt_today;
END IF;
/* Validate mandatory fields of TRAX table */
IF t_note_pad.NOTES = 0 THEN
t_note_pad.NOTES :=null;
End If;
IF t_note_pad.NOTES_LINE is null THEN
t_note_pad.NOTES_LINE := 1;
End If;
IF TRIM(t_note_pad.PRINT_NOTES) is null Then
t_note_pad.PRINT_NOTES := 'YES';
END IF;
IF TRIM(t_note_pad.NOTES_CATEGORY) is null THEN
t_note_pad.NOTES_CATEGORY := 'NORMAL';
END IF;
If TRIM(t_note_pad."CREATED_BY") is null Then
t_note_pad."CREATED_BY" := c_created_by;
End if;
If TRIM(t_note_pad."MODIFIED_BY") is null Then
t_note_pad."MODIFIED_BY" := c_created_by;
End if;
If TRIM(t_note_pad."MODIFIED_DATE") is null Then
t_note_pad."MODIFIED_DATE" := dt_today;
End if;
If TRIM(t_note_pad."CREATED_DATE") is null Then
t_note_pad."CREATED_DATE" := dt_today;
End if;
-- end structure validation
/* Do Insert here here */
insert into "ODB"."NOTE_PAD"
values t_note_pad;
commit;
END LOOP;
dbms_output.put_line('After loop.');
CLOSE cur_notes;
-- Update NOTES Switch
SELECT MAX(NT."NOTES") + 100
INTO n_notes_count
FROM "ODB"."NOTE_PAD" NT
UPDATE "ODB"."SYSTEM_TRAN_CONFIG"
SET "CONFIG_NUMBER" = n_notes_count,
"MODIFIED_BY" = 'TRAXCNV',
"MODIFIED_DATE" = dt_today
WHERE ( ODB."SYSTEM_TRAN_CONFIG"."SYSTEM_TRANSACTION" = 'CONFIGURATION' ) AND
( ODB."SYSTEM_TRAN_CONFIG"."SYSTEM_CODE" ='NOTES' )
COMMIT;
dbms_output.put_line('before audit.');
/* Do Save Audit record */
"ODB"."PKG_CONVERSIONS_EXCEPTIONS".writeAudit(t_conv_exceptions."SCRIPT",c_created_by,n_records_read,dt_today);
dbms_output.put_line('After audit.');
SELECT SYSDATE INTO MYDATE FROM DUAL;
-- Begin exception handling.
exception
when ex_notes_number_blank then
t_conv_exceptions.exception_description := 'Note number is blank.';
ODB.PKG_CONVERSIONS_EXCEPTIONS.writeException(t_conv_exceptions, false);
when others then
t_conv_exceptions.exception_description := substr(SQLERRM,1,1000);
ODB.PKG_CONVERSIONS_EXCEPTIONS.writeException(t_conv_exceptions, false);
RAISE;
-- End exception handling.
dbms_output.put_line('before end.');
END ;
/Avoid row-at-a-time processing if at all possible (cursor for loops, periodic commits, etc).
Try adding some calls to dbms_application_info.set_module (or set_action) in order to find out where your code is. -
INVALID CURSOR - Anonymous Block calling Cursor in function
I am getting an error when trying to call my cursor.
CREATE OR REPLACE PACKAGE tax_update
AS
TYPE gencur IS ref cursor;
FUNCTION tax_sf
p_state IN bb_tax.state%type,
p_thecursor IN OUT gencur
RETURN NUMBER;
END;
CREATE OR REPLACE PACKAGE BODY tax_update
AS
FUNCTION tax_sf
p_state IN bb_tax.state%type,
p_thecursor IN OUT gencur
RETURN NUMBER
IS
lv_taxrate NUMBER;
BEGIN
OPEN p_thecursor FOR
SELECT taxrate
FROM bb_tax
WHERE state = p_state;
RETURN lv_taxrate;
END;
END;
DECLARE
tax_cur tax_update.gencur;
rec_tax bb_tax%rowtype;
BEGIN
LOOP
FETCH tax_cur INTO rec_tax;
EXIT WHEN tax_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(rec_tax.taxrate);
END LOOP;
END;
DECLARE
ERROR at line 1:
ORA-01001: invalid cursor
ORA-06512: at line 6Assignment is to create a package that will hold tax rates by state in a packaged cursor. The package will contain a function that can receive a 2 character state abbr. as an argument and find a match in the cursor and return the tax rate for tha tstate. An anonymous block will test the function with state of NC.
Can anyone assist?You would need to call the function to open the cursor before you try to fetch from the cursor
DECLARE
tax_cur tax_update.gencur;
rec_tax bb_tax%rowtype;
l_some_number number;
BEGIN
l_some_number := tax_update.tax_sf( <<some state parameter>>, tax_cur );
LOOP
FETCH tax_cur INTO rec_tax;
EXIT WHEN tax_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(rec_tax.taxrate);
END LOOP;
END;A couple of points, though.
1) Your function returns a NUMBER but that NUMBER will always be NULL. It seems rather unlikely that this is really what you want. It would seem to make more sense for the function to return the cursor rather than returning a superfluous number.
2) Your function requires a `bb_tax.state%type` parameter. But your anonymous block doesn't seem to have any concept of a state so I'm not sure what you want to pass in there.
3) Looking at the code, it seems a bit odd that your cursor returns a single column of data. If a state can have multiple rates, wouldn't you need to select some additional criteria in order to figure out which sort of tax each row represents or to otherwise differentiate different rows? If a state can only have a single tax rate, it makes no sense to open a cursor that is only going to ever return a single row.
4) There is no need to declare your own weak ref cursor type (tax_update.gencur). You can just use the Oracle built-in type SYS_REFCURSOR.
Justin -
Reference value of an SQLPLUS variable in a PL/SQL anonymous block
All,
Is there a way of referencing an SQLPLUS variable within a PL/SQL anonymous block. See my example below........
sqlplus -s /@${L_DB_SID} <<-ENDOFSQL >> ${L_LOGFILE}
SET FEEDBACK OFF
SET PAGES 0
SET SERVEROUTPUT ON
WHENEVER SQLERROR EXIT SQL.SQLCODE
WHENEVER OSERROR EXIT 2
VARIABLE l_ret_sts NUMBER;
VARIABLE l_ret_msg VARCHAR2(300);
exec sh_plsql_owner.sh\$secure_batch.p\$set_role(p_ret_sts => :l_ret_sts);
begin
if :l_ret_sts > 0 then
dbms_output.put_line('l_ret_sts:'||:l_ret_sts||':SECURITY');
else
${L_PLSQL_PROG}(p_ret_type => 0, p_ret_sts => :l_ret_sts, p_ret_msg => :l_ret_msg);
dbms_output.put_line('l_ret_sts:'||NVL(:l_ret_sts,0));
dbms_output.put_line('l_ret_msg:'||:l_ret_msg);
end if;
end;
exit
ENDOFSQL
I need to be able to reference :l_ret_sts in the begin block using the if statement "if :l_ret_sts > 0 then"
:l_ret_sts is populated in a procedure call beforehand.
However it seems as though the begin block cannot reference the value returned to :l_ret_sts.
Any ideas.
Ian.Managed to solve this. I put my call to the package that the role enables via dynamic sql....
sqlplus -s /@${L_DB_SID} <<-ENDOFSQL >> ${L_LOGFILE}
SET FEEDBACK OFF
SET PAGES 0
SET SERVEROUTPUT ON
WHENEVER SQLERROR EXIT SQL.SQLCODE
WHENEVER OSERROR EXIT 2
VARIABLE l_ret_sts NUMBER;
VARIABLE l_ret_msg VARCHAR2(300);
exec dbms_application_info.set_client_info('CONTROL-M');
exec sh_plsql_owner.sh\$secure_batch.p\$set_role(p_ret_sts => :l_ret_sts);
declare
v_text varchar2(500);
begin
if :l_ret_sts > 0 then
dbms_output.put_line('l_ret_sts:'||:l_ret_sts||':SECURITY');
else
v_text := 'begin ${L_PLSQL_PROG}(p_ret_type => 0, p_ret_sts => :1, p_ret_msg => :2);end;';
execute immediate v_text using in out :l_ret_sts, in out :l_ret_msg;
dbms_output.put_line('l_ret_sts:'||NVL(:l_ret_sts,0));
dbms_output.put_line('l_ret_msg:'||:l_ret_msg);
end if;
end;
exit
ENDOFSQL
Cheers
Ian. -
Getting value with an anonymous block using ODP
Hi all!
I have a problem I hope someone can help me with. I believe it to be a minor one. I am trying to imbed an anonymous block into my .net app and use it dynamically to get a value from the database depending on the values in a tables. Since my procedure is quite large I am displaying a small example proc for simplicity purposes. Basically I want to execute an anonymous block from my app that will return a value (not a row or rows) from the database. The code is below:
Private Sub test()
Dim cn As New OracleConnection(profileString)
Try
Dim sb As New System.Text.StringBuilder
sb.Append("Declare ")
sb.Append("v_maxnum varchar2(6); ")
sb.Append("Begin ")
sb.Append("Select max(to_number(email_address_id)) into ")
sb.Append("v_maxnum from CVWH14_CDRV_TEST.EMAIL_ADDRESS_TBL; ")
sb.Append("dbms_output.put_line(v_maxnum); ")
sb.Append("Exception ")
sb.Append("When Others ")
sb.Append("Then ")
sb.Append("dbms_output.put_line('Program run errors have occurred.'); ")
sb.Append("End; ")
Dim cmd As New OracleCommand(sb.ToString, cn)
With cmd
cmd.CommandType = CommandType.Text
Dim parm As New OracleParameter
parm.ParameterName = "v_maxnum"
parm.OracleType = OracleType.VarChar
parm.Direction = ParameterDirection.Output
parm.Size = 6
cmd.Connection.Open()
Dim ret As Object = cmd.ExecuteScalar()
Dim res As String = cmd.Parameters.Item(0).Value.ToString -- **Error is occuring here**
cmd.Connection.Close()
cmd.Dispose()
End With
Catch ex As Exception
MessageBox.Show(ex.Message, "Error")
'End If
If cn.State = ConnectionState.Open Then
cn.Close()
End If
End Try
End Sub
The exception error reads "Invalid Index 0 for this OracleParameterCollection with Count=0."
If I can figure out how to get a parameter value from the database via the anonymous block, I can apply the logic to the real application. Any help or direction I could receive would be greatly appreciated. Thanks for reading this post!Thank you for responding. The code that I posted was just one of many ways I have tried. I retried the proc making just 2 changes:
Private Sub test()
Dim cn As New OracleConnection(profileString)
Try
Dim sb As New System.Text.StringBuilder
sb.Append("Declare ")
sb.Append("v_maxnum varchar2(6); ")
sb.Append("Begin ")
sb.Append("Select max(to_number(email_address_id)) into ")
sb.Append("v_maxnum from CVWH14_CDRV_TEST.EMAIL_ADDRESS_TBL; ")
sb.Append("dbms_output.put_line(:v_maxnum); ") -- !Changed this to a bind variable!
sb.Append("Exception ")
sb.Append("When Others ")
sb.Append("Then ")
sb.Append("dbms_output.put_line('Program run errors have occurred.'); ")
sb.Append("End; ")
Dim cmd As New OracleCommand(sb.ToString, cn)
With cmd
cmd.CommandType = CommandType.Text
Dim parm As New OracleParameter
parm.ParameterName = ":v_maxnum" -- !Changed this to a bind variable!
parm.OracleType = OracleType.VarChar
parm.Direction = ParameterDirection.Output
parm.Size = 6
cmd.Connection.Open()
Dim ret As Object = cmd.ExecuteScalar() -- !The error is now occuring here!
Dim res As String = cmd.Parameters.Item(0).Value.ToString
cmd.Connection.Close()
cmd.Dispose()
End With
Catch ex As Exception
MessageBox.Show(ex.Message, "Error")
If cn.State = ConnectionState.Open Then
cn.Close()
End If
End Try
End Sub
I am now getting the error message "Not all variables bound". Any more help or direction that you could throw my way would be greatly appreciated. -
Printing the Package output from Anonymous block
Hi,
I need to call the below package from anonymous block and get the output.
Could you let me know.
I tried using this, but i don't get data.
===========Anonymous Block=====================================================================
declare
var xxdc.xxdc_sr_log_his_pkg.sr_tbl_type;
l_sr_idx_bi BINARY_INTEGER := 0;
BEGIN
xxdc.xxdc_sr_log_his_pkg.service_record('14040',var);
dbms_output.put_line('CLAIM_CREDIT_OFFERS :'||var(l_sr_idx_bi).qa_credit_offers(l_sr_idx_bi).character1 );
end;
=============================================================================================
============================================================================================
Package Spec
TYPE cr_offer_type IS TABLE OF apps.qa_results_v%ROWTYPE
INDEX BY BINARY_INTEGER;
TYPE sr_rec_type IS RECORD
(task_status apps.jtf_task_statuses_tl.name%TYPE
,task_type apps.jtf_task_types_tl.name%TYPE
,qa_credit_offers cr_offer_type
TYPE sr_tbl_type IS TABLE OF sr_rec_type
INDEX BY BINARY_INTEGER;
PROCEDURE service_record(p_service_req_num IN VARCHAR2
,p_service_req_tbl OUT sr_tbl_type
Package Body
FOR emp_row_rec IN cur_credit_off
LOOP
l_sr_tbl(l_sr_idx_bi).qa_credit_offers(l_sr_idx_bi).character1 := emp_row_rec.character1;
--dbms_output.put_line( l_sr_tbl(l_sr_idx_bi).qa_credit_offers(l_sr_idx_bi).character1); --commenting for testing
l_sr_idx_bi := l_sr_idx_bi + 1;
END LOOP;
p_service_req_tbl := l_sr_tbl;
=============================================================================================
ThankHi,
Did you issue the SQL*Plus command
SET SERVEROUTPUT ON
or, if you're using some other front end, its equivalent?
Can you ever see output from dbms_output? For example, what happens when you run this?
SET SERVEROUTPUT ON
BEGIN
dbms_output.put_line ('Hello, world!');
END;
Since I don't have your tables, I can't actually run your code. If you'd post CREATE TABLE and INSERT statements, or re-write the package to reference commonly available tables, such as those in the scott schema, then I could test it. -
Handling loop exception in an anonymous block
hI ,
I have a an anonymous block
declare
cursor
local variables
begin
open cursor
some statements
loop
some statement ;
some othet statement;
select something from sometablein local variable where some field = cursor.value ;
some more statements
end loop
some more statements
exception
when whatever
then whatever
end;
Now my select statement may give a NO_DATA_FOUND error which i want to catch and ignore .
Pls tell me how to do it.So that mean you can have multiple exception blocks
in a pl/sql script ?You can have one exception handler per execution block.
Execution blocks can be nested inside other execution blocks.
Handling the error within one exception handler causes execution to return out to the execution of the parent block.
Raising an error within one exception handler causes the execution to go straight to the exception handler of the parent block.
e.g.
-- execution block 1
BEGIN
-- execution block 2
DECLARE
myvar number;
BEGIN
SELECT mynumber INTO myvar FROM mytable;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL; -- handle error and return execution to block 1
WHEN OTHERS THEN
RAISE; -- raise any other errors to block 1 exception handler
END; -- block 2
DBMS_OUTPUT.PUT_LINE('Select took place successfully or no data was found');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('An error occurred either in block1 or in block 2 (except for NO_DATA_FOUND in block2)');
END; -
Oracle SQL Developer 3.0: PL/SQL debugging of anonymous blocks: ISSUES
Hello,
I just downloaded the Oracle SQL Developer 3.0. I have been using the EA releases as they came into existence and was happy to see the released version. So I immediately tried to debug an anonymous block (something I did not try to do in the EA releases), and nothing happened.
The "Debug" was grayed out and the key-chord "ctrl-shift-F10" did nothing. I found this forum:
Re: 30EA1: anonymous block debugging?
and followed Vadim Tropashko's advice. This did nothing for my anon. block but worked fine for the simple example.
So I started to whittle my anon. block down to find the culprit, here is a repeatable breaking point for me:
declare
stmt1 long;
stmt2 long;
stmt3 long;
stmt4 long;
p_data varchar2( 500 );
i varchar2( 10 );
BEGIN
STMT1 := 1;
STMT2 := 1;
STMT3 := 1;
STMT4 := 1;
--the moment this is in the block "Debug" is no longer an option
select
SendDocumentResult
into
p_data
from
XMLTABLE( '/data'
PASSING
xmltype.createxml( '<?xml version="1.0" encoding="utf-8"?><data><SendDocumentResult>test</SendDocumentResult></data>' )
COLUMNS SendDocumentResult varchar2( 1000 ) PATH 'SendDocumentResult' ) ;
end;The moment I have the SELECT INTO ... XMLTABLE() it fails (a normal SELECT INTO works just fine).
Is this a problem with my environment or is a problem with SQL Developer 3.0.04. Looking over K's comments, it seems the debug worked for 'simple' blocks, so I wonder if this is just out-of-scope...
My environment:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for IBM/AIX RISC System/6000: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
and Oracle SQL Developer
3.0.04 (Buld Main 04.34 with bundled Java) on a Window's XP box.Thanks, I'll survive. Just my luck, the first item I try to anon. debug didn't work! :)
thanks, hopefully this problem will be few and far between -
Anonymous Block in SQL Developer
I am using SQL Developer 3.1x and trying to run a pretty simple Anonymous block and am having trouble declaring a variable. This block runs successfully:
set SERVEROUTPUT on
--declare
-- V_CRT := CHR(13);
begin
for t in (select owner, table_name from dba_tables where owner = 'ABC123)
LOOP
DBMS_STATS.GATHER_TABLE_STATS(t.owner, t.table_name);
end loop;
DBMS_OUTPUT.PUT_LINE('Statistics Calculations complete');
DBMS_OUTPUT.PUT_LINE('Begin Record Counts');
-- DBMS_OUTPUT.PUT_LINE(v_crt);
-- DBMS_OUTPUT.PUT_LINE(V_CRT);
end;
If I remove my comments in an effort to include my Declare statement, I receive: PLS-00103: Encountered the symbol "=" when expecting one of the following
How do I declare / initialize the variable "v_crt"? Admittedly this is a VERY basic Block but I just started to build out a more "robust" procedure and am getting stumped.
Thank you for your help!The symbol *:=* is for assignment, not variable declaration. Just give the variable name and then its type, like this:DECLARE
V_CRT VARCHAR2(13);You can give it a default value if you want to.DECLARE
V_CRT VARCHAR2(13) := 'Hello';Looks like you want it to be a carriage return character.DECLARE
V_CRT VARCHAR2(1) := CHR(13); -
The output is always "anonymous block completed"
Hi ,
I have written a simple Stored Procedure as shown :
create or replace procedure display
ename out emp.ename%type
is
begin
select ename into ename from emp where empno='7369';
end;
I tried to execute the above using this block
declare
ename emp.ename%type;
begin
display(ename);
dbms_output.put_line(ename);
end;
I am always getting the Output as "anonymous block completed" and nothing else .
Please help . Thanks .Hi:
First type this to enable the output.
SET SERVEROUTPUT ON;Saad, -
Select after anonymous blocks no INTO allowed
hi
I need to run an EXECUTE IMMEDIATE command to create a SEQUENCE in oracle sql 10g. I can only call EXECUTE IMMEDIATE between a BEGIN and a END; thus creating
an anonymous block
after the EXECUTE I need to do a select
the problem is I get an error no matter what I have after the END;
I cannot put the SELECT in the anonymous block because then I need to use INTO and I don't want to use INTO I just have to da a select
can this be done in any way in oracle 10g(I am using the web interface) ?
this is very frustrating for me as in mysql and ms sql this is sooooo simple and in oracle it looks impossible
thank you in advanceuser10624880 wrote:
so this cannot be done with oracle?
the selects will return multiple rows what should I do with those rows
I want them to appear on the screen when I run the script with the web interfaceSo you do want to actually capture the data and do something with it.
If you are just running an SQL script through something like SQL*Plus you can just select the data and it will appear on the screen, but if you are doing it within PL/SQL code then you have to capture that data and output it via the appropriate means. Remember that PL/SQL is a process that is running on the database server so it doesn't have an interface to display data on for the user.
You could select the data into an array structure (bulk collect), or use a select loop and then output it using something like DBMS_OUTPUT.PUT_LINE, assuming that your interface is going to read the DBMS_OUTPUT buffer and display the data.
You haven't provided enough information about what you are really doing or the environment you are trying to run it through, for us to be able to give much more advice.
As for whether it can be done with Oracle... yes it can, if you understand the concepts correctly. You can't just select data within PL/SQL and expect it to be displayed on your screen; as I said, the PL/SQL process on the database server knows nothing about your screen. -
What is "anonymous block completed" ?
I run the following package in sql developer but always come out " anonymous block completed"
I would like to what is "anonymous block completed" ? Is it an error? What we need to bear in mind?
BEGIN
PKG_VERIFICATION2.SP_CHK();
END;Each call to Oracle, returns a return or exit code.
For a successful call, the code ORA-0000 is returned.
Oracle assigned the text message "+ORA-0000: normal, successful completion+" to that code.
Many clients will however use a tad more meaningful messages. If the call was to create a table, the client can display "+Table created+" as the response message. Or "+Table altered+" for an alter table statement.
Likewise, for an anonymous PL/SQL block, the client can respond with a "+anonymous block completed+". -
Basic anonymous block which drops and creates a table
Version: 11.2.0.3
I am fairly new to PL/SQL.
We have a table named CHK_CNFG_DTL.
I want to create a backup table for CHK_CNFG_DTL which will be named like CHK_CNFG_DTL_BKP_<timestamp> eg: CHK_CNFG_DTL_BKP_JULY_22_2013
Creation of this backup table has to be automated so, I want to create an anonymous block which will first drop the existing backup table and then create a new backup table from the original table.
The below code works fine. But the very first time when you run it , the loop won't iterate because there is no such table named CHK_CNFG_DTL_BKP%.
declare
v_stmt varchar2(1000);
v_date date;
begin
for rec in
(select * from user_tables where table_name like 'CHK_CNFG_DTL_BKP%' )
loop
begin
execute immediate 'alter session set nls_date_format=''DD_MON_YYYY''';
v_stmt := 'drop table '||rec.table_name|| ' purge';
dbms_output.put_line(v_stmt); ----- Drops Old backup table
execute immediate v_stmt;
select sysdate into v_date from dual;
v_stmt := 'create table CHK_CNFG_DTL_BKP_'||to_date(v_date)||' as select * from CHK_CNFG_DTL';
dbms_output.put_line('Creating Bkp table CHK_CNFG_DTL_BKP_'|| to_date(v_date) );
dbms_output.put_line(v_stmt);
execute immediate v_stmt; --- Creates new Backup table
exception
when others
then
dbms_output.PUT_LINE (rec.table_name||'-'||sqlerrm);
end;
end loop;
end;
PL/SQL procedure successfully completed.
-- Backup table not created.
SQL> select table_name from user_Tables where table_name like 'CHK_CNFG_DTL%';
TABLE_NAME
CHK_CNFG_DTL
Of course, this can fixed by creating a table like bleow before executing the anonymous block
SQL> create table CHK_CNFG_DTL_BKP_JULY_22_2013 (x varchar2(37));
Table created.
and now the block will succesfully run like
24 end;
25 /
drop table CHK_CNFG_DTL_BKP_JULY_22_2013 purge
Creating Bkp table CHK_CNFG_DTL_BKP_22_JUL_2013
create table CHK_CNFG_DTL_BKP_22_JUL_2013 as select * from CHK_CNFG_DTL
PL/SQL procedure successfully completed.
But this is going to production . We can't a table like CHK_CNFG_DTL_BKP_JULY_22_2013 without a proper business reason.
How can I modify the above code so that if even if there is no such table like 'CHK_CNFG_DTL_BKP%' , it will proceed to create the backup table?Hi,
Why won't you push the creation of the backup out of the loop ?
declare
v_stmt varchar2(1000);
v_date date;
begin
for rec in
(select * from user_tables where table_name like 'CHK_CNFG_DTL_BKP%' )
loop
begin
execute immediate 'alter session set nls_date_format=''DD_MON_YYYY''';
v_stmt := 'drop table '||rec.table_name|| ' purge';
dbms_output.put_line(v_stmt); ----- Drops Old backup table
execute immediate v_stmt;
exception
when others
then
dbms_output.PUT_LINE (rec.table_name||'-'||sqlerrm);
end;
end loop;
select sysdate into v_date from dual;
v_stmt := 'create table CHK_CNFG_DTL_BKP_'||to_date(v_date)||' as select * from CHK_CNFG_DTL';
dbms_output.put_line('Creating Bkp table CHK_CNFG_DTL_BKP_'|| to_date(v_date) );
dbms_output.put_line(v_stmt);
execute immediate v_stmt; --- Creates new Backup table
end;
Maybe you are looking for
-
Can I get rid of the MobileMe sync icon in Mountain Lion?
I recently set up a new MacBook Pro by using setup assistant to restore from a Time Machine backup of an old Snow Leopard machine. In general it's worked fine, but I still seem to have the old MobileMe sync icon in the menu bar, and as far as I can w
-
How fix "Adobe Photoshop CS6 has stopped working" error in Win7?
Hi All, I'm getting the following error message when ever I try to use Move Tool and the program gets close. "Adobe Photoshop CS6 has stopped working. A problem caused the program to stop working correctly. Windows will close the program and notify y
-
"Scrolled" Legend in DS 1.3 charts
Hi, After upgrading DS from 1.2 to 1.3 I observed strange behaviour of legend in one of my charts. After the upgrade legend entries are squeezed to one row only and a scrollbar appears below, so not all labels are visible for user. BEFORE in DS 1.2 A
-
Patch level for SAPGUI 7.10 in ECC 6.0
Hi all, we are upgrading our ECC 6.0 SP 13 to SP18. Actually SAPGUI patch level is 4; is there a matrix compatibility or a link in order to check with patch level for SAPGUI is recomended. Thank's in advance. Best regards. Maurizio Ortolani
-
Front Row crashes my Macbook Pro
When playing music in Front Row, the system will freeze approximately 10 to 15 minutes into play time. Time is not consistent. My Screen Saver is disabled. Any ideas? I have all of the latest updates as of May 11, 2008.