Calling a Oracle Package in Jasper Report - oracle

I have a requirement where a existing Oracle package needs to be executed and the calculated fields from the package are stored in a separate table. Once the Oracle package has been called then the reports needs to be generated. Now when I am trying to call that package from Jasper Studio I am getting this error :
The call statement I am trying to run in Jasper :
{call PKG_SR_ENGLAND.GenerateReturn($P{p_start_date} , $P{p_end_date} , $P{p_quarterly_run} , $P{ORACLE_REF_CURSOR} , $P{p_debug}) }
I am passing the same set of parameters with the same data types as present in the procedure but still the error persists.
This is the package that is being called :
create or replace PACKAGE PKG_SR_ENGLAND AS
PROCEDURE GenerateReturn (p_start_date IN VARCHAR2,
p_end_date IN VARCHAR2,
p_quarterly_run IN CHAR,
p_run_number OUT NUMBER,
p_debug IN CHAR DEFAULT 'N');
END PKG_SR_ENGLAND;
Could someone please help in understanding what is missing or what needs to be done to get this working in Jasper Studio? This package needs to be called before the other reports are executed.
The statement throws the error :
{call PKG_SR_ENGLAND.GenerateReturn($P{p_start_date} , $P{p_end_date} , $P{p_quarterly_run} , $P{ORACLE_REF_CURSOR} , $P{p_debug}) }
Caused by: java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'GENERATERETURN'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

Related

Cannot execute a stored procedure in Oracle

Here is a simple example using Toad for Data Analysts 3.0.1.1734. I have full permissions on the schema JSWEENEY.
Create the table
CREATE TABLE JSWEENEY.TEMP_SQL
(
SQL VARCHAR2(3000)
);
Create the procedure
CREATE OR REPLACE PROCEDURE JSWEENEY.SP_INSERT_SQL
IS
BEGIN
INSERT INTO JSWEENEY.TEMP_SQL(SQL) VALUES('SELECT * FROM TEMP_SQL');
COMMIT;
END JSWEENEY.SP_INSERT_SQL;
/
Execute the procedure:
BEGIN
JSWEENEY.SP_INSERT_SQL;
END;
The first error:
ORA-06550: line 2, column 11:
PLS-00905: object JSWEENEY.SP_INSERT_SQL is invalid
ORA-06550: line 2, column 2: PL/SQL: Statement ignored
Execute the procedure:
BEGIN
EXECUTE JSWEENEY.SP_INSERT_SQL;
END;
The second error:
ORA-06550: line 2, column 10:
PLS-00103: Encountered the symbol "JSWEENEY" when expecting one of the following: := . ( # % ; immediate The symbol ":=" was substituted for "JSWEENEY" to continue.
Any suggestions would be greatly appreciated.
When you compile the procedure you will get an error; if your client doesn't display that then you can query the user_errors view (or all_errors if you're creating it in a different schema) to see the problem. Here it will be complaining that:
LINE/COL ERROR
-------- -----------------------------------------------------------------
6/13 PLS-00103: Encountered the symbol "." when expecting one of the following:
;
It's valid to use the schema name in the create call; but not as part of the end. So if you need to specify the schema at all - which you don't if you're creating an object in your own schema, but your reference to permissions makes it sound like you aren't - then it should be:
CREATE OR REPLACE PROCEDURE JSWEENEY.SP_INSERT_SQL
IS
BEGIN
INSERT INTO JSWEENEY.TEMP_SQL(SQL) VALUES('SELECT * FROM TEMP_SQL');
COMMIT;
END SP_INSERT_SQL;
/
Your second error is because execute on its is a client command (in SQL*Plus and relations), not a PL/SQL statement. The error refers to immediate because PL/SQL does have an execute immediate statement which is used for dynamic SQL, not for making static calls to procedures. Your first syntax to run the procedure is correct, once the procedure itself is valid:
BEGIN
JSWEENEY.SP_INSERT_SQL;
END;
/
try this edited the SQL statement.
create table TEMP_SQL ( col1 varchar2(100));
CREATE OR REPLACE PROCEDURE SP_INSERT_SQL
AS
BEGIN
INSERT INTO TEMP_SQL SELECT * FROM TEMP_SQL;
COMMIT;
END SP_INSERT_SQL;

Use string concatenation in UPDATEXML()

I want to write an update script for my oracle db. I want to replace old XML node values with new ones. But I need to do this for many values so I wanna outsource the logic in a procedure.
This is what I've come up with.
CREATE OR REPLACE PROCEDURE MY_PROCEDURE(
old_name IN NVARCHAR2,
new_name IN NVARCHAR2
)
AS
BEGIN
UPDATE
MY_TABLE
SET
ENTITY = UPDATEXML(ENTITY, '/*/Section', '<Section>' || new_name || '</Section>', 'xmlns="http://foo.bar.com/baz"')
WHERE
EXTRACTVALUE(ENTITY, '/*/Section', 'xmlns="http://foo.bar.com/baz"') = old_name;
END;
This is actually working really well - when I don't use string concatenation in UPDATEXML(). When I start using concatenation the execution of the procedure stops working / starts to throw exceptions.
I've also tried CONCAT(CONCAT('<Section>', new_name), '</Section>') instead of the ||-Operator. Didn't work out either.
The exception I get running the procedure in Oracle SQL Developer
ORA-06550: line 2, column 5:
PLS-00905: object MY_DB.MY_PROCEDURE is invalid
ORA-06550: line 2, column 5:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:

PL/SQL: Receiving an array as a parameter and looping through it

I am trying to process an array of string values (single column) called from C++ code, and iterate over it using PL/SQL in a stored procedure.
For that I have created a new type:
CREATE OR REPLACE TYPE "DEVICELIST_OBJTYP" AS OBJECT
(DEVICE VARCHAR2(46 BYTE))
/
CREATE OR REPLACE TYPE devicelist_coltyp AS
TABLE OF devicelist_objtyp;
/
The PL/SQL procedure looks as follows (with seemingly irrelevant logic removed):
PROCEDURE pr_MyProc
( p_UserId IN USERSTAB.USRID%TYPE,
p_DeviceList IN DEVICELIST_OBJTYP,
p_ResCode OUT NUMBER,
p_ResMsg OUT VARCHAR2)
IS
BEGIN
...
FOR i IN 1 .. p_DeviceList.COUNT LOOP
dbms_output.put_line(i);
--more code to follow..
END LOOP;
...
END;
/
When I try to compile the procedure, I fail with:
Warning: Package Body created with compilation errors.
Errors for PACKAGE BODY PA_HANDLE_ASSETS:
LINE/COL ERROR
-------- -----------------------------------------------------------------
135/17 PL/SQL: Statement ignored
135/44 PLS-00302: component 'COUNT' must be declared
BEGIN
*
ERROR at line 1:
ORA-20002:
ORA-06512: at line 4
How should I iterate over the nested table object without providing the .COUNT attribute? When I tried without the .COUNT, I errored out with something in the line of ~"p_DeviceList is not a cursor".
Should I convert the p_DeviceList object to another type of data?

Creating Oracle SQL Java Function does not work

When trying to create oracle SQL java function to generate random UUID as described in this StackOverflow answer, I get following error:
sql> CREATE or REPLACE FUNCTION random_uuid
RETURN VARCHAR2
AS LANGUAGE JAVA NAME 'java.util.UUID.randomUUID() return java.lang.String'
[2019-01-29 09:28:29] [99999][17110] Warning: execution completed with warning
[2019-01-29 09:28:29] completed in 23 ms
[2019-01-29 09:28:29] 3:78:PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
[2019-01-29 09:28:29] ;
[2019-01-29 09:28:29] The symbol ";" was substituted for "end-of-file" to continue.
Even this is just a warning, calling it does not work afterwards:
sql> select random_uuid() from dual
[2019-01-29 09:36:28] [65000][6575] ORA-06575: Package or function RANDOM_UUID is in an invalid state
I use IntelliJ IDEA's Database Console to execute the script. What is wrong?
EDIT: Mine original script does contain semicolon at the end:
create or replace function random_uuid return varchar2 as
language java
name 'java.util.UUID.randomUUID() return String';
Adding ';' after the String does not help:
create or replace function random_uuid return varchar2 as
language java
name 'java.util.UUID.randomUUID() return String;';
Since the problem appears to be the IDE not recognising where the statement terminates then you can try to wrap it in a PL/SQL anonymous block and use EXECUTE IMMEDIATE to force it to parse the statement correctly:
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE FUNCTION RandomUUID RETURN VARCHAR2 AS LANGUAGE JAVA NAME ''java.util.UUID.randomUUID() return java.lang.String'';';
END;
/

Modify Oracle Package code

I have added two fields to a table called CartRequests. We store JSON text in this table sent from our e-commerce package for each of our online orders. This helps us to be able to rebuild orders that fail for any reason. I am adding these 2 fields to facilitate faster searches because, currently, we have to only search the json (CR_JSON) text for values and it takes anywhere from 30 secs to a minute to find anything using a like clause. Most of the time, we are searching for either the CustomerID or OrderID.
I have the following package that puts the sent JSON into the CartRequests table, it was written
by another developer more familiar with PL/SQL:
CREATE OR REPLACE PACKAGE BODY CIC3.CartJSON AS
gCr_id number;
gRequestMsg varchar2(32000);
gResponseMsg varchar2(32000);
gMessageJSON w_MessageJSON_t;
gJSON JSON.JSONStructObj;
procedure SaveRequest is
begin
select CartRequestsSeq.nextval into gCr_id from dual;
insert into CartRequests (cr_id, cr_date ,cr_json) values (gCr_id, sysdate, gRequestMsg);
end;
procedure ExtractRequest is
i number;
vJSON JSON.JSONStructObj;
begin
i:=-1;
vJSON:=JSON.String2JSON(gRequestMsg);
NewJMessageJSON(gMessageJSON,vJSON,i);
gJSON:=JSON.String2JSON(gMessageJSON.ObjectSent);
update CartRequests set
cr_CartTime=gMessageJSON.CartTime,
cr_ObjectSent=gMessageJSON.ObjectSent
-- ***************************************************************
-- I'd like to add these fields but getting following errors:
-- PLS-00487 (39: 27): PLS-00487: Invalid reference to variable 'OBJECTSENT'
-- ORA-00904 (39: 27): PL/SQL: ORA-00904: "GMESSAGEJSON"."OBJECTSENT"."CUSTOMERID": invalid identifier
-- ***************************************************************
-- cr_OrderID=gMessageJSON.ObjectSent.OrderID, -- Adding this field
-- cr_CustomerID=gMessageJSON.ObjectSent.CustomerID -- Adding this field
where cr_id=gCr_id;
end;
END CartJSON;
/
How can I add these 2 fields with no errors?
CREATE OR REPLACE type CIC3.W_MESSAGEJSON_T as object (
CartTime Varchar2(30),
ObjectSent Varchar2(4000),
/
PLS-00487 (39: 27): PLS-00487: Invalid reference to variable 'OBJECTSENT'
ORA-00904 (39: 27): PL/SQL: ORA-00904: "GMESSAGEJSON"."OBJECTSENT"."CUSTOMERID": invalid identifier
The PL/SQL compiler error message above indicates that variable gMessageJSON (that is type of w_MessageJSON_t) doesn't have a member ObjectSent that would have member OrderID or CustomerID. You don't show us w_MessageJSON_t (could be an object type or a record) so it's impossible to say anything more precise.
Maybe the correct syntax would be cr_OrderID = gMessageJSON.OrderID?

Resources