Passing a XML in Execute Immediate - oracle11g

varSQL: = 'DECLARE
varOptionId NUMBER;
varXML XMLTYPE;
varHsCode VARCHAR2(200);
varHsCodeCount NUMBER;
varId NUMBER;
RVAL OBJ_RETURN:=OBJ_RETURN(NULL,NULL,NULL,NULL);
BEGIN
varXML:=:refXML;
varHsCode:= varXML.EXTRACT('/OBJECT/HsCodes/HsCode/text()').GETSTRINGVAL();
:out:=varHsCode;
END';
EXECUTE IMMEDIATE varSQL USING PXML,OUT varOut;
This gives the following error:
ORA-06550: line 9, column 15:
PLS-00382: expression is of wrong type
ORA-06550: line 9, column 2:
PL/SQL: Statement ignored
ORA-06512: at "BIZZXE_V2_SCH.SYSTEM_UTILITY", line 225
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Is it possible to pass a XML?

Yes, you can pass an XMLType variable as a bind parameter:
declare
varsql varchar2(1024);
varout varchar2(4);
pxml xmltype := xmltype('<OBJECT><HsCodes><HsCode>Test</HsCode></HsCodes></OBJECT>');
begin
varSQL := 'DECLARE
varOptionId NUMBER;
varXML XMLTYPE;
varHsCode VARCHAR2(200);
varHsCodeCount NUMBER;
varId NUMBER;
--RVAL OBJ_RETURN:=OBJ_RETURN(NULL,NULL,NULL,NULL);
BEGIN
varXML:=:refXML;
varHsCode:= varXML.EXTRACT(''/OBJECT/HsCodes/HsCode/text()'').GETSTRINGVAL();
:out:=varHsCode;
END;';
EXECUTE IMMEDIATE varSQL USING PXML,OUT varOut;
dbms_output.put_line(varOut);
end;
/
PL/SQL procedure successfully completed.
Test
The error you are getting is because you have declared PXML as a string; either a varchar2 or CLOB variable:
declare
varsql varchar2(1024);
varout varchar2(4);
</HsCodes></OBJECT>');
pxml varchar2(64) := '<OBJECT><HsCodes><HsCode>Test</HsCode></HsCodes></OBJECT>';
begin
varSQL := 'DECLARE
varOptionId NUMBER;
varXML XMLTYPE;
varHsCode VARCHAR2(200);
varHsCodeCount NUMBER;
varId NUMBER;
--RVAL OBJ_RETURN:=OBJ_RETURN(NULL,NULL,NULL,NULL);
BEGIN
varXML:=:refXML;
varHsCode:= varXML.EXTRACT(''/OBJECT/HsCodes/HsCode/text()'').GETSTRINGVAL();
:out:=varHsCode;
END;';
EXECUTE IMMEDIATE varSQL USING PXML,OUT varOut;
dbms_output.put_line(varOut);
end;
/
Error report -
ORA-06550: line 9, column 10:
PLS-00382: expression is of wrong type
ORA-06550: line 9, column 2:
PL/SQL: Statement ignored
ORA-06512: at line 21
In your example there's no reason to use dynamic SQL anyway, but maybe your real-world example is more complicated.

Related

Calling a stored procedure with CLOB output

I am trying to use the CLOB datatype as the output parameter in my stored procedure because its resultset exceeds the storage capacity of a var datatype.
How do I execute the procedure? Below are the commands I had run to execute.
I tried assigning the resultset to the the CLOB variable using the INTO query as shown in the query.
var cl CLOB;
EXECUTE procedure_name(:cl);
print cl;
How do i declare the binding variable because if you look at the first command, I am first initializing cl as var I am not able to initialize it as CLOB as it is giving out an error.
This is a sample of my procedure. The actual query in the procedure is 700 lines long.
CREATE OR REPLACE PROCEDURE procedure_name (cl OUT CLOB)
IS
BEGIN OPEN cl FOR
SELECT * FROM .....
statement 1
.
.
.
.
.
statement n
INTO cl
FROM
statement 1
.
.
.
statement n
EXCEPTION
WHEN
OTHERS THEN
DECLARE
err_num NUMBER := SQLCODE;
err_msg VARCHAR2(512) := SQLERRM;
error_id_pk NUMBER;
error_dt DATE;
BEGIN
SELECT (REGEXP_REPLACE(CURRENT_TIMESTAMP, '[^0-9]+', ''))INTO error_id_pk FROM DUAL;
SELECT SYSDATE INTO error_dt FROM DUAL;
INSERT INTO ODS_CONTROL.ERROR_DETAILS(ERROR_ID, ERROR_CODE, ERROR_DATE, PROCEDURE_NAME, ERROR_MSG)
VALUES ( error_id_pk,
err_num,
error_dt,
'PRC_FLEXI_CARD',
err_msg
);
END;
END;
Error message:
Error starting at line : 2 in command -
EXECUTE procedure_name( :clb )
Error report -
ORA-06550: line 1, column 7:
PLS-00905: object procedure_name is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
[TL;DR] VAR is a keyword for declaring a variable and is not a data type; your actual error is due to using invalid syntax when you tried to define your procedure and it has not compiled.
VAR is short for VARIABLE and defines a PL/SQL bind variable.
This declaration has the syntax:
VAR[IABLE] [variable [type] ]
where type represents one of the following:
NUMBER
CHAR
CHAR (n [CHAR | BYTE])
NCHAR
NCHAR (n)
VARCHAR2 (n [CHAR | BYTE])
NVARCHAR2 (n)
BLOB
BFILE
CLOB
NCLOB
REFCURSOR
BINARY_FLOAT
BINARY_DOUBLE
So with:
var cl CLOB;
you are declaring a variable using the VAR keyword and the variable is named cl and has the type CLOB.
Also, your CREATE PROCEDURE statement has a syntax error as you cannot have the single quotes around the procedure name. For example:
CREATE PROCEDURE procedure_name (clb OUT CLOB)
IS
BEGIN
clb := 'test';
END;
/
Then:
VAR cl CLOB;
EXECUTE procedure_name( :cl );
PRINT cl;
Outputs:
test
Updated:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE ERROR_DETAILS(
ERROR_ID NUMBER,
ERROR_CODE NUMBER,
ERROR_DATE DATE,
PROCEDURE_NAME VARCHAR2(30),
ERROR_MSG VARCHAR2(512)
)
/
CREATE PROCEDURE procedure_name (cl OUT CLOB)
IS
BEGIN
SELECT DUMMY
INTO cl
FROM dual
WHERE ROWNUM = 1;
EXCEPTION
WHEN
OTHERS THEN
DECLARE
err_num NUMBER := SQLCODE;
err_msg VARCHAR2(512) := SQLERRM;
BEGIN
INSERT INTO /* ODS_CONTROL. */ ERROR_DETAILS(
ERROR_ID,
ERROR_CODE,
ERROR_DATE,
PROCEDURE_NAME,
ERROR_MSG
) VALUES (
TO_NUMBER( TO_CHAR( CURRENT_TIMESTAMP, 'YYYYMMDDHH24MISSFF9' ) ),
err_num,
SYSDATE,
'PRC_FLEXI_CARD',
err_msg
);
END;
END;
/
Query 1:
SELECT * FROM USER_ERRORS
Results:
No rows selected

ERROR in calling UTL_MAIL procedures

I am trying to send mails through UTL_MAIL.
where I used below code:
declare
v_sender VARCHAR2(30);
v_recipients VARCHAR2(60);
v_subj VARCHAR2(20);
v_msg VARCHAR2(200);
begin
v_sender := 'abc#xyz.com';
v_recipients := 'aaa#xyz.com';
v_subj := 'Info';
v_msg := 'This is an automated mail';
CALL (UTL_MAIL.SEND(v_sender, v_recipients, NULL, NULL, v_subj, v_msg));
END;
and I am receiving an error:
[Error] Execution (12: 9): ORA-06550: line 12, column 9:
PLS-00222: no function with name 'SEND' exists in this scope
ORA-06550: line 12, column 3:
PL/SQL: Statement ignored
Please help me with this..
Thank you

PLSQL script not working with passing multiple values into IN() caluse

I am very new in PLSQL, i want to pass an array of number into IN() clause value, But Sqldeveloper throw following error messages:
Error report -
ORA-06550: line 11, column 60:
PLS-00382: expression is of wrong type
ORA-06550: line 11, column 53:
PL/SQL: ORA-22905: cannot access rows from a non-nested table item
ORA-06550: line 10, column 4:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
This is my code :
DECLARE
TYPE sc IS TABLE OF transactionhistory.NBSUBCOMPANY%TYPE INDEX BY PLS_INTEGER;
arr sc;
BEGIN
arr(0) := 000;
arr(1) := 111;
arr(2) := 222;
arr(3) := 333;
select count(th.CHCARDNUMBER) as transactions from transactionhistory th INNER JOIN cards ch on ch.NBATTMID=th.NBATTMID where th.dtdate>=to_date('01-oct-2016','dd-mon-yyyy') and th.dtdate<to_date('01-nov-2016','dd-mon-yyyy')
and ch.NBSUBCOMPANY IN (select column_value from table (arr))
and ((th.CHTRANSTYPE in ('2940', '2916', '2941', '2942', '2943', '2944', '2945', '2902', '2917', '2925') and th.NBBASEAMT < 0) or (th.CHTRANSTYPE in ('2922', '2923', '2926', '2950', '2951', '2952', '2953', '2954', '2955') and th.NBBASEAMT > 0) or (th.CHTRANSTYPE in ('1101', '1102', '1104', '1105', '1106', '1107', '1109') and th.BASEII_STATUS = 'C') or th.CHTRANSTYPE not in ('2940', '2916', '2941', '2942', '2943', '2944', '2945', '2902', '2917', '2925', '2922', '2923', '2926', '2950', '2951', '2952', '2953', '2954', '2955', '1101', '1102', '1104', '1105', '1106', '1107', '1109'));
END;
Please suggest me how can i pass this.
You will need to have a workaround.
SQL doesn't support local collection types to be used in the way you want.
Sample Procedure below which will help in resolving
CREATE OR REPLACE type TEST_TYPE
IS
TABLE OF NUMBER;
You will need to create a type in the database for this to work. Can be created inside a package, if you have one.
DECLARE
TEST_VAR TEST_TYPE := TEST_TYPE();
BEGIN
TEST_VAR.extend(1);
TEST_VAR(TEST_VAR.last) := 222;
TEST_VAR.extend(1);
TEST_VAR(TEST_VAR.last) := 333;
FOR rec IN
(SELECT column_value
FROM TABLE(TEST_VAR)
)
LOOP
dbms_output.put_line(rec.column_value);
END LOOP;
END;
Output
222
333
This way, you can use select column_value from table(test_var) for your IN() clause.
Also, you don't necessarily need to follow the extend(i) part. you can simply do the below as well
TEST_VAR TEST_TYPE := TEST_TYPE(222,333);
Have a read - local collection types not allowed in SQL statements
You can use MEMBER OF clause. See below:
As #Sudipta mentioned you cannot use a collection decalred in PLSQL block as you are doing, you need to declare it outside of the PLSQL block.
CREATE OR REPLACE TYPE sc IS TABLE OF NUMBER;
and then
DECLARE
-- TYPE sc IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
arr sc:=sc();
num number;
BEGIN
arr.extend(4);
arr(1) := 0;
arr(2) := 1;
arr(3) := 2;
arr(4) := 3;
Select count(1)
into num
from employee
-- You can use either commented one or uncommented one. your choice.
--where employee_id in (select column_value from table(arr));
where employee_id member of arr;
END;

Procedure error with '&'

error screenshot I am trying to execute the below program in Toad.
create or replace procedure tst_excp as
var_sal number;
var_empid number;
var_excp exception;
begin
select sal into var_sal from emp
where empno = &var_empid;
if var_sal < 4500 then
raise var_excp;
end if;
exception
when var_excp then
dbms_output.put_line ('The salary is low');
end;
and I am getting an error at the line: where empno = &var_empid;
error message is:
PL/SQL: ORA-00936: missing expression
I am planning to pass the value to the variable while executing it.
the & is part of the sqlplus (and TOAD, SQL Developer and PL/SQL Developer) runtime variables. it will prompt you on execution (in your case while compiling the procedure) for an input to replace in the code.
if you want the get an input for the procedure, so it will be added to the where clause on every run, you need to receive it as an input variable:
create or replace procedure tst_excp (var_empid in number) as -- << changed here
var_sal number;
var_empid number;
var_excp exception;
begin
select sal into var_sal from emp
where empno = var_empid; -- << changed here too
if var_sal < 4500 then
raise var_excp;
end if;
exception
when var_excp then
dbms_output.put_line ('The salary is low');
end;

how to execute pl/sql procedure

Procedure:
create or replace
PROCEDURE ADDITION
(
A IN NUMBER
, B IN NUMBER
, C OUT number
) AS
BEGIN
C := A+B;
dbms_output.put_line(c);
END ADDITION;
executing:
begin
addition(4,5);
end;
Error:
PLS-00306: wrong number or types of arguments in call to 'ADDITION'
ORA-06550: line 2, column 2:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
How to rectify this error.Let me know what is the wrong in code
Your procedure expects an out parameter which you also need to provide:
declare
add_result number;
begin
addition(4,5,add_result);
end;
/

Resources