How to pass bind variable as IN OUT parameter in PLSQL procedure - plsql

I want to use 1st parameter of my procedure EMP_ID as IN OUT parameter. Originally it's IN parameter and this procedure is working fine, but as the last line concern
htp.p('Inserted for Employee-id '||EMP_ID);
I want to use this line in anonymous block and most importantly it should be a bind variable because I am creating the REST API in which user will only enter values and it will be taken as bind variable in oracle Apex and the below procedure is working fine with respect of IN parameter.
create or replace procedure att_time_ins (EMP_ID in varchar2, ORG_ID in number,V_TIME_STATUS in number) is
BEGIN
INSERT INTO TIME_ATTENDANCE_POOL
(EMPLOYEE_ID, ATTENDANCE_DATE,TIME_HOURS,TIME_MINUTES,TIME_STATUS,LOCATION_ID,ORG_ID,PREPARED_ON )
VALUES
(EMP_ID, to_date(sysdate,'DD/MM/YYYY'),to_char(sysdate,'HH24') ,to_char(sysdate,'MI'),V_TIME_STATUS,null,ORG_ID,
to_date(sysdate,'DD/MM/YYYY') );
COMMIT;
time_management.create_attendance_sheet(v_org_id => ORG_ID,
v_employee_id => EMP_ID,
target_date => to_date(sysdate,'DD/MM/YYYY'));
htp.p('Inserted for Employee-id '||EMP_ID);
end att_time_ins;
I am calling my procedure in this way
begin
att_time_ins(:employee_id,:org_id,:time_status);
end;
Please help me to modify this stuff according to IN OUT Parameter i.e Employee_id should be IN OUT parameter. There is no proper documentation regarding passing bind variables as in out prameter in PLSQL Block.

Let us say you have a procedure named PR_PROC, you can use VARIABLE statement for passing IN OUT or OUT kind of variables.
CREATE OR REPLACE PROCEDURE PR_PROC (EMP_NAME IN VARCHAR2,
EMP_ID IN OUT VARCHAR2)
IS
BEGIN
DBMS_OUTPUT.PUT_LINE (EMP_NAME||EMP_ID);
END;
VARIABLE KURSOR VARCHAR2
BEGIN
:KURSOR:='4';
PR_PROC('SENIOR',:KURSOR);
END;
Note: If you are using TOAD Editor you can press F5 to make it work.
Oracle VARIABLE

Related

how to use collection type in PLSQL, while receiving multiple value from front end java page?

Actually my requirement is,am having 3 tables so i need to create type for each table or consolidate type to all table. but in java developer have to send the multiple parameter to my Procedure, so how to get the multiple values in single type and insert it into table??
Object type
CREATE OR REPLACE TYPE "POL_QUAT_TYPE"
IS OBJECT (V_POLICY_NO VARCHAR2 (30),
V_FOREIGN_POLICY VARCHAR2 (1));
tabletype
CREATE OR REPLACE TYPE POL_QUAT_table IS TABLE OF POL_QUAT_TYPE
Sample procedure
CREATE OR REPLACE PROCEDURE TEST1 (A POL_QUAT_TYPE) IS
B VARCHAR2(100);
C VARCHAR2(100);
BEGIN
B:=A(1);
C:=A(1);
INSERT INTO TEST ( PART, B )
VALUES (B,C);
COMMIT;
END;
Call this procedure
begin
test1('a','b');
end;
I want to know how get the value (a,b) though procedure from collection type.
Ok, you can insert the contents of an array of objects into the table like so:
CREATE OR REPLACE TYPE "POL_QUAT_TYPE"
IS OBJECT (V_POLICY_NO VARCHAR2 (30),
V_FOREIGN_POLICY VARCHAR2 (1));
/
CREATE OR REPLACE TYPE POL_QUAT_table IS TABLE OF POL_QUAT_TYPE;
/
CREATE OR REPLACE PROCEDURE TEST1 (p_a in POL_QUAT_table)
as
BEGIN
INSERT INTO TEST (PART, B)
select t.v_policy_no,
t.v_foreign_policy
from table(p_a) t;
COMMIT;
END;
/
I've created a test case to demonstrate that it works over on Oracle LiveSQL.
This means you can insert all the content of the array in one go without having to loop through the array and insert one record at a time, so it should be much more performant.

Execute immediate in netezza stored procedure is not inserting value to a table

When I am running this Netezza stored procedure, I am getting an error
attribute 'SOME_VALUE' not found
As per requirement I have to get value from one table (TABLE_A) and insert into another table (TABLE_B).
This is the procedure:
create or replace procedure my_proc()
returns boolean
execute as owner
language NZPLSQL
as
BEGIN_PROC
declare rec RECORD ;
BEGIN
for rec in SELECT * from TABLE_A loop
EXECUTE IMMEDIATE
'INSERT INTO TABLE_B(COLUMN_B)
values( '|| rec.COLUMN_A_OFTABLE_A || ')';
END LOOP;
END;
END_PROC;
execute my_proc()
Here below, I am able to insert a string. But I need to insert different value depending on other table as I mentioned above.
EXECUTE IMMEDIATE 'INSERT INTO TABLE_B(COLUMN_B) values( ''Y'');';
When building a string that you are going run EXECUTE IMMEDIATE against, you have be careful to have everything quoted properly. In your case it's thinking that it needs to treat SOME_VALUE as an attribute/column, and it can't any column with that name.
Wrap your column reference in quote_literal() and it will interpret the contents of your column and quote-escape it properly for you.
create or replace procedure my_proc()
returns boolean
execute as owner
language NZPLSQL
as
BEGIN_PROC
declare rec RECORD ;
BEGIN
for rec in SELECT * from TABLE_A loop
EXECUTE IMMEDIATE
'INSERT INTO TABLE_B(COLUMN_B)
values( '|| quote_literal(rec.COLUMN_A_OFTABLE_A) || ')';
END LOOP;
END;
END_PROC;
You can find some more information in the documentation here.
Note: I am assuming that you have some more complicated logic to implement in this stored procedure, because looping over row by row will be much, much slower that insert..select. Often by an order of magnitude.

Calling Oracle Stored Procedure from Spotfire

I've create a stored procedure (SP) within Oracle that has an OUT parameter of type SYS_REFCURSOR, this SP executes as expected within Oracle.
CREATE OR REPLACE PROCEDURE SCHEMA.MyProc
(
p_Code IN varchar2,
p_FromDate IN Timestamp,
p_ToDate IN timestamp,
p_ResultSet OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN p_ResultSet FOR
-- Obtain required data
END SF_EquipmentStatusHistory;
/
However when the Spotfire guy in the organisation tries to create new Procedure in Spotfire and reference my SP, Spotfire complains that it can't have an OUT parameter.
Reading this link Spotfire Procedure Overview, seems to suggest that Spotfire "Information Designer only support procedures that return data of the type REF CURSOR"
Can somebody please help as to how I resolve this issue?
Thanks
Resolved:
As suggested changing the Stored Procedure to a Function within Oracle did resolve the problem of Spotfire complaining about OUT parameter:
CREATE OR REPLACE FUNCTION SCHEMA.MyFunc
(
p_Equipment_code IN varchar2,
p_FromDate IN Timestamp,
p_ToDate in timestamp
)
return SYS_REFCURSOR
AS p_ResultSet sys_refcursor;
BEGIN
OPEN p_ResultSet FOR
-- Obtain required data
return p_ResultSet;
END MyFunc
/
you might try something like this
CREATE OR REPLACE FUNCTION SCHEMA.MyFuctRC
(
p_Code IN varchar2,
p_FromDate IN Timestamp,
p_ToDate IN timestamp
)
Return sys_refcursor
AS
my_rc sys_refcursor ;
BEGIN
OPEN my_rc FOR
-- your select statement
return my_rc;
END MyFuctRC;
/

Mixing arrays and queries

I have a set of product that I want to tag to a certain value so what I did this:
declare
type array_produit_auto is varray(3) of varchar(50);
array array_produit_auto := array_produit_auto('code_product1', 'code_product2', 'code_product3');
begin
for i in 1..array.count loop
update F_PRODUITASS pas
set PAS_NONGES_IDA = 0
WHERE PAS.PAS_CODE_PRODUIT = array(i;
end loop;
end;
commit;
however, the list of these products is too long. Instead I'd like to do this:
declare
type array_produit_auto is varray(3) of varchar(50);
array array_produit_auto := array_produit_auto('code_product4', 'code_product5', 'code_product6');
begin
update F_PRODUITASS pas
set PAS_NONGES_IDA = 1
WHERE PAS.PAS_CODE_PRODUIT NOT IN array;
end;
commit;
except this doesn't work since apparently I can't mix a query and an array this way.
Any idea of how I could make this work?
If you used a nested table then you could query from the nested table, something like this:
DECLARE
v_exclude_list t_array_produit_auto :=
t_array_produit_auto('code_product4', 'code_product5', 'code_product6');
BEGIN
UPDATE F_PRODUITASS pas
SET PAS_NONGES_IDA = 1
WHERE PAS.PAS_CODE_PRODUIT NOT IN ( SELECT *
FROM TABLE(v_exclude_list) )
;
END;
/
Also, you meant varchar2, right?
Update regarding the Opaque error: The type declaration would need to be an object type (create with the CREATE OR REPLACE TYPE syntax rather than a local plsql type as in the DDL below.
CREATE TABLE F_PRODUITASS(PAS_NONGES_IDA number, PAS_CODE_PRODUIT VARCHAR2(50));
INSERT INTO F_PRODUITASS VALUES(3, 'code_product3');
INSERT INTO F_PRODUITASS VALUES(4, 'code_product4');
CREATE OR REPLACE TYPE t_array_produit_auto IS TABLE OF VARCHAR2(50);
If you did not wish to create your own object type, you could use pre-existing varchar2 or number types such as sys.odcivarchar2list as described here:
Anonymous TABLE or VARRAY type in Oracle

PL/SQL update statement error

--Student(id, company) Table schema
create or replace procedure student_update(
v_company IN VARCHAR2(10),
v_id IN NUMBER
)
IS
BEGIN
update student set company=v_company where id=v_id;
commit;
END student_update;
/
Error: Encountered the symbol '(' where expecting one of the following
Need to change the dataType of the parameters
create or replace procedure student_update(
v_company IN student.company%TYPE,
v_id IN student.id%TYPE
)
IS
BEGIN
update student set company=v_company where id=v_id;
END;
/
This works fine.
You cannot give a length to you parameters. If you really need to limit v_company to 10, you can do a length check inside the procedure.
You might also consider looking into using Native Dynamic SQL. You're at risk running code straight from inputs.
CREATE OR REPLACE PROCEDURE student_update
(
v_company IN VARCHAR2
,v_id IN NUMBER
) IS
BEGIN
IF LENGTH(v_company) > 10 THEN
raise_application_error(-20001, 'Company must be 10 Char or less.');
END IF;
UPDATE student SET company = v_company WHERE ID = v_id;
COMMIT;
END student_update;
/

Resources