Executing procedure in plsql developer - plsql

I am totally new to PLSQL and I am struggling to execute a procedure in PLSQL Developer. I have created a procedure named as 'employee' as follows:
CREATE OR REPLACE PROCEDURE employee IS
var_name VARCHAR2(20) := 'Parkavi';
var_web VARCHAR2(20) := 'parkavi.com';
BEGIN
DBMS_OUTPUT.PUT_LINE('Hi! I am ' ||var_name|| 'from' ||var_web);
END employee;
Now I need to execute this procedure so that I can view the output. Please help me out. Thanks in advance!!

In PL/SQL Developer, you execute PL/SQL blocks in the Test Window.
File > New > Test Window will provide a template block something like this:
declare
begin
end;
You just need to add your procedure name (and remove the unneeded declare section as you have no variables), so it's:
begin
employee;
end;
Alternatively, right-click on the procedure name and select 'Test' from the pop-up menu, and it will generate the above block for you.
If the expected dbms_output text is not displayed in the 'Output' tab, the first thing to check is that the 'Enabled' checkbox is checked.
To diagnose dbms_output, the simplest test case would be just:
begin
dbms_output.put_line('Hello');
end;

Related

How to correctly make a procedure in Pl/SQL in which I create a TABLE and use a CURSOR

The assignment I am trying to do is
"Create a procedure that places the names of all presidents who were born in one specific
state, in a temporary table. Display the contents of this table."
The procedure complies but when I try to invoke it, it gives me:
00000 - "table or view does not exist"
Error(8,5): PLS-00103: Encountered the symbol "CREATE" when expecting one of the following: begin function pragma procedure subtype type current cursor delete exists prior
I have been stuck for a while now. Does anybody know what I am doing wrong?
My code so far is:
CREATE OR REPLACE PROCEDURE stateofpresident(p_state president.state_born%TYPE)
AS
CURSOR c_state IS
SELECT *
FROM president;
BEGIN
execute immediate 'CREATE TABLE presidentFromState;
(
president_name VARCHAR2
)';
FOR r_state IN c_state LOOP
IF(p_state = r_state.state_born) THEN
execute immediate 'INSERT INTO presidentFromState VALUES(r_state.pres_name)';
commit;
END IF;
END LOOP;
execute immediate 'DROP TABLE presidentFromState';
END stateofpresident;
/
SET SERVEROUT ON
BEGIN
stateofpresident('VIRGINIA');
END;
/
SELECT *
FROM presidentFromState;
The immediate cause of your error is the semi-colon (;) at "presidentFromState;" At run fhat terminates the statement and the SQL interpreter at that point does not know what is want, the create syntax is invalid. The statement compiles because at compile time it is a properly formatted string. That is why dynamic SQL should be avoid if at all possible. Your script also has an additional error. Your last select will fail as the table presidentFromState ws not only created but also dropped in the procedure. Finally, just an FYI, the entire FOR cursor and the cursor itself is entirely unnecessary, the entire operation can be completed is one statement: Look into the structure
Insert into table_name(columns)
Select columns ...
Since this obviously an assignment or tutorial I'll leave the exact for your research.

Ending PLSQL procedure

I wrote a PLSQL procedure in Oracle APEX, but I don't know how to end it as every way I have tried it still complains.
DECLARE
PROCEDURE FzgZuordnen(Volt VARCHAR2) IS
Variable Declarations
*
BEGIN
*
END;
FzgZuordnen END;
I have also tried
*
END;
END;
But it doesn't seem to like any way I end my procedure. I have ended all of the things inside the procedure.
Thanks for any help.
You can declare a local procedure in a PL/SQL block anywhere - including in APEX. The syntax is like this:
DECLARE
PROCEDURE FzgZuordnen(Volt VARCHAR2) IS
-- Variable Declarations
BEGIN
-- Procedure code
END FzgZuordnen;
BEGIN
-- Block PL/SQL that calls the procedure
END;
For example:
DECLARE
PROCEDURE raise_error (error_text VARCHAR2) IS
BEGIN
raise_application_error (-20001, error_text);
END FzgZuordnen;
BEGIN
if :p1_value < 0 then
raise_error ('Value cannot be negative');
elsif :p1_value > 10 then
raise_error ('Value cannot exceed 10');
end if;
END;
Because the procedure is declared locally it can only be used from the PL/SQL block where it is declared. If you needed a procedure that could be called from many placed in your application or page then it would need to be defined in the database (preferably in a package).
To my knowledge you cannot place PL/SQL procedures directly in an APEX page. For PL/SQL execution there are APEX processes. If you have to re-use your code on other pages then either copy the process to each page or use a db procedure (meaning putting the procedure directly in the database)
Using APEX process:
Create a new Process on the Page and select "PL/SQL Code" as type. Then type your Code into the APEX process.
Variable Declarations
*
BEGIN
*
END;
Processes can only be used inside the same page. If you want to use your code on multiple other pages you have to copy them to this page.
Using DB-procedure:
If you use a db procedure you have to add it directly to the oracle database. Therefor connect to the database with a tool of your choice. Execute your code from above. To call the procedure in APEX use something like this.
begin
PKG.FzgZuordnen(:APEX_PAGEITEM);
end;
try this way:
DECLARE
PROCEDURE FzgZuordnen(Volt VARCHAR2) IS
Variable Declarations
*
BEGIN
*
END FzgZuordnen;
BEGIN
*
END;
You can create a plsql procedure inside a database schema using sql developer or sql plus
create or replace procedure zgZuordnen(Volt VARCHAR2) IS
.. variable declaration
begin
{statament blocks}
end zgZuordnen;
From APEX frontend developer option you can call the procedure with bind variable

bind variable substitution in oracle

The below simple procedure is suppose to provide grants to the user scott in oracle.
The value for &scott_SCHEMA is already defined in a seperate file(define_variable.sql) and the value is getting substituted correctly, but im getting the error(as specified in the bottom of the script), a help is much appreciated.
SET SERVEROUTPUT ON
declare
l_sql varchar2(3200);
begin
for i in ( select table_name as oname,'TABLE' as type from all_tables where owner='HR' AND table_name not like 'BIN$%' union all select view_name as oname,'VIEW' as type from all_views where owner='HR' and view_name not like 'BIN$%' )
loop
if i.type = 'TABLE' then
dbms_output.put_line(l_sql);
l_sql:= 'grant select,insert,update,delete on hr.'||i.oname||' to :owner with grant option';
execute immediate l_sql using '&scott_SCHEMA';
else
l_sql:= 'grant select on hr.'||i.oname||' to :owner with grant option';
end if;
end loop;
end;
/
*declare
*
ERROR at line 1:
ORA-00987: missing or invalid username(s)
ORA-06512: at line 12*
You can't use bind variables in place of identifiers (specifically schema or object names) in DDL or DML statements, they can only be used in place of value expressions.
Since you're using substitution variables, you could just place it in the sql statement itself:
l_sql:= 'grant select,insert,update,delete on hr.'||i.oname||' to &scott_SCHEMA with grant option';
and execute it with out passing it as a parameter:
execute immediate l_sql;
On a side note, your DBMS_OUTPUT line should come after you assignment to l_sql, otherwise you'll miss outputting one or more of the statements being processed. A good place would be between the assignment statement and the execute statement.

Dynamic SQL and Cursor related issue

I have declared cursor and used in the procedure body, then I have dynamic sql statement which creates a table on the fly. After that I need to access the same cursor which i declared.
When I try to open the cursor before the execution of dynamic sql statement its working fine.
When I try to open the cursor after the execution of dynamic sql statement its not opening and cursor.
Please help me.
Thank you.
create or replace procedure(columns varchar2)
is
column_names varchar2(100);
sql_query varchar2(200);
begin
select pk_cols into column_names
from rules where rule_column=columns;
sql_query:='create global temporary table ('||column_names||')';
execute immediate sql_query;
end;
Creating the table is DDL which in Oracle results in an implicit commit, ending your transaction.
To solve this problem you could create the table inside an autonomous transaction:
-- open cursor
declare
pragma autonomous_transaction;
begin
execute immediate 'create table ...';
end;
-- do more with your cursor
For more information about autonomous transactions, see this overview on Tim Hall's excellent site.

Execute Immediate

Can any one help me to to find out the error.
create or replace procedure sample
is
begin
DECLARE AGG_COLUMNS VARCHAR2(2000);
BEGIN
EXECUTE IMMEDIATE 'SELECT COLUMNS FROM COLUMN_NAMES' INTO AGG_COLUMNS;
END;
begin
EXECUTE IMMEDIATE
'CREATE TABLE NEW_BW_COLUMN_ROW_CELL_JOIN AS
(
SELECT *
FROM BW_COLUMN_ROW_CELL_JOIN
PIVOT
(
MAX(STRING_VALUE)
FOR COLUMN_NAME IN ('||AGG_COLUMNS||')))';
END;
end;
Error(9,5): PL/SQL: Statement ignored
Error(17,36): PLS-00201: identifier 'AGG_COLUMNS' must be declared
Thanks
The immediate error is that the local variable AGG_COLUMNS is declared in the first nested PL/SQL block. That means that it is out of scope as soon as the first nested block completes. You cannot, therefore, use it in the second nested PL/SQL block. You can fix that by declaring the local variable in your procedure's declaration section. You can also get rid of the nested PL/SQL blocks
create or replace procedure sample
is
AGG_COLUMNS VARCHAR2(2000);
begin
EXECUTE IMMEDIATE 'SELECT COLUMNS FROM COLUMN_NAMES' INTO AGG_COLUMNS;
EXECUTE IMMEDIATE
'CREATE TABLE NEW_BW_COLUMN_ROW_CELL_JOIN AS
(
SELECT *
FROM BW_COLUMN_ROW_CELL_JOIN
PIVOT
(
MAX(STRING_VALUE)
FOR COLUMN_NAME IN ('||AGG_COLUMNS||')))';
end;
This should remove the immediate compilation error. I'm not sure, though, whether that resolves all your problems.
COLUMN_NAMES isn't a table in a default Oracle install. This would have to be something that you created in order for this code to run.
If you did create the COLUMN_NAMES table and COLUMNS stores a comma-separated string, then there is no need to use dynamic SQL to query the table. You can do a simple SELECT ... INTO.

Resources