Hi, I'm new to PL/SQL and I want to know how to add a variable type in a package - oracle

I want to know how is ROT_TMLN_ARRAY type added to a variable in sql developer. I see that ROT_TMLN_ARRAY is also a type and I want to create something similar with another variable.
create or replace PACKAGE BODY AS PKG TMLN
PROCEDURE SP TMLN SVC (
rotnPrngNb IN VARCHAR2
empiRotnDetails OUT ROT_TMLN ARRAY)

U can add the variable as a Type in both IN or OUT Parameter.
CREATE OR REPLACE PROCEDURE P_TMLN_SVC(I_ID IN NUMBER,
O_RESULT OUT T_TABLE)
AS
BEGIN
SELECT OWNER_TYPE BULK COLLECT INTO O_RESULT FROM OWNERES WHERE OWNERS_ID=I_ID;
END P_TMLN_SVC;
Calling Statement:
DECLARE
T_ARRAY T_TABLE;
BEGIN
P_TMLN_SVC(100,T_ARRAY);
END;

Related

Oracle PL/SQL Developer: Return %RowType from Package Procedure

i'm kind of new to Oracle Pl\SQL. I was just trying to create a simple Package with a procedure that returns a set of object id's; the code is as follows:
--Package Spec
CREATE OR REPLACE PACKAGE TEST IS
--GET OBJECT ID'S FROM CONTROL TABLE
PROCEDURE get_object_id_control(p_obj_id OUT abc_table%ROWTYPE);
END;
--Package Body
PROCEDURE get_object_id_control(p_obj_id OUT abc_table%ROWTYPE) AS
BEGIN
SELECT object_id
INTO p_obj_id
FROM abc_table
WHERE fec_proc IS NULL;
END;
I get Error: PL/SQL: ORA-00913: too many values. Is this the correct way for returning multiple values of same data type, or is there a better approach. Thanks in advance.
You can create a custom table type and set the out parameter of the procedure to that type.
CREATE TABLE ABC_TABLE(ID varchar2(100));
create or replace type abc_tab is table of varchar2(100);
/
CREATE OR REPLACE PACKAGE TEST IS
PROCEDURE get_object_id_control(p_obj_id OUT abc_tab);
END;
/
CREATE OR REPLACE PACKAGE BODY TEST IS
PROCEDURE get_object_id_control(p_obj_id OUT abc_tab) AS
BEGIN
SELECT id
bulk collect INTO p_obj_id
FROM abc_table;
END;
END;
/
Then you can call it like so:
declare
v abc_tab;
begin
TEST.get_object_id_control(p_obj_id => v);
for i in v.first..v.last loop
dbms_output.put_line(v(i));
end loop;
end;
/
Similar to GurV's answer (since he beat me by like 30 seconds...), you can use a PL/SQL object type as well. You do not need the CREATE TYPE statement if you don't need to reference the type in SQL.
--Package Spec
CREATE OR REPLACE PACKAGE TEST AS
TYPE id_table_type IS TABLE OF NUMBER;
--GET OBJECT ID'S FROM CONTROL TABLE
PROCEDURE get_object_id_control(p_obj_id_list OUT id_table_type);
END;
--Package Body
CREATE OR REPLACE PACKAGE BODY TEST AS
PROCEDURE get_object_id_control(p_obj_id_list OUT id_table_type) AS
BEGIN
SELECT object_id
BULK COLLECT INTO p_obj_id_list
FROM abc_table
WHERE fec_proc IS NULL;
END;
END;
To use it:
DECLARE
l_id_list test.id_table_type;
BEGIN
test.get_object_id_control (p_obj_id_list => l_id_list);
FOR i IN l_id_list.FIRST .. l_id_list.LAST LOOP
DBMS_OUTPUT.put_line (l_id_list (i));
END LOOP;
END;

How to pass an array of values from Oracle Apex Page into Oracle stored procedure

I'm stuck with the passing Dates as an array parameters from the Oracle Apex page into package. Package contains one procedure with an array of type of dates. So what I want to do is to pass a simple dates into it from the Apex page, pl/sql block. Here is my code so far:
create or replace PACKAGE PK_NAME AS
TYPE DATES_ARRAY_TYPE IS VARRAY(100) OF DATE;
PROCEDURE PASS_DATES (
DATES DATES_ARRAY_TYPE
);
END PK_NAME;
create or replace PACKAGE BODY PK_NAME AS
PROCEDURE PASS_DATES (
DATES DATES_ARRAY_TYPE
) AS
BEGIN
for i in 1..DATES.count loop
HTP.P(DATES(i));
end loop;
END;
END PASS_DATES;
END PK_NAME;
Simple as that. And I call this procedure from the Apex page pl/sql block:
PK_NAME.PASS_DATES (
DATES => '15-JAN-15', '16-JAN-15', '17-JAN-15'
);
However, it doesn't work, every time I'm trying to save it, it gives me an error:
•ORA-06550: line 3, column 25: PLS-00312: a positional parameter association may not follow a named association ORA-06550: line 2, column 1: PL/SQL: Statement ignored
What is wrong with it or what have I missed ?
https://docs.oracle.com/cd/A97630_01/appdev.920/a96624/05_colls.htm
you must init constructor DATES_ARRAY_TYPE()
i think it must look like this
create TYPE DATES_ARRAY_TYPE IS VARRAY(100) OF DATE;
create or replace procedure test_case( p_dates DATES_ARRAY_TYPE) is
begin
dbms_output.put_line(p_dates(1));
end;
declare
a DATES_ARRAY_TYPE;
begin
a := DATES_ARRAY_TYPE(sysdate, sysdate + 1,to_date('1.01.2016','dd.mm.yyyy'));
test_case(a);
end;
also if you want to use TYPE in PACKAGE PK_NAME (not global) you must use object like PK_NAME.DATES_ARRAY_TYPE in your code.
ok, lets go in your case:
1. create package and body:
https://gyazo.com/789b875ce47852e859c395c2021f9cd4
create or replace PACKAGE PCK AS
-- your type in pck
TYPE DATES_ARRAY_TYPE IS VARRAY(100) OF DATE;
procedure test_case(p_dates DATES_ARRAY_TYPE);
END PCK;
create or replace PACKAGE body PCK AS
procedure test_case(p_dates DATES_ARRAY_TYPE) IS
BEGIN
--here just raise second element in array for DEMO
raise_application_error('-20000',p_dates(2) );
END;
END PCK;
2.create page and button and after submit process:
https://gyazo.com/755f6e089db0a6a8ea058567d2b3384b
declare
asd PCK.DATES_ARRAY_TYPE := PCK.DATES_ARRAY_TYPE('31-JUL-15', '01-AUG-15', '02-AUG-13', '03-AUG-13');
begin
pck.test_case(asd);
end;
after button that submit page i get this:
https://gyazo.com/b894fc6b9b6dd28964ba2e6548244bc8

How to transfer cursor to the procedure dynamically and to set rowtype variable dynamically?

I have written the procedure with dynamically set cursor and %rowtype variable:
create or replace procedure process(source_table IN varchar2, my_cursor IN sys_refcursor)
is
c sys_refCURSOR;
rec my_cursor%rowtype;
begin
Dbms_Output.put_line('process starts');
open c for 'select * from '||source_table;
loop
fetch c into rec;
exit when c%notfound;
end loop;
close c;
Dbms_Output.put_line('process is over');
end process;
I am going to transfer cursor to the procedure with the function as follows:
CREATE OR REPLACE FUNCTION ddp_get_allitems (source_table IN Varchar2)
RETURN SYS_REFCURSOR
AS
my_cursor SYS_REFCURSOR;
BEGIN
OPEN my_cursor FOR 'SELECT * FROM '|| source_table;
RETURN my_cursor;
END ddp_get_allitems;
While compiling the procedure "process" I have the error:
PLS-00320 the declaration of the type of the expression is incomplete or malformed.
The compiler has hilighted the row with "rec my_cursor%rowtype;" as the error source. The varibale "source_table" and "my_cursor" are based upon the same table (select * from my_table).
So Why the error has arisen and how to remove it?
Since PL/SQL is statically typed the compiler needs to know the types of all the variables at compile time.
So there is no room for advanced metaprogramming. I'm afraid you can't do that.
There are, however, generic types found at SYS.STANDARD and a few internal functions accepting them.
-- The following data types are generics, used specially within package
-- STANDARD and some other Oracle packages. They are protected against
-- other use; sorry. True generic types are not yet part of the language.
type "<ADT_1>" as object (dummy char(1));
type "<RECORD_1>" is record (dummy char(1));
type "<TUPLE_1>" as object (dummy char(1));
type "<VARRAY_1>" is varray (1) of char(1);
type "<V2_TABLE_1>" is table of char(1) index by binary_integer;
type "<TABLE_1>" is table of char(1);
type "<COLLECTION_1>" is table of char(1);
type "<REF_CURSOR_1>" is ref cursor;
Take "<ADT_1>" for example. There is XMLTYPE constructor or DBMS_AQ ENQUEUE and DEQUEUE functions. You can pass any kind of object there.
For now you cannot use this datatype in custom functions since they are "not yet part of the language", but maybe some day there will be some support for this.
Just a thought to modify soe params which can basically same output
you want to achieve. Basically here for Function i have replaced
RETURN type as TABLE TYPE which can be easilt called in Procedure abd
rest manipulations can be done.Let me know if this helps
--SQL Object creation
CREATE TYPE source_table_obj IS OBJECT
(<TABLE_ATTRIBITES DECLARATION>);
--SQL TABLE type creation
CREATE TYPE source_table_tab IS TABLE OF source_table_obj;
--Function creation with nested table type as RETURN type
CREATE OR REPLACE FUNCTION ddp_get_allitems(
source_table IN VARCHAR2)
RETURN source_table_tab
AS
src_tab source_table_tab;
BEGIN
SELECT * BULK COLLECT INTO src_tab FROM source_table;
RETURN src_tab;
END ddp_get_allitems;
-- Using Function's OUT param as an IN Param for Procedure an do all the requird processing
CREATE OR REPLACE PROCEDURE process(
source_table IN VARCHAR2,
src_tab_in IN source_table_tab)
IS
BEGIN
FOR i IN src_tab_in.FIRST..src_tab_in.LAST
LOOP
dbms_output.put_line('job processing');
END LOOP;
END process;

Oracle package variable not get set from sp parameter

Trying to set a local variable to parameter value that is passed to Oracle stored procedure However i am getting nottihgn..what am i doing wrong. When I test the package v_param is empty.
I am passing a long text
create or replace package MA_MAIN_SP_TESTCLOB IS
v_param clob;
procedure RUNALL( iOffice clob);
end MA_MAIN_SP_TESTCLOB;
create or replace package body MA_MAIN_SP_TESTCLOB IS
procedure RUNALL(iOffice clob) IS
BEGIN
v_param := iOffice;
--dbms_output.put_line('Parmeters are ' || v_param);
insert into ICCMSDW_CR.OfficeHolder(POFFICE)
values(v_param);
END RUNALL;
END MA_MAIN_SP_TESTCLOB;

Calling Oracle Stored proc with user define type array

I need to call a stored procedure in oracle. One of the parameters is a user defined type like so:
CREATE OR REPLACE TYPE MY_PK AS OBJECT
(
SOURCE_ID INTEGER,
ACCT_SYSTEM VARCHAR2(255)
)
/
CREATE OR REPLACE TYPE MY_PK_ARR AS TABLE OF MY_PK
/
PROCEDURE get_data(pk_in IN my_pk_arr, my_coursor OUT t_cursor)
IS
...
END
I am trying to call it like so:
var pk my_pk_arr
var my_cursor t_cursor
execute myschema.mypackage.get_data (pk , :my_cursor);
I can't figure out how to create the array. Is this possible or I need to create some sort of table to do it?
Thanks
call it like this if you're calling it via a script. sqlplus doesn't support user defined arrays etc.
declare
v_pk my_pk_arr;
v_cur t_cursor;
begin
v_pk := MY_PK_ARR(MY_PK(1, 'a'), MY_PK(2, 'b')); -- or build in a loop etc.
get_data(v_pk, v_cur);
end;
/

Resources