I'm trying to create a stored procedure that used REF CURSOR. I am using this website to find some examples. First I created types:
CREATE OR REPLACE TYPE ROW_TYPE IS OBJECT (
"COL1" CHAR(3 BYTE),
"COL2" NUMBER(4,0)
)
CREATE TYPE ROW_TYPE_TABLE AS TABLE OF ROW_TYPE;
Then created packages:
CREATE OR REPLACE PACKAGE package AS
FUNCTION get_by_id(p_id CHAR) RETURN ROW_TYPE_TABLE PIPELINED;
END package;
But when creating package body using the following command I get the following message PLS-00103: Encountered the symbol "FOR"
I have checked on Oracle official website how to use the open-for statement but can't find my mistake.
CREATE OR REPLACE PACKAGE BODY package AS
FUNCTION get_by_id(p_idCHAR) RETURN SERV_TYPE_TABLE PIPELINED IS
OUT_REC SERV_TYPE_TABLE := SERV_TYPE_TABLE(null,null);
servCursor sys_refcursor;
OPEN servCursor FOR 'SELECT * FROM SERV WHERE COL1= :1' USING p_id;
LOOP
FETCH servCursor INTO OUT_REC.COL1, OUT_REC.COL;
EXIT WHEN servCursor%NOTFOUND;
PIPE ROW(OUT_REC);
END LOOP;
CLOSE servCursor;
RETURN;
END get_by_id;
END package ;
Do you see any problem in the code submitted?
Regards.
PL/SQL functions have the structure:
FUNCTION <function name>(parameter1 <type>, ...) RETURN <return type> IS
<variable declarations>
BEGIN
<function body (code)>
END <function name>;
You forgot the BEGIN.
Related
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;
Hi I am trying to execute below statements for creating a package , but i am getting an error saying
Error(3,1): PLS-00540: object not supported in this context.
When trying to change it to RECORD i am getting another error
Error(3,32): PLS-00103: Encountered the symbol "RECORD" when expecting one of the following:
object opaque The symbol "object was inserted before "RECORD" to continue.
package Definition trying to execute
CREATE OR REPLACE PACKAGE "PKG_LOAN_LOGIC_SERVICE_V2" AS
TYPE LOAN_LOGIC_RESULT_TYPE AS OBJECT (
loanid NUMBER,
ret_value varchar2(500),
xPath varchar2(200)
);
TYPE LOAN_LOGIC_RESULTS_TABLE IS TABLE OF LOAN_LOGIC_RESULT_TYPE;
procedure PR_CORAL_LOAN_LOGIC(
in_loan_id IN wcts.loans.loan_id%TYPE,
in_trans_id IN wcts.loans.loan_id%TYPE,
as_errm out varchar2,
out_order_contents_tab out LOAN_LOGIC_RESULTS_TABLE
);
END PKG_LOAN_LOGIC_SERVICE_V2;
When i am trying to execute the user defined types in another standalone SQL Developer Window , its executing successfully .
CREATE OR REPLACE TYPE LOAN_LOGIC_RESULT_TYPE AS OBJECT (
loanid NUMBER,
ret_value varchar2(500),
xPath varchar2(200)
);
CREATE OR REPLACE TYPE LOAN_LOGIC_RESULTS_TABLE AS TABLE OF LOAN_LOGIC_RESULT_TYPE;
Why its not allowing me to run inside package ? or how i will create these types inside a package
Update:
create or replace procedure PR_CORAL_LOAN_LOGIC(
in_loan_id IN wcts.loans.loan_id%TYPE,
in_trans_id IN wcts.loans.loan_id%TYPE,
as_errm out varchar2,
out_order_contents_tab out LOAN_LOGIC_RESULTS_TABLE
)
is
begin
for o in (SELECT xpath_name FROM loan_logic WHERE attribute =
upper(TRIM('STATUS_0')))
loop
-- How i will get the user defined type here tp assign the values
--Assign the column values while iterating
END LOOP;
end PR_CORAL_LOAN_LOGIC;
According to Oracle documentation
You must define object types using the SQL statement CREATE TYPE
EDIT
For example
create or replace procedure PR_CORAL_LOAN_LOGIC(out_order_contents_tab out LOAN_LOGIC_RESULTS_TABLE)
is
obj LOAN_LOGIC_RESULT_TYPE;
begin
obj := LOAN_LOGIC_RESULT_TYPE(2, 'return value', 'some/path');
out_order_contents_tab := LOAN_LOGIC_RESULTS_TABLE();
out_order_contents_tab.extend;
out_order_contents_tab(1) := obj;
There are lots of examples available online, including Working with Collections. Not to mention the Oracle documentation.
I'm trying create package with oracle, although I have read many examples in docs oracle and built code same this tutorial but I still error this.
The following code:
create table manage_emplyee
(
f_name varchar(20),
l_name varchar(20)
);
// Specification
create or replace package fn2
as
procedure manage_emplyee(v_fname in VARCHAR2, v_lname in VARCHAR2);
procedure manage_emplyee_delete(v_fname in VARCHAR2);
end;
/
create or replace package body fn2
as
--Procedure Implementation
procedure manage_emplyee(v_fname in VARCHAR2, v_lname in VARCHAR2)
is
begin
insert into manage_emplyee VALUES (v_lname, v_lname);
end manage_emplyee;
// body
procedure manage_emplyee_delete (v_fname in VARCHAR2)
is
begin
delete manage_emplyee where v_fname = v_fname;
end manage_emplyee_delete;
end fn2;
/
Error
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
begin end function pragma procedure
Please help me fix it, thanks so much !
There are many things incorrect, so here is a correct version.
Run the table script first -
create table manage_emplyee
(
f_name varchar(20),
l_name varchar(20)
);
Run the Spec script after that
create or replace package fn2
as
procedure manage_emplyee(v_fname VARCHAR2,
v_lname VARCHAR2);
procedure manage_emplyee_delete(v_fname VARCHAR2);
end;
/
Run the body script after that
create or replace package body fn2
as
procedure manage_emplyee(v_fname VARCHAR2, v_lname VARCHAR2)
is
begin
insert into manage_emplyee VALUES (v_lname, v_lname);
end ;
procedure manage_emplyee_delete (v_fname VARCHAR2)
is
begin
delete from manage_emplyee where f_name = v_fname;
end ;
end;
/
The syntax for delete from table_name was incorrect.
I am sure, you want to match f_name from table with v_fname from the input variable to delete the data. Earlier you were matching v_fname with v_fname in your code, which will always be true (except for when its passed NULL) and you would end up loosing all your test data
*NOTE -
Adding IN explicitly is not required, the default type is IN for parameters in PLSQL procedures
I have got an SQL script stored in an .sql-file containing several statements like this:
create or replace package <schema>.custom_package is
procedure getReleaseEmployees(p_Cursor in out sys_refcursor, p_Role in string);
end custom_package;
/
create or replace package <schema>.pck_account_monitoring is
procedure checkAndLockOracleAccount;
end pck_account_monitoring;
/
<...some more packages following>
Running the script in an SqlDeveloper or PL/SQLDeveloper against my database works fine.
Now, when I'm trying to migrate via Flyway using the Java API, I'll get the following error message and Flyway's migration fails:
SQL State : 42000
Error Code : 900
Message : ORA-00900: Invalid SQL Statement
Location : migrations/sql/V0_2__migration.sql
Line : 6172
Statement : end pck_account_monitoring
at org.flywaydb.core.internal.dbsupport.SqlScript.execute(SqlScript.java:117)
at org.flywaydb.core.internal.resolver.sql.SqlMigrationExecutor.execute(SqlMigrationExecutor.java:71)
at org.flywaydb.core.internal.command.DbMigrate.doMigrate(DbMigrate.java:352)
If I try to put the first statement into a single line, i.e.
create or replace package quattro.custom_package is procedure getReleaseEmployees(p_Cursor in out sys_refcursor, p_Role in string); end custom_package;
/
<rest as before>
I'll get the same error message, but the parser now complains about the '/' symbol and the beginning of the next statement:
Error Code : 900
Message : ORA-00900: Invalid SQL Statement
...
Line : 6167
Statement : /
create or replace package quattro.pck_account_monitoring is ...
Now, if I remove that first '/' as well, the migration will run (with warnings, though).
My schema will then correctly have compiled all the other packages except for the first one - even though every other package declaration is formatted like the first one was in my initial attempt! The first package (custom_package) however is still missing.
My Java class basically looks like the sample class from the Flyway homepage.
Does anyone have any idea what's going wrong here with the Flyway parser or can maybe provide me with a workaround?
(This is too long for a comment, therefore, I'm posting it as an answer)
FWIW, I cannot reproduce this (using the Flyway 3.2.1 command line tool); running this example script:
-- PACKAGES
create or replace package flyway_demo.custom_package is
procedure getReleaseEmployees(p_Cursor in out sys_refcursor, p_Role in string);
end custom_package;
/
create or replace package flyway_demo.pck_account_monitoring is
procedure checkAndLockOracleAccount;
end pck_account_monitoring;
/
create or replace package flyway_demo.logger
authid definer
as
-- TYPES
type rec_param is record(
name varchar2(255),
val varchar2(4000));
type tab_param is table of rec_param index by binary_integer;
g_off constant number := 0;
function is_number(p_str in varchar2)
return boolean;
end logger;
/
create or replace package body flyway_demo.pck_account_monitoring is
procedure checkAndLockOracleAccount is
begin
null;
end;
end pck_account_monitoring;
/
create or replace package body flyway_demo.custom_package is
procedure getReleaseEmployees(p_Cursor in out sys_refcursor, p_Role in string)
is
begin
open p_Cursor for select * from dual;
end;
end custom_package;
/
create or replace package body flyway_demo.logger
as
function is_number(p_str in varchar2) return boolean is
begin
return true;
end;
end logger;
/
works perfectly fine. Can you please try it with this script and post your findings?
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