I have written below procedure in oracle but its getting compiled with error.
CREATE OR REPLACE PROCEDURE PROC_MIGRATE_ONEIBER
AS
BEGIN
-- EXECUTE PROCEDURE ONEFIBER_LNK_MIGRATE;
execute ONEFIBER_LNK_MIGRATE;
execute ONEFIBER_LNK_MIGRATE_CITY;
execute ONEFIBER_LNK_MIGRATE_NLDC;
END;
-- NULL;
END PROC_MIGRATE_ONEIBER;
I have to execute 3 procedures in one main procedure without any IN or OUT parameters. But its not working
Just remove the execute keyword. Whenever you want to call another procedure within the procedure you can directly use the procedure name and parameters, If any.
CREATE OR REPLACE PROCEDURE PROC_MIGRATE_ONEIBER AS
BEGIN
-- EXECUTE PROCEDURE ONEFIBER_LNK_MIGRATE;
ONEFIBER_LNK_MIGRATE;
ONEFIBER_LNK_MIGRATE_CITY;
ONEFIBER_LNK_MIGRATE_NLDC;
--END;
-- NULL;
END PROC_MIGRATE_ONEIBER;
/
Update: Check this small code of how it should be. All procedures created in this answer are just for demo. (Make sure that the procedure that you are calling is not INVALID)
SQL>
SQL> CREATE OR REPLACE PROCEDURE ONEFIBER_LNK_MIGRATE AS
2 BEGIN
3 NULL;
4 END;
5 /
Procedure created.
SQL>
SQL> CREATE OR REPLACE PROCEDURE ONEFIBER_LNK_MIGRATE_CITY AS
2 BEGIN
3 NULL;
4 END;
5 /
Procedure created.
SQL>
SQL> CREATE OR REPLACE PROCEDURE ONEFIBER_LNK_MIGRATE_NLDC AS
2 BEGIN
3 NULL;
4 END;
5 /
Procedure created.
SQL>
SQL> CREATE OR REPLACE PROCEDURE PROC_MIGRATE_ONEIBER AS
2 BEGIN
3 ONEFIBER_LNK_MIGRATE;
4 ONEFIBER_LNK_MIGRATE_CITY;
5 ONEFIBER_LNK_MIGRATE_NLDC;
6 END PROC_MIGRATE_ONEIBER;
7 /
Procedure created.
SQL>
Related
I have Created a Package and procedure and functions within.
I have a small doubt.
If I have created procedure name employee_dtls in the package and at the same time
employee_dtls procedure as an independent object in the schema.
But i want to call the independent procedure employee_dtls inside my package but when I am trying to call
the procedure within the package is getting executed an independent one is not being called.
I assume since the name of both the procedures are the same it is calling the procedure inside the package.
Please help what can I do in this case?
What can you do? Qualify procedure name (as Justin commented). Here's how (read comments within code):
Standalone procedure:
SQL> create or replace procedure p_test is
2 begin
3 dbms_output.put_line('...standalone P_TEST procedure');
4 end;
5 /
Procedure created.
Packaged procedure:
SQL> create or replace package pkg_test is
2 procedure p_test;
3 procedure p_run;
4 end;
5 /
Package created.
SQL> create or replace package body pkg_test is
2 procedure p_test is
3 begin
4 dbms_output.put_line('...packaged P_TEST procedure');
5 end;
6
7
8 procedure p_run is
9 begin
10 dbms_output.put_line('calling P_TEST');
11 p_test; -- no qualifier - runs the packaged procedure (that's what you have now)
12
13 dbms_output.put_line('calling SCOTT.P_TEST');
14 scott.p_test; -- procedure name preceded by owner name - runs the standalone procedure
15
16 dbms_output.put_line('calling PKG_TEST.P_TEST');
17 pkg_test.p_test; -- procedur ename preceded by package name - runs the packaged procedure
18 end;
19 end;
20 /
Package body created.
Testing:
SQL> set serveroutput on;
SQL> exec pkg_test.p_run;
calling P_TEST
...packaged P_TEST procedure
calling SCOTT.P_TEST
...standalone P_TEST procedure
calling PKG_TEST.P_TEST
...packaged P_TEST procedure
PL/SQL procedure successfully completed.
SQL>
I am using Oracle 12c database and trying to run a package using SQL commands.
CREATE OR REPLACE PACKAGE "PK_CP_OTM" as
FUNCTION F_CP_OPTIMIZATION (
v_current_day IN VARCHAR2,
v_branch_code IN VARCHAR2)
RETURN VARCHAR2;
END PK_CP_OTM;
When I try to execute it using:
DECLARE
BEGIN
EXECUTE IMMEDIATE PK_CP_OTM.F_CP_OPTIMIZATION('20190409','BRNCD001');
END;
It shows:
ORA-00900: invalid SQL statement
ORA-06512: at line 3
00900. 00000 - "invalid SQL statement"
Thanks for your help.
As #Littlefoot said, you don't need dynamic SQL here, you can make a static call; but as you are calling a function you do need somewhere to put the result of the call:
declare
l_result varchar2(30); -- make it a suitable size
begin
l_result := pk_cp_otm.f_cp_optimization('20190409','BRNCD001');
end;
/
In SQL*Plus, SQL Developer and SQLcl you can use the execute client command (which might have caused some confusion) and a bind variable for the result:
var result varchar2(30);
exec :result := pk_cp_otm.f_cp_optimization('20190409','BRNCD001');
print result
There's nothing dynamic here, so - why would you use dynamic SQL at all?
Anyway: if you insist, then you'll have to select the function into something (e.g. a local variable). Here's an example
First, the package:
SQL> set serveroutput on
SQL>
SQL> create or replace package pk_cp_otm
2 as
3 function f_cp_optimization (v_current_day in varchar2,
4 v_branch_code in varchar2)
5 return varchar2;
6 end pk_cp_otm;
7 /
Package created.
SQL> create or replace package body pk_cp_otm
2 as
3 function f_cp_optimization (v_current_day in varchar2,
4 v_branch_code in varchar2)
5 return varchar2
6 is
7 begin
8 return 'Littlefoot';
9 end;
10 end pk_cp_otm;
11 /
Package body created.
How to call the function?
SQL> declare
2 l_result varchar2 (20);
3 begin
4 execute immediate
5 'select pk_cp_otm.f_cp_optimization (''1'', ''2'') from dual'
6 into l_result;
7
8 dbms_output.put_line ('result = ' || l_result);
9 end;
10 /
result = Littlefoot
PL/SQL procedure successfully completed.
SQL>
I know this is a very stupid question, but I just can't get this to work. I get an error saying that identifier hello must be declared
CREATE OR REPLACE PROCEDURE hello (p_name IN VARCHAR2)
IS
BEGIN
dbms_output.put_line (‘Welcome '|| p_name);
END hello;
/
EXECUTE hello('JOHN');
Everything's fine, except the first single quote in DBMS_OUTPUT call:
SQL> CREATE OR REPLACE PROCEDURE hello (p_name IN VARCHAR2)
2 IS
3 BEGIN
4 dbms_output.put_line ('Welcome '|| p_name);
5 END hello; -- ^ change this one
6 /
Procedure created.
SQL> EXECUTE hello('JOHN');
Welcome JOHN
PL/SQL procedure successfully completed.
SQL>
I have to do a procedure that add plus 1 to the previous value every time its is called in PL/SQL language. But I don't know how to do that.
I mean, if the procedure is call "plus1":
First execution:
exec plus1
will return value 1.
Second execution:
exec plus1
will return value 2.
And go on
The best way is to create a sequence, as noticed in comments:
create sequence my_seq;
To call the sequence in PL/SQL:
my_var := my_seq.nextval;
To call in SQL:
select t.*, my_seq.nextval from table t;
In the SQL query, a new value will be generated for each line.
If you don't need a sequence, and you don't need to store the value between sessions, create a package:
create or replace package my_package as
function get_next_value return number;
end my_package;
/
create or replace package body my_package as
current_num number := 0;
function get_next_value return number is
begin
current_num := current_num + 1;
return current_num;
end;
end my_package;
/
And then call my_package.get_next_value.
It is not entirely clear what you need. Here is one approach, assuming you need a session variable, initialized to zero at the start of the session, which you can call as needed, and is increased only when a procedure is executed. This is different from a function that increments the variable and returns it at the same time.
If you need to access the variable in SQL (rather than just in PL/SQL), you need to write a wrapper function that returns the value; I included the wrapper function in the code below.
create or replace package silly_p as
v number := 0;
function show_v return number;
procedure increment_v;
end;
/
create or replace package body silly_p as
function show_v return number is
begin
return v;
end show_v;
procedure increment_v is
begin
v := v+1;
end increment_v;
end silly_p;
/
Here is a SQL*Session demonstrating the compilation of this package and then its use - I access the variable both through SQL SELECT and from PL/SQL (with DBMS_OUTPUT) to demonstrate both access methods. Notice how the value is unchanged between calls to the procedure, and increases by one every time the procedure is executed.
SQL> create or replace package silly_p as
2 v number := 0;
3 function show_v return number;
4 procedure increment_v;
5 end;
6 /
Package created.
Elapsed: 00:00:00.03
SQL>
SQL> create or replace package body silly_p as
2 function show_v return number is
3 begin
4 return v;
5 end show_v;
6 procedure increment_v is
7 begin
8 v := v+1;
9 end increment_v;
10 end silly_p;
11 /
Package body created.
Elapsed: 00:00:00.00
SQL> select silly_p.show_v from dual;
SHOW_V
----------
0
1 row selected.
Elapsed: 00:00:00.00
SQL> exec dbms_output.put_line(silly_p.v)
0
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
SQL> exec silly_p.increment_v
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.04
SQL> select silly_p.show_v from dual;
SHOW_V
----------
1
1 row selected.
Elapsed: 00:00:00.14
SQL> exec silly_p.increment_v
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.07
SQL> exec dbms_output.put_line(silly_p.v)
2
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.07
SQL>
I've answered a similar question recently (have a look here); basically, you need to store current value somewhere (a table might be a good choice) and create a function (or, in your case, a procedure) that returns the next number.
How to convert the function I wrote to a procedure? Use it as a wrapper.
Here's the whole example:
SQL> CREATE TABLE broj (redni_br NUMBER NOT NULL);
Table created.
SQL>
SQL> CREATE OR REPLACE FUNCTION f_get_broj
2 RETURN NUMBER
3 IS
4 PRAGMA AUTONOMOUS_TRANSACTION;
5 l_redni_br broj.redni_br%TYPE;
6 BEGIN
7 SELECT b.redni_br + 1
8 INTO l_redni_br
9 FROM broj b
10 FOR UPDATE OF b.redni_br;
11
12 UPDATE broj b
13 SET b.redni_br = l_redni_br;
14
15 COMMIT;
16 RETURN (l_redni_br);
17 EXCEPTION
18 WHEN NO_DATA_FOUND
19 THEN
20 LOCK TABLE broj IN EXCLUSIVE MODE;
21
22 INSERT INTO broj (redni_br)
23 VALUES (1);
24
25 COMMIT;
26 RETURN (1);
27 END f_get_broj;
28 /
Function created.
SQL>
SQL> CREATE PROCEDURE p_get_Broj
2 AS
3 BEGIN
4 DBMS_OUTPUT.put_line (f_get_broj);
5 END;
6 /
Procedure created.
SQL>
SQL> EXEC p_get_broj;
PL/SQL procedure successfully completed.
SQL> set serveroutput on
SQL> EXEC p_get_broj;
2
PL/SQL procedure successfully completed.
SQL> EXEC p_get_broj;
3
PL/SQL procedure successfully completed.
SQL> EXEC p_get_broj;
4
PL/SQL procedure successfully completed.
I believe you need a session a variable like mathguy's assumption above. You can try below code and understand how it works. Note that each DB session could have different value to the NUM_VAR variable in var_pkg package depending on how many times the procedure below was executed for each session.
CREATE OR REPLACE PACKAGE var_pkg
IS
num_var NUMBER := 0;
PROCEDURE set_num_var(p_number NUMBER);
FUNCTION get_num_var RETURN NUMBER;
END;
/
CREATE OR REPLACE PACKAGE BODY var_pkg
IS
PROCEDURE set_num_var(p_number NUMBER)
IS
BEGIN
num_var := p_number;
END;
FUNCTION get_num_var RETURN NUMBER
IS
BEGIN
RETURN num_var;
END;
END;
/
CREATE PROCEDURE plus1
IS
v_num NUMBER;
BEGIN
v_num := var_pkg.get_num_var + 1;
var_pkg.set_num_var(v_num);
DBMS_OUTPUT.PUT_LINE(v_num);
END;
/
To run the procedure,
exec plus1;
or
BEGIN
plus1;
END;
/
And in case you want to know the current value of the variable, you can query it using below code,
SELECT var_pkg.get_num_var
FROM dual;
Does anyone know whether it's possible for a PL/SQL procedure (an error-logging one in this case) to get the name of the function/procedure which called it?
Obviously I could pass the name in as a parameter, but it'd be nice to make a system call or something to get the info - it could just return null or something if it wasn't called from a procedure/function.
If there's no method for this that's fine - just curious if it's possible (searches yield nothing).
There is a package called OWA_UTIL (which is not installed by default in older versions of the database). This has a method WHO_CALLED_ME() which returns the OWNER, OBJECT_NAME, LINE_NO and CALLER_TYPE. Note that if the caller is a packaged procedure it will return the PACKAGE name not the procedure name. In this case there is no way of getting the procedure name; this is because the procedure name can be overloaded, so it's not necessarily very useful.
Find out more.
Since 10gR2 there is also the $$PLSQL_UNIT special function; this will also return the OBJECT NAME (i.e. package not packaged procedure).
I found this forum: http://www.orafaq.com/forum/t/60583/0/. It may be what you are looking.
Basically, you can use the Oracle supplied dbms_utility.format_call_stack:
scott#ORA92> CREATE TABLE error_tab
2 (who_am_i VARCHAR2(61),
3 who_called_me VARCHAR2(61),
4 call_stack CLOB)
5 /
Table created.
scott#ORA92>
scott#ORA92> CREATE OR REPLACE PROCEDURE d
2 AS
3 v_num NUMBER;
4 v_owner VARCHAR2(30);
5 v_name VARCHAR2(30);
6 v_line NUMBER;
7 v_caller_t VARCHAR2(100);
8 BEGIN
9 select to_number('a') into v_num from dual; -- cause error for testing
10 EXCEPTION
11 WHEN OTHERS THEN
12 who_called_me (v_owner, v_name, v_line, v_caller_t);
13 INSERT INTO error_tab
14 VALUES (who_am_i,
15 v_owner || '.' || v_name,
16 dbms_utility.format_call_stack);
17 END d;
18 /
Procedure created.
scott#ORA92> SHOW ERRORS
No errors.
scott#ORA92> CREATE OR REPLACE PROCEDURE c
2 AS
3 BEGIN
4 d;
5 END c;
6 /
Procedure created.
scott#ORA92> CREATE OR REPLACE PROCEDURE b
2 AS
3 BEGIN
4 c;
5 END b;
6 /
Procedure created.
scott#ORA92> CREATE OR REPLACE PROCEDURE a
2 AS
3 BEGIN
4 b;
5 END a;
6 /
Procedure created.
scott#ORA92> execute a
PL/SQL procedure successfully completed.
scott#ORA92> COLUMN who_am_i FORMAT A13
scott#ORA92> COLUMN who_called_me FORMAT A13
scott#ORA92> COLUMN call_stack FORMAT A45
scott#ORA92> SELECT * FROM error_tab
2 /
WHO_AM_I WHO_CALLED_ME CALL_STACK
------------- ------------- ---------------------------------------------
SCOTT.D SCOTT.C ----- PL/SQL Call Stack -----
object line object
handle number name
6623F488 1 anonymous block
66292138 13 procedure SCOTT.D
66299430 4 procedure SCOTT.C
6623D2F8 4 procedure SCOTT.B
6624F994 4 procedure SCOTT.A
66299984 1 anonymous block
scott#ORA92>
Basically, all you need to do is to define vars and pass them in a call to a utility method to fill them up with values:
create or replace procedure some_test_proc (p_some_int int)
is
owner_name VARCHAR2 (100);
caller_name VARCHAR2 (100);
line_number NUMBER;
caller_type VARCHAR2 (100);
begin
....
OWA_UTIL.WHO_CALLED_ME (owner_name,caller_name,line_number,caller_type);
-- now you can insert those values along with systimestamp into a log file
....
end;