How to use Substitution in Stored Procedure - oracle

Actually I am creating stored procedure with substitution, while trying to compile the procedure, I get the popup to enter the substitution values in compiling itself, Instead of getting popup while execution.
Please share me your idea to compile the procedure without asking the substitution

In SQL*Plus or Oracle SQL Developer, you'd SET DEFINE OFF. You tagged the question with PL/SQL Developer tag (which is a tool I don't use), but - see if this helps.
However: I'd suggest you not to do it that way. If you're creating a stored procedure, then use its parameters, don't ask for substitution variables. Something like this:
SQL> set serveroutput on
SQL> create or replace procedure p_test (par_deptno in dept.deptno%type) is
2 begin
3 dbms_output.put_line('Department ' || par_deptno);
4 end;
5 /
Procedure created.
SQL> exec p_test(10);
Department 10
PL/SQL procedure successfully completed.
You can now reuse such a procedure, passing any parameter value you want.
The way you're doing it now:
SQL> create or replace procedure p_test is
2 begin
3 dbms_output.put_line('Department ' || &par_deptno);
4 end;
5 /
Enter value for par_deptno: 25
old 3: dbms_output.put_line('Department ' || &par_deptno);
new 3: dbms_output.put_line('Department ' || 25);
Procedure created.
SQL> exec p_test
Department 25
PL/SQL procedure successfully completed.
SQL>
you can run the procedure many times, but it'll always display (i.e. use) the same value, throughout that session. Once you exit and log in again, procedure will always use the same value.

You cannot! A substitution variable acts like a find-replace operation in the client application at the time the statement is run; the database does NOT see the substitution variable as the client application you are using will have already performed the find-replace operation. Which, for a procedure, would be at the time the CREATE PROCEDURE statement is sent from the client to the database to be compiled. It is NOT an operation that the database performs.
If you try it in a client that does not support substitution variables (or in a client that does support it after turning off substitution variables using, for example, the command SET DEFINE OFF in the client application) then you will get a compilation error. db<>fiddle
If you want to use substitution variables then use them in the anonymous block when you call the procedure.
An example procedure would take parameters and have no substitution variable:
CREATE PROCEDURE procedure_name(
p_value IN NUMBER
)
IS
BEGIN
-- Do something
DBMS_OUTPUT.PUT_LINE( p_value );
END;
/
Then when you want to execute the procedure you can use a substitution variable in the calling block:
BEGIN
procedure_name( &value );
END;
/

Related

Oracle SELECT <var name> AS <column name> equivalent after stored procedure where <var name> is an outbound parameter (JDBC/SQL Only no SQL*Plus)

Does Oracle have a way other than using using DBMS_OUTPUT to render the content of returned variables coming back out of a stored procedure via SELECT?
I'm aware of functions too, but I don't have a say in rewriting things, in case that's what people are thinking of responding with.
DECLARE
NAME TIDAL.JOBMST.JOBMST_NAME%TYPE; -- Oracle syntax to base the type of variable upon a column in a table. It resolves to varchar2(256)
BEGIN
TIDAL.GETJOBNAMEFORID(1,NAME); -- 'NAME' is an outbound parameter of stored procedure and gets bound to variable 'NAME' in DECLARE above.
DBMS_OUTPUT.PUT_LINE('Name: ' || NAME); -- || is Oracle string concat `+` anywhere else!
END;
The program that processes this SQL via JDBC needs to be able to render output as a CSV, XML or raw payload. It can only do all these options with the "select" style output. (probably using Java's Resultset API)
The DBMS_OUTPUT.PUTLINE doesn't generate output within the program that processes the SQL. DBeaver does. So this doesn't work for me either.
I thought there would be some awkward SELECT :NAME FROM DUAL or SELECT NAME: = NAME INTO DUAL syntax I could use to render it, since Oracle won't allow a SELECT without a FROM akin to SQL Server (see below), but the solution eludes me.
In this case the result is a scalar, but it could equally be one or more records, or rows of a single column..
I would like to use AS in order to be able to label the column(s) for a downstream processes too.
Can someone tell me if this is possible?
The code has to pass JDBC SQL parser syntax checks and generates no ORA error code. The bulk of the solutions I see on Oracle on the internet seem flaky. SQL*Plus answers with things like var or exec or print don't seem to work with JDBC SQL. I've been trying to validate things via DBeaver too - and most of the time a colon prepends variable names it seems to prompt for input so I'm not sure if that/my Oracle knowledge, is muddying the waters and I should try SQL Developer to validate code instead.
This would be the equivalent in SQL Server of what I want to achieve in Oracle:
DECLARE
#NAME varchar(256),
EXEC GETJOBNAMEFORID
1
#NAME = #NAME OUTPUT;
SELECT #NAME As Name
Other that this canned example I don't have visibility to the stored procedures to know if a sys_refcursor is in use on outbound parameters either.
Is it possible? Kind of. This is SQL*Plus (command-line tool):
Procedure with an OUT parameter (just like yours):
SQL> create or replace procedure p_test (par_deptno in dept.deptno%type,
2 par_dname out dept.dname%type)
3 as
4 begin
5 select dname
6 into par_dname
7 from dept
8 where deptno = par_Deptno;
9 end;
10 /
Procedure created.
Declare a variable:
SQL> var v_dname varchar2(20);
Execute the procedure:
SQL> exec p_test(10, :v_dname);
PL/SQL procedure successfully completed.
Print the result:
SQL> print v_dname
V_DNAME
--------------------------------------------------------------------------------
ACCOUNTING
SQL>
What if the procedure returns many rows? Then you could return refcursor:
SQL> create or replace procedure p_test (par_deptno in dept.deptno%type,
2 par_dname out sys_refcursor)
3 as
4 begin
5 open par_dname for
6 select dname
7 from dept
8 where deptno <= par_deptno;
9 end;
10 /
Procedure created.
SQL> var v_dname refcursor
SQL>
SQL> exec p_test(40, :v_dname);
PL/SQL procedure successfully completed.
SQL> print v_dname
DNAME
--------------
ACCOUNTING
RESEARCH
SALES
OPERATIONS
SQL>

How to excecute stored procedure with parameter in Oracle

My procedure is like this:
CREATE OR replace PROCEDURE rs_pes (c1 IN OUT SYS_REFCURSOR,
pi_prod_type_code IN VARCHAR2,
pi_entry_date IN VARCHAR2,
pi_dealer IN VARCHAR2,
pi_adv IN VARCHAR2 )
And, I'm trying to execure it like this:
execute RS_PES('Investments Series 2',
'31-12-2012',
'All Dealer',
'All Adv')
I'm getting incorrect syntax error.
ORA-00900: Invalid SQL statement
00900.00000 - Invalid SQL statement
What I'm doing wrong, how to execute this? I'm new to Oracle.
Execute is a SQL*Plus command which basically wraps your procedure call around BEGIN/END statements. This won't work anywhere else except SQL*Plus
If you want to execute the procedure in Oracle SQL Developer, wrap it in BEGIN/END block
BEGIN
RS_PES('Investments Series 2',
'31-12-2012',
'All Dealer',
'All Adv');
END;
Also, your procedure has 5 parameters, while you're setting only 4. You need to fix that.

How to execute procedure in APEX SQL script?

I am trying to understand how to use multiple procedures in APEX SQL script. First I don't really need stored procedure, but not sure how to declare simple procedure in APEX SQL script. So this is my attempt:
create or replace procedure test1 as
begin
DBMS_OUTPUT.ENABLE;
dbms_output.put_line('test1');
end;
execute test1;
This gives me an error:
Error at line 7: PLS-00103: Encountered the symbol "EXECUTE"
So questions - how to create regular/not stored/ procedures in one SQL script and then call them. What is the entry point of execution in APEX SQL script?
UPD (At the first time I understood question totally wrong)
Correct version of a script:
create or replace procedure test1 as
begin
DBMS_OUTPUT.ENABLE;
dbms_output.put_line('test1');
end;
/
begin
test1;
end;
/
Documentation says, that script can contain inly SQL and PL/SQL commands. Commands of sqlplus will be ignored.
OLD VERSION (Let stay here)
In APEX pages you can use PL/SQL anonymous blocks. For example, you can create process (APEX has some types of them) or PL/SQL region, and use following:
declare
...
begin
some_proc(:P_MY_ITEM);
end;
Here you can invoke any procedure and do anything else that allowed by PL/SQL. Also you can use parameters like :P_ITEM_NAME to get and set values of page and application items.

EXECUTE recognizes a stored procedure, CALL does not

When I try to run a stored procedure using EXECUTE, the proc runs fine. When I use CALL, I get "ORA-06576: not a valid function or procedure name". I am connecting directly via toad. Why can't I use call?
I have tried both of these Calls:
CALL(BPMS_OWNER.DAILY_PARTITION_NOROTATE('MIP_TEST',5,5,'MIP_TEST_',5,FALSE,TRUE));
CALL BPMS_OWNER.DAILY_PARTITION_NOROTATE('MIP_TEST',5,5,'MIP_TEST_',5,FALSE,TRUE);
The reason I need to use CALL is that our platform parses SQL before we send it to Oracle, which for whatever reason does not support EXECUTE.
Simply because call requires that you add parenthesis, for instance, call my_proc()
If I set up a little test:
SQL>
SQL> create or replace procedure test is
2 begin
3 dbms_output.put_line('hi');
4 end;
5 /
Procedure created.
And run this several different ways you'll see
SQL> exec test
hi
PL/SQL procedure successfully completed.
SQL> call test;
call test
*
ERROR at line 1:
ORA-06576: not a valid function or procedure name
SQL> call test();
hi
Call completed.
Why do you need to use call? Isn't exec, execute and begin ... end enough?
Based on your update the problem is the booleans, which call doesn't seem to support. Creating yet another small procedure
SQL> create or replace procedure test (Pbool boolean ) is
2 begin
3 if Pbool then
4 dbms_output.put_line('true');
5 else
6 dbms_output.put_line('false');
7 end if;
8 end;
9 /
Procedure created.
SQL> show error
No errors.
and running it proves this
SQL> call test(true);
call test(true)
*
ERROR at line 1:
ORA-06576: not a valid function or procedure name
I don't quite understand your reasoning behind why you can't use exec or execute but assuming these are both off limits why not just use a traditional, anonymous PL/SQL block?
SQL> begin
2 test(true);
3 end;
4 /
true
PL/SQL procedure successfully completed.

How to test an Oracle Stored Procedure with RefCursor return type?

I'm looking for a good explanation on how to test an Oracle stored procedure in SQL Developer or Embarcardero Rapid XE2. Thank you.
Something like
create or replace procedure my_proc( p_rc OUT SYS_REFCURSOR )
as
begin
open p_rc
for select 1 col1
from dual;
end;
/
variable rc refcursor;
exec my_proc( :rc );
print rc;
will work in SQL*Plus or SQL Developer. I don't have any experience with Embarcardero Rapid XE2 so I have no idea whether it supports SQL*Plus commands like this.
Something like this lets you test your procedure on almost any client:
DECLARE
v_cur SYS_REFCURSOR;
v_a VARCHAR2(10);
v_b VARCHAR2(10);
BEGIN
your_proc(v_cur);
LOOP
FETCH v_cur INTO v_a, v_b;
EXIT WHEN v_cur%NOTFOUND;
dbms_output.put_line(v_a || ' ' || v_b);
END LOOP;
CLOSE v_cur;
END;
Basically, your test harness needs to support the definition of a SYS_REFCURSOR variable and the ability to call your procedure while passing in the variable you defined, then loop through the cursor result set. PL/SQL does all that, and anonymous blocks are easy to set up and maintain, fairly adaptable, and quite readable to anyone who works with PL/SQL.
Another, albeit similar way would be to build a named procedure that does the same thing, and assuming the client has a debugger (like SQL Developer, PL/SQL Developer, TOAD, etc.) you could then step through the execution.
In SQL Developer you can right-click on the package body then select RUN. The 'Run PL/SQL' window will let you edit the PL/SQL Block. Clicking OK will give you a window pane titled 'Output Variables - Log' with an output variables tab. You can select your output variables on the left and the result is shown on the right side. Very handy and fast.
I've used Rapid with T-SQL and I think there was something similiar to this.
Writing your own delcare-begin-end script where you loop through the cursor, as with DCookie's example, is always a good exercise to do every now and then. It will work with anything and you will know that your code works.
In Toad 10.1.1.8 I use:
variable salida refcursor
exec MY_PKG.MY_PRC(1, 2, 3, :salida) -- 1, 2, 3 are params
print salida
Then, Execute as Script.
I think this link will be enough for you. I found it when I was searching for the way to execute oracle procedures.
The link to the page
Short Description:
--cursor variable declaration
variable Out_Ref_Cursor refcursor;
--execute procedure
execute get_employees_name(IN_Variable,:Out_Ref_Cursor);
--display result referenced by ref cursor.
print Out_Ref_Cursor;
create or replace procedure my_proc( v_number IN number,p_rc OUT SYS_REFCURSOR )
as
begin
open p_rc
for select 1 col1
from dual;
end;
/
and then write a function lie this which calls your stored procedure
create or replace function my_proc_test(v_number IN NUMBER) RETURN sys_refcursor
as
p_rc sys_refcursor;
begin
my_proc(v_number,p_rc);
return p_rc;
end
/
then you can run this SQL query in the SQLDeveloper editor.
SELECT my_proc_test(3) FROM DUAL;
you will see the result in the console right click on it and cilck on single record view and edit the result you can see the all the records that were returned by the ref cursor.

Resources