I have created a stored procedure in Oracle 11g:
CREATE OR REPLACE PROCEDURE greetings(cnt OUT VARCHAR2)
AS
BEGIN
SELECT COUNT(*)
INTO cnt
FROM SYS.all_tables;
END greetings;
but I am unable to call it.
I have tried the following code snippets:
EXEC GREETINGS();
EXEC GREETINGS;
CALL GREETINGS;
The procedure requires one parameter, so - provide it.
SQL> CREATE OR REPLACE PROCEDURE greetings(cnt OUT VARCHAR2)
2 AS
3 BEGIN
4 SELECT COUNT(*)
5 INTO cnt
6 FROM SYS.all_tables;
7 END greetings;
8 /
Procedure created.
One option, which works everywhere, is to use an anonymous PL/SQL block:
SQL> set serveroutput on
SQL> declare
2 l_cnt number;
3 begin
4 greetings(l_cnt);
5 dbms_output.put_line(l_cnt);
6 end;
7 /
87
PL/SQL procedure successfully completed.
Another one works in SQL*Plus (or any other tool which is capable of simulating it):
SQL> var l_cnt number;
SQL> exec greetings(:l_cnt);
PL/SQL procedure successfully completed.
SQL> print l_cnt;
L_CNT
----------
87
Regarding the call example, this is explained in EXECUTE recognizes a stored procedure, CALL does not. It's not obvious from the syntax documentation but it does require brackets, so it is (rather unhelpfully) rejecting the whole thing and giving the impression that greetings is the problem, when actually it is not:
SQL> call greetings;
call greetings
*
ERROR at line 1:
ORA-06576: not a valid function or procedure name
while using the mandatory brackets gets you the real issue:
SQL> call greetings();
call greetings()
*
ERROR at line 1:
ORA-06553: PLS-306: wrong number or types of arguments in call to 'GREETINGS'
As others have pointed out, you are missing the parameter.
SQL> var n number
SQL>
SQL> call greetings(:n);
Call completed.
SQL> print :n
N
----------
134
execute is just a handy SQL*Plus shortcut for the PL/SQL block begin xxx; end; which is less fussy about brackets and gives the same error message with or without them.
(variable and print are SQL*Plus commands and may not be supported in other environments.)
There's no problem with the procedure body. You can call like this :
SQL> var nmr number;
SQL> exec greetings(:nmr);
PL/SQL procedure successfully completed
nmr
------------------------------------------
306 -- > <a numeric value returns in string format>
Oracle doesn't care assigning a numeric value to a string. The execution prints the result directly, but whenever you want you can recall that value of variable(nmr) again, and print as
SQL> print nmr
nmr
---------
306
Related
I am very new to doing SQL work. I was wondering how I return a select statement in a stored procedure in PL/SQL.
My understanding so far (that is little) is that I should put the return of the data in a table and assign the data within the table to a reference cursor. With that loaded then LOOP through the REF Cursor and present the data back?
Actually converting that into code for a stored procedure has lost me completely with little examples to see with my use case. Any help is appreciated.
Many thanks in advance :)
Here's one example: procedure has only one - OUT - parameter, which is a refcursor:
SQL> create or replace procedure p_test (par_rc out sys_refcursor)
2 is
3 begin
4 open par_rc for select deptno, dname, loc from dept;
5 end;
6 /
Procedure created.
In order to call such a procedure, you need to store the result into something. In order to do that, I'll declare a variable (in SQL*Plus, which is a tool I use for this example) and call the procedure using begin-end block, providing the variable name as its parameter:
SQL> var l_rc refcursor;
SQL>
SQL> begin
2 p_test (:l_rc);
3 end;
4 /
PL/SQL procedure successfully completed.
Print the result:
SQL> print l_rc
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
There might be other options, which depend on what you really are doing.
Usually a stored procedure is used to perform manipulations of data in the database, and functions are used to return values or data. If you're just trying to use a select statement within a stored procedure, then you would want to use a cursor, which is something you declare like any other variable at the beginning of the procedure, and then open either implicitly or explicitly within the procedure code.
Example of an implicit cursor:
declare
cursor sample_cur is --this can be your select statement
select sysdate as today from dual;
begin
for rec in sample_cur loop
-- step by step for each record you return in your cursor
dbms_output.put_line(rec.today);
end loop;
end;
I want to create Procedure/Function without Parameters.
create or replace procedure p_newname ()
iS
begin
dbms_output.put_line('ok');
end p_newname;
/
But, i am getting the following error message:
"Warning: Procedure created with compilation errors."
Actually i wanted to call this Procedure using - Standalone Execution but without any involvement of parameters be it Formal parameters or Actual parameters:
EXECUTE p_newname();
Expected result should be - ok
Because, you need to remove parentheses after procedure name if procedure doesn't have any parameter during the creation.
But,you can call either by
SQL> exec p_newname();
/
or
SQL> exec p_newname;
/
or
SQL> begin
p_newname;
end;
/
or
SQL> begin
p_newname();
end;
/
of course without forgetting to issue
SQL> set serveroutput on
before them the results to be able to be printed on the screen.
As the question is
What can be the smallest Procedure?
and if it means "use as few letters as possible", then something like this might be the answer:
SQL> create procedure p as begin null; end;
2 /
Procedure created.
SQL>
I try to write select procedure in oracle.but it compile success, when I try to execute it given error.
set serveroutput on;
CREATE OR REPLACE PROCEDURE retrieve_decrypt(
custid in NUMBER,
column_name in VARCHAR2,
test_value OUT VARCHAR2
)
AS
BEGIN
-- enc_dec.decrypt(column_name,password) into test_value from employees where custid=5;
COMMIT;
END;
/
set serveroutput on;
EXEC retrieve_decrypt(5,'creditcardno');
the error says ,
This is your procedure:
SQL> create or replace procedure retrieve_decrypt
2 (custid in number,
3 column_name in varchar2,
4 test_value out varchar2
5 )
6 as
7 begin
8 -- your code goes here
9 null;
10 end;
11 /
Procedure created.
SQL>
This is how you call it (and get the error):
SQL> exec retrieve_decrypt(5, 'creditcardno');
BEGIN retrieve_decrypt(5, 'creditcardno'); END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'RETRIEVE_DECRYPT'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
SQL>
The cause of the error is:
the procedure contains 3 parameters:
2 of them are IN - you provided their values
1 of them is OUT - you didn't provide it and got the error
Here's what you should have done: as the 3rd parameter is OUT, you'll have to DECLARE it:
SQL> declare
2 l_out varchar2(20);
3 begin
4 retrieve_decrypt(5, 'creditcardno', l_out);
5 end;
6 /
PL/SQL procedure successfully completed.
SQL>
EXEC you used is a SQL*Plus command so it might not work everywhere; DECLARE-BEGIN-END block will so I'd suggest you use it.
Alternatively, in SQL*Plus, it could be rewritten as
SQL> var l_out varchar2
SQL>
SQL> exec retrieve_decrypt(5, 'creditcardno', :l_out);
PL/SQL procedure successfully completed.
SQL>
but - once again - you'd better use DECLARE-BEGIN-END PL/SQL block.
The initial error is:
wrong number or types of arguments in call to 'RETRIEVE_DECRYPT'
The procedure requires 3 parameters. You are only passing 2 (or apparently only 1, in the attempt that generated the error message shown).
Why do you also see the message "Usually a PL/SQL compilation error"? The EXEC command in SQLPlus creates a PL/SQL block containing the text you provide, and sends that to Oracle for execution. Oracle attempts to compile that PL/SQL block (just like it compiles the procedure when you create it). In this case, the compilation fails because of the mismatch in the number of arguments.
I have an oracle stored procedure which accepts varchar2 input parameter. My problem is that some of the input parameter contains "&" or "<" sign. Since these are the special character Oracle ignores it.
Since this is stored procedure i can not do SET DEFINE OFF as it is called by some system.
Can you please help on this as i want to store data with this special character like "A & M Solution" or "hemil mistry"
Any help on this
You need to set DEFINE OFF in the caller, not in the procedure.
For example:
create or replace procedure doSomething(str in varchar2) is
begin
dbms_output.put_line(str);
end;
If I call this procedure from SQLPlus, I get:
SQL> exec doSomething('&&&');
&&&
PL/SQL procedure successfully completed.
SQL> exec doSomething('&aa');
Enter value for aa: XXX
XXX
PL/SQL procedure successfully completed.
After setting DEFINE OFF, I have:
SQL> set define off
SQL> exec doSomething('&aa');
&aa
PL/SQL procedure successfully completed.
create table s (str varchar2(4000));
create or replace procedure storestr(str in varchar2) is
begin
insert into s values(str);
commit;
end;
/
exec storestr('&&&');
exec storestr('&&<');
select * from s;
Everything works fine.
What is your problem? Maybe please post what your procedure is going to do with data containing special characters.
When you pass specials characters as input parameters you should use function
chr()
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions019.htm
example:
set serveroutput on size 3000
create or replace procedure p_accept_special_char(ip_str in varchar2) is
begin
dbms_output.put_line(ip_str);
end;
/
exec p_accept_special_char(chr(38)||chr(62)||chr(60))
/
output:
SQL> set serveroutput on size 3000
SQL>
SQL> create or replace procedure p_accept_special_char(ip_str in varchar2) is
2 begin
3 dbms_output.put_line(ip_str);
4 end;
5 /
Procedure created.
SQL> exec p_accept_special_char(chr(38)||chr(62)||chr(60))
&><
PL/SQL procedure successfully completed.
I am using Oracle 11G database. I have created a package as described below:
create or replace package forward_emp is
Function emp_sal_avg return number;
Procedure emp_new_sal;
End forward_emp;
/
package created.
Then I created the package body:
create or replace package body forward_emp is
Function emp_sal_avg return number is
avg_sal emp.salary%type;
Begin
Select avg (salary) into avg_sal
from emp;
Return avg_sal;
End emp_sal_avg;
Procedure emp_new_sal is
Begin
Insert into Emp (salary) values (emp_sal_avg);
End emp_new_sal;
End forward_emp;
/
Package body created.
Now when I tried calling the package its is showing error.
Call forward_emp.emp_new_sal;
ORA- 06576: not a valid function or procedure.
Please help. Not been able to understand the problem.
CALL is a SQL statement, not a PL/SQL statement, not a SQLPLUS command. CALL can be used in SQLPLUS directly, but, when you execute a function, the returning result should be stored somewhere, hence into clause of the call statement is needed. And parenthesis, even if a function or a stored procedure has no arguments, kind of mandatory.
Here is an example:
SQL> create or replace package pkg as
2 function f1 return number;
3 procedure p1;
4 end;
5 /
Package created.
SQL> create or replace package body pkg as
2 function f1 return number is
3 begin
4 return 12345;
5 end;
6 procedure p1 is
7 begin
8 null; -- does nothing
9 end;
10 end;
11 /
Package body created.
Now let's execute those procedure and function defined withing the PKG package:
-- variable, which is going to store result the function returns
SQL> variable f_res number;
-- executing the F1 function
SQL> call pkg.f1() into :f_res;
Call completed.
-- print the result
SQL> print f_res;
F_RES
----------
12345
-- executing the P1 procedure
SQL> call pkg.p1();
Call completed.
This what happens if we simply omit parenthesis or do not specify into clause when executing a stored procedure or a type method using CALL statement:
SQL> call pkg.p1;
call pkg.p1
*
ERROR at line 1:
ORA-06576: not a valid function or procedure name
SQL> call pkg.f1 into :f_res;
call pkg.f1 into :f_res
*
ERROR at line 1:
ORA-06576: not a valid function or procedure name
SQL> call pkg.f1();
call pkg.f1()
*
ERROR at line 1:
ORA-06576: not a valid function or procedure name
I think you're trying to use CALL as a SQL*Plus command. As AHWNN pointed out, in sqlplus you would use EXECUTE to run the procedure. However you could in SQL test with CALL by using an anonymous block:
BEGIN
CALL the_pack.the_proc;
END;
/