What is the result for stored procedure with in ,out parameters and IS keyword parameters before procedure body - oracle

Procedure with in , out parameters and having IS keyword with parameters list before BEGIN. In this case which result we will get after executing procedure.
PROCEDURE sample_proc (id in VARCHAR2, name in VARCHAR2, Course out varchar2)
IS error EXCEPTION, error_code VARCHAR2(100), courseID NUMBER, price NUMBER
BEGIN
select * from student where ID =id and name=name;
END executePROC;
Which fields we will get as result after executing via mybatis.
The stored procedure having parameters with data type before BEGIN keyword. In this case the parameters after IS and Before BEGIN keyword how it will work. Please explain

Which fields we will get as result after executing via mybatis.
None, the code has syntax errors and will not compile in Oracle.
You have:
A statement starting with PROCEDURE and not CREATE PROCEDURE (assuming that it is not part of a package as you do not include a preceding CREATE PACKAGE statement).
, following the variable declarations and not ;
A SELECT statement in the PL/SQL scope that does not have an INTO clause.
WHERE id = id AND name=name is (almost) the same as doing WHERE 1=1 AND 1=1 as the id and name values on both sides of the equality comparison will be from the local scope of the SQL statement and will not reference the procedure's arguments.
Variables that you are not using.
The procedure's identifier does not match the identifier after the final END statement.
To fix it you want something like:
CREATE PROCEDURE sample_proc (
i_id in STUDENT.ID%TYPE,
i_name in STUDENT.NAME%TYPE,
o_Course out STUDENT.COURSEID%TYPE
)
IS
BEGIN
SELECT courseid
INTO o_course
FROM student
WHERE id = i_id
AND name = i_name;
END sample_proc;
/
db<>fiddle here

IS keyword with parameters list before BEGIN.
They are not parameters, they are local variables.
As MTO has explained, the example you gave is not valid for a number of reasons.
But for the sake of argument, if you did actually have something like:
... PROCEDURE sample_proc (...)
IS
error EXCEPTION;
error_code VARCHAR2(100);
courseID NUMBER;
price NUMBER;
BEGIN
...
then the bit between IS and BEGIN is the optional declaration part, as described in the documention:
Declarative part (optional)
This part declares and defines local types, cursors, constants, variables, exceptions, and nested subprograms. These items cease to exist when the subprogram completes execution.
This part can also specify pragmas.
Note: The declarative part of a subprogram does not begin with the keyword DECLARE, as the declarative part of an anonymous block does.
The bit that is particularly relevant to your question (as I understand it anyway) is "These items cease to exist when the subprogram completes execution." They are local variables for use within the procedure, and not visible to or accessible by whatever calls the procedure.
The only data made visible to the caller is whatever it put into the OUT parameters.

Related

difference between creating a type with new keyword or without in plsql

In oracle pl/sql you can create an object with or without the new keyword.
Is there any difference how oracle threats these requests ?
So for example:
CREATE TYPE emp_object AS OBJECT(
emp_no NUMBER,
emp_name VARCHAR2(50),
salary NUMBER,
manager NUMBER,
CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER, p_emp_name VARCHAR2,
p_salary NUMBER) RETURN SELF AS RESULT),
MEMBER PROCEDURE insert_records,
MEMBER PROCEDURE display_records);
/
CREATE OR REPLACE TYPE BODY emp_object AS
CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2,
p_salary NUMBER)
RETURN SELF AS RESULT
IS
BEGIN
Dbms_output.put_line('Constructor fired..');
SELF.emp_no:=p_emp_no;|
SELF.emp_name:=p_emp_name;
SELF.salary:=p_salary;
SELF.managerial:=1001;
RETURN;
END:
MEMBER PROCEDURE insert_records
IS
BEGIN
INSERT INTO emp VALUES(emp_noemp_name,salary,manager);
END
MEMBER PROCEDURE display_records
IS
BEGIN
Dbms_output.put_line('Employee Name:'||emp_name);
Dbms_output.put_line('Employee Number:'||emp_no);
Dbms_output.put_line('Salary':'||salary);
Dbms_output.put_line('Manager:'||manager);
END:
END:
/
This is a type with spec and body, now you can create the object like this without the new keyword:
DECLARE
guru_emp_det emp_object;
BEGIN
guru_emp_det:=emp_object(1005,'RRR',20000,1000);
guru_emp_det.display_records;
guru_emp_det.insert_records;
COMMIT;
END;
But it is also possible with the keyword:
DECLARE
guru_emp_det emp_object;
BEGIN
guru_emp_det:= new emp_object(1005,'RRR',20000,1000);
guru_emp_det.display_records;
guru_emp_det.insert_records;
COMMIT;
END;
From the Type Constructor Expressions documentation:
Type Constructor Expressions
A type constructor expression specifies a call to a constructor method. The argument to the type constructor is any expression. Type constructors can be invoked anywhere functions are invoked.
type_constructor_expression::=
The NEW keyword applies to constructors for object types but not for collection types. It instructs Oracle to construct a new object by invoking an appropriate constructor. The use of the NEW keyword is optional, but it is good practice to specify it.
As to your question:
Is there any difference how oracle treats these requests?
No, there is no difference; the NEW keyword is optional.
Although the documentation states that the NEW keyword does not apply for collection types, in practice it does not appear to be invalid syntax and is both allowable and optional for collection types (there may be an edge-case I have not yet found where the NEW keyword is forbidden; however, on some brief tests I cannot find such a case).
fiddle

Using DECODE in PL/SQL procedure call

I have a stored PL/SQL procedure (say X) that inserts records into a table. I am calling that procedure from another procedure (say Y). I have some parameters in procedure Y like para1,para2,para3 which can have two values either zero or one, for zero and one values I have one id stored in a TBL_SETUP, and when I call procedure X I want to check that if para1 is null then return null, if it is not null then check if it is one then return YES_ID and if it is no then return NO_ID.
I have tried something like this. I wrote a SELECT statement for getting YES_ID,NO_ID before calling the procedure and it is working fine, but when I write procedure call as below, it is giving me error "PLS-00204: Function or pseudo-column may be used inside a SQL statement only". How to use DECODE in a procedure call?
PROC_X(DECODE(para1,NULL,NULL,DECODE(para1,'1',YES_ID,NO_ID)),para2,NULL,NULL,DECODE(para2,'1',YES_ID,NO_ID)),para3,NULL,NULL,DECODE(para3,'1',YES_ID,NO_ID)),)
You could use SELECT INTO:
DECLARE
DECODE_RESULT VARCHAR2(100); -- or any suitable data type
BEGIN
SELECT DECODE(...) INTO DECODE_RESULT FROM dual;
PROC_X(DECODE_RESULT);
END;

Calling a Procedure in Select Statement

I have a package consists of function and procedures
CREATE OR REPLACE PACKAGE BODY schema.pkg_product as
function xxxxx()
procedure product_get(p_product_id IN Number,
P_direct_balance Out Number,
P_indirect_balance Out Number) IS
v_request CLOB :=<soapenv:Envelope xmnlns:----->
v request_end varchar(100) := <can:----->
BEGIN
Selct statement
END
My question is can we can Call the procedure in the select statement and how can I get the P_direct_balance , P_indirect_balance. if so in the select query coz I want to retrieve that data from the procedure.
It's not possible. You could write a function but you cannot use functions with out parameters in SQL. So you'll have to rewrite your code. For instance create two functions that return p_direct_balance and p_indirect_balance.
If rewriting the procedure to be a function with an out parameter is not possible, I would suggest altering the procedure to write the relevant values to a temporary table and commit. Then use your select statement to retrieve the values from the temp table.

Encountered the symbol declare when creating a stored procedure

The following procedure is not being created in Oracle SQL Developer
CREATE OR REPLACE PROCEDURE CheckUser(UserName IN VARCHAR2,Password IN VARCHAR2)
AS
DECLARE Counts int;
BEGIN
SELECT COUNT(UserNames) INTO Counts FROM tblUsers
WHERE UserNames = UserName and Passwords = Password;
IF Counts = 1 THEN
SELECT 1 AS Code;
ELSE
SELECT -1 AS Code;
END;
When I run above procedure the following error message is returned in SQL Developer:
PROCEDURE CHECKUSER compiled
Errors: check compiler log
Error(3,1): PLS-00103: Encountered the symbol "DECLARE" when expecting
one of the following: begin function pragma procedure subtype type
current
cursor delete exists prior external language
To actually go over your errors:
The procedure declaration CREATE OR REPLACE... is the DECLARE block; you can remove the DECLARE; see the documentation for more information.
You need to select from something, this is normally the table DUAL, which has been designed for this purpose, i.e.
select 1 as code from dual
If you're selecting data in a procedure you need to SELECT INTO a variable. You do this the first time but not the second, i.e.
select 1 into <some variable> from dual
INT is not a datatype; it's INTEGER, which is a synonym for NUMBER(38,0
As far as I can tell you're not actually using the return code at all... I assume you're authenticating users here, which means you need to tell the calling program whether it was successful or not.
If you want to return a value the you probably want a function, as opposed to a procedure.
To take this to it's logical conclusion, your IF statement is unnecessary; the COUNT(*) will return 1 or 0 depending on whether the username and password exist... use this as a Boolean True/False instead.
I hope this is a password hash and not the actual password...
It's often better to be explicit about naming conventions and separate out parameters from column names etc to make it easier to read and less likely to cause Oracle to choke on the scope.
Putting all this together you end up with something like this:
create or replace function check_user (
PUsername in varchar2, PPassword_Hash in varchar2
) return number is
l_exists number;
begin
select count(*) into l_exists
from tblUsers
where username = PUsername
and password = PPassword_Hash
;
return l_exists;
end;
/
It's worth noting that your method of authentication is only safe if you ensure that people can only have one username, i.e. if TBLUSERS has a unique constraint on the column USERNAME. If it doesn't you do need some other method of uniquely identifying each user in your database, otherwise you could end up logging in people as a different user than they actually are.

How to declare / assign a variable to a cursor type in PL/SQL procedure

I have two cursors declared in a stored procedure (inside a package).
procedure RECONCILE_CC_TRX (p_to_date in date,
p_nz_flag in varchar2,
p_Reconcile_Header_ID out NUMBER
) is
CURSOR LOADED_TRXS_AU IS
SELECT
CC_REC_LOAD_TRX_ID,
CC_REC_LOAD_HEADER_ID,
....
CURSOR LOADED_TRXS_NZ IS
SELECT
CC_REC_LOAD_TRX_ID,
CC_REC_LOAD_HEADER_ID,
The only difference between the two cursors is the where clause.
What I want to do, is open one of those cursors based on the p_nz_flag passed in above. ie:
IF NVL(p_nz_flag, 'F') = 'F' THEN
v_load_trx_cursor := LOADED_TRXS_AU;
ELSE
v_load_trx_cursor := LOADED_TRXS_NZ;
END IF;
FOR bitem IN v_load_trx_cursor LOOP
...
My initial thinking was to declare a variable and assign it the appropriate cursor, however, I can't get the procedure to compile with this. eg, I have tried:
v_load_trx_cursor sys_refcursor;
but I get a compilation error when assigning v_load_trx_cursor of "PLS-00382: Expression is of wrong type". If I change my declaration to:
v_load_trx_cursor cursor;
I get compilation error at the declaration point stating "PLS-00201: Identifier 'Cursor' must be declared.
Is it possible to do what I want to do? At the end of the day, I just want to iterate the appropriate cursor based on the p_nz_flag parameter passed in.
Thanks
It looks like you want to use only one cursor in your code, based on the value of p_nz_flag
In this case, believe it will be better to make the where clause dynamically in your code and then use refcursor to return the data of the query.
Something like given in Example 7-4 on this link Dynamic Query with Refcursor
Hope it Helps
Vishad
Hi if your whole work for doing this procedure is just to populate the appropriate cursor i think this code may help you.
CREATE OR REPLACE PROCEDURE av_nst_cursor(
flag_in IN VARCHAR2,
av_cur OUT sys_refcursor)
AS
BEGIN
IF flag_in = 'Y' THEN
OPEN av_cur FOR SELECT Query;
ELSE
OPEN av_cur FOR SELECT query;
END IF;
END;

Resources