Create and execute an Oracle Stored Procedure for a select query in SQL Developer - oracle

I am using Oracle SQL Developer with Oracle 11g.
I face a strange issue creating a simple stored procedure for a Select query that doesn't need any input parameters as such. It just selects from a user defined function from the "dual" table.
These are the issues I face:
I am not able to create a procedure with no input parameters (because I don't need to use any parameter value in the select!). But the syntax does not allow me to have zero parameters, it demands a REF_CURSOR out parameter. Is the REF_CURSOR a compulsory thing in SQL Developer procedures? Is it anything to do with procedures involving a Select query?
The select query demands an INTO clause (a variable to copy the query result) in SQL developer. Is it mandatory?
Even if I used an INTO clause, I can't figure out the syntax to declare a temporary variable to copy the query result into this variable. So that I can use this out variable in my program snippet.
This is my procedure block:
Create or Replace PROCEDURE Getmarketdetails
AS
DECLARE temp varchar;
BEGIN
SELECT *
INTO temp from dual;
END Getmarketdetails;
I get these errors on compiling the procedure:
PLS-00103: Encountered the symbol "DECLARE" when expecting one of
the following: begin function pragma procedure subtype type
current cursor delete exists prior external language The
symbol "begin" was substituted for "DECLARE" to continue.
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: ( begin case declare end exception exit for goto if loop mod null pragma raise return select update while with << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge .
All I need is the perfect script syntax to create the stored procedure for this and also execute it using the exec command. And some clarifications to questions raised above. Appreciate if someone can oblige ! :)

Your syntax is incorrect - you need to declare a length for your varchar and you don't need the declare.
Create or Replace PROCEDURE Getmarketdetails
AS
temp varchar(100);
BEGIN
SELECT *
INTO temp from dual;
END Getmarketdetails;

Create or Replace PROCEDURE Getmarketdetails
AS
temp varchar2(20);
BEGIN
SELECT 'stack overflow' INTO temp from dual;
Dbms_output.put_line(temp);
END Getmarketdetails;
Some modification done in your procedure. Don't write declare and mention variables as per your need.

Related

Variable not being replaced (learning Dynamic PL/SQL)

The below code returns error ORA-00942: table or view does not exist, I think may be because PL/SQL runtime engine(or something I don't know what) is trying to treat table_in as a Table but why would it do so, I have already table_in declared as variable.
The ex26011601 table exists with values in the same schema.
set serveroutput on
declare
function tabcount (table_in in varchar2)
return pls_integer
is
l_return pls_integer;
begin
select count(*) into l_return from table_in;
return l_return;
end;
begin
dbms_output.put_line(tabcount('ex26011601'));
end;
I understand EXECUTE IMMEDIATE would solve the purpose. What I am trying to get is why is it necessary and whats wrong with current statement that 'table_in' could not be treated as variable even after being declared in the scope. Or what is the reason why a variable is not expected there?
I understand EXECUTE IMMEDIATE would solve the purpose. What I am
trying to get is why is it necessary and whats wrong with current
statement that 'table_in' could not be treated as variable even after
being declared in the scope.
As per oracle documentation : Static SQL
A PL/SQL static SQL statement can have a PL/SQL identifier wherever its SQL counterpart can have a placeholder for a bind variable. The PL/SQL identifier must identify either a variable or a formal parameter.To use PL/SQL identifiers for table names, column names, and so on, use the EXECUTE IMMEDIATE statement
In PL/SQL, you need dynamic SQL to run when :
SQL whose text is unknown at compile time
For example, a SELECT statement that includes an identifier that is unknown at compile time (such as a table name) or a WHERE clause in
which the number of sub clauses is unknown at compile time.
SQL that is not supported as static SQL
Dynamic SQL
Yes, as you said oracle pl/sql syntax does not allowing that, pass table name by variable. As you also said you can do it only by dynamic sql and execute immediate:
execute immediate 'select count(*) from ' || table_in
into l_return;

Show output before and then prompt for input in PL/SQL [duplicate]

This is a question about a small part of a large project I'm doing. I tried the following but I just get the two errors below it:
SET SERVEROUTPUT ON
CREATE OR REPLACE PROCEDURE HELLO AS
DECLARE
variable1 NUMBER(1);
variable2 CHAR(1);
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello World');
variable1 := &please_enter_1_or_0;
variable2 := &please_enter_y_or_n;
END;
/
Error(2,5): PLS-00103: Encountered the symbol "DECLARE" when expecting
one of the following: begin function pragma procedure subtype type
current
cursor delete exists prior external language The symbol "begin" was
substituted for "DECLARE" to continue.
Error(10,8): PLS-00103: Encountered the symbol "end-of-file" when
expecting one of the following: ( begin case declare end exception
exit for goto if loop mod null pragma raise return select update
while with
<< continue close current delete fetch lock
insert open rollback savepoint set sql execute commit forall merge
pipe purge
We were given a markscheme of how our code would be marked, and for this section, the relevant criteria would be:
"Does the script use a procedure?" and
"Does the script prompt for right/wrong and team/individual and handle the data provided correctly?".
The project brief quotes "Develop a procedure that prompts for RIGHT/WRONG (using &), then updates table" (where table is the name of a table).
The purpose of the variables was to update an existing record attribute. i.e. if user chose 1 and n then update the null in the record to 2. if it was 1 and y then update to 1, and if 0 and y/n then update to 0.
PL/SQL is a language for writing autonomous programs. It is not designed for user interactivity. Input values are passed as parameters.
So your program should look like this
CREATE OR REPLACE PROCEDURE hello
( p1 in number
, p2 in varchar2 )
AS
l_salutation varchar2(20) := 'Hello World';
BEGIN
DBMS_OUTPUT.PUT_LINE(l_salutation);
DBMS_OUTPUT.PUT_LINE('p1 = ' || p1);
DBMS_OUTPUT.PUT_LINE('p2 = ' || p2);
END;
/
Note there is no need for DECLARE with a named Procedure. The section between AS and BEGIN is for declaring variables, as I've done with l_salutation.
You can provide values for those parameters when invoking the program. In SQL*Plus it would work like this:
SET SERVEROUTPUT ON
accept p1 prompt "please enter 1 or 0: "
accept p2 prompt "please enter Y or N: "
exec HELLO (&p1, '&p2')
This piece of code works only in SQL*Plus and can't be used to produce a stored procedure!!!
DECLARE
variable1 NUMBER(1);
variable2 CHAR(1);
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello World');
variable1 := &please_enter_1_or_0;
variable2 := '&please_enter_y_or_n';
END;
Mind the difference in the last statement where the last substitution variable is quoted in a string to be properly accepted by the PL/SQL syntax. Anyway, as I told you in the last comment to your question this is not a user interaction but just the result of a statement preprocessing. Every time you input different values the RDBMS executes a different source code.
Probably your requirement to use a "procedure" doesn't meant to use a STORED procedure(that is impossible to do so), but they just intended a SQL*Plus script, ask for clarifications.
You cannot directly receive messages from the client in a PL/SQL procedure or package.
The best you can do to emulate this is to interface with table data, and have users insert data into the table and react to that, or use Advanced Queueing (which amounts to pretty much the same thing).
Alternatively, accept the user input as parameters when the procedure is called.
You can just Remove the declare to remedy that ora error

stored procedure for select query not giving output

I am using sqlplus and have a table named users from which I wish to retrieve all values with the help of a stored procedure in oracle. Here is what I am trying to do -
create or replace procedure getall(prc out sys_refcursor)
is
begin
open prc for select * from users
end;
/
When I hit return after this, I get the following error -
Warning: Procedure created with compilation errors.
Why does this happen? And how do I get the desired output? Help much appreciated!
To see the compilation errors use the show errors‌​ SQL*Plus command (which also works in SQL Developer), or query the user_errors view which works with any client. You can also query all_errors to see problems with objects that are not in your schema.
But you are just missing a semicolon after the select:
create or replace procedure getall(prc out sys_refcursor)
is
begin
open prc for select * from users;
end;
/
You'll need a bind variable to be able to see the output in SQL*Plus, e.g.:
variable rc refcursor;
exec getall(:rc);
print rc
Notice the colon before the rc in the procedure call, which shows it's a bind variable reference. And exec is a shorthand anonymous block.
You might find it simpler to have a function that returns a ref cursor, or a pipelined function; or just query the table directly of course.

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.

PL/SQL: Error when creating sequence

I'm quite new to PL/SQL, and am using Oracle SQL Developer to write a procedure which uses a sequence to generate a primary key for some existing data, to write into another DB.
The code in question is under NDA.. Essentially I have the following:
create or replace
PROCEDURE Generate_Data
(
output IN VARCHAR2
)
AS
-- Variables here --
CURSOR myCursor IS
SELECT data1, data2
FROM table;
CREATE SEQUENCE mySequence <-- error on this line
START WITH 0
INCREMENT BY 1;
BEGIN
LOOP
-- snip --
It raises the error PLS-00103, saying it encountered the symbol CREATE when expecting on of the following: begin, function, package, pragma, procedure, ...
I've been following the example at:
http://www.techonthenet.com/oracle/sequences.php
The reason you're getting this error is that you're trying to perform DDL, in this case creating a sequence, within PL/SQL. It is possible to do this, but you must use execute immediate.
As Alex says, you also wouldn't be able to do this in the declare section. It would look something like this:
begin
execute immediate 'CREATE SEQUENCE mySequence
START WITH 0
INCREMENT BY 1';
end;
However, as Padmarag also says, it's highly unlikely that you want to do this within PL/SQL. It would be more normal to create a sequence outside and then reference this later. More generally speaking, performing DDL inside a PL/SQL block is a bad idea; there should be no need for you to do it.
You don't mention what version of Oracle you're using. From 11g the ways in which you could access sequences got extended. If you're using 11g then you can access the sequence by creating a variable and assigning the next value in the sequence, .nextval, to this variable:
declare
l_seq number;
begin
loop
-- For each loop l_seq will be incremented.
l_seq := mysequence.nextval;
-- snip
end;
If you're before 11g you must (outside of DML) use a select statement in order to get the next value:
declare
l_seq number;
begin
loop
-- For each loop l_seq will be incremented.
select mysequence.nextval into l_seq from dual;
-- snip
end;
Please bear in mind that a sequence is meant to be a persistent object in the database. There is no need to drop and re-create it each time you want to use it. If you were to run your script, then re-run it the sequence would happily keep increasing the returned value.
Further Reading
About sequences
Using sequences
You can't create sequence in the DECLARE block of procedure. Move it after BEGIN. It's arguable if it makes sense, though. You probably need to create it outside your procedure in the first place.
Update
Actually, if you truly want it inside BEGIN/END use following:
EXECUTE IMMEDIATE 'CREATE SEQUENCE mySequence START WITH 0 INCREMENT BY 1';
You'd need to create the sequence before using it.
And in the PL/SQL code use
-- Variables here --1
v_seq_val number;
BEGIN
Select mySequence.nextval from dual into v_seq_val
In general SQL is for DDL(Data Definition Language) and PL/SQL is for DML(Data Manipulation Language) and logic.
If you wanted you could do Create from PL/SQL, but I think that's not what you want over here.

Resources