Ending PLSQL procedure - plsql

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

Related

Executing procedure in plsql developer

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;

Dynamic Assignment to PLSQL Type variable

I have a scenario where I have to perform dynamic assignment to PLSQL type variable.
For example, below is a simple assignment of value to type my_tab_type. fn_get_value(varchar2) function returns value based on string passed.
my_tab_type.table_name.LEAD := fn_get_value('LEAD_ID');
Like these there will be hundreds of assignments. I want to store the mapping (LEAD,LEAD_ID) in a table, fetch these mapped values in a cursor and dynamically create assignment statement.
I want to avoid execute immediate or dbms_sql.execute for each dynamic assignment created as performance will be affected. Please help me come up with an feasible and effective approach.
(You might have a XY-problem.)
You don't tell us the types in your question so I assume nested table of records.
You can't assign a PL/SQL record "dynamically" without using dynamic PL/SQL (i.e. running PL/SQL with execute immediate). This also means that all uses of such "dynamically" created record have to take place dynamically. That's not the way PL/SQL is supposed to be used.
However if you can change your data type to associative array you can archive your goal with a plain boring static well-mannered PL/SQL !
Below you'll find an example that should get you started.
Example
create table so60 (
from_ varchar2(20)
,to_ varchar2(20)
);
insert into so60 values('A_FROM', 'A_TO');
insert into so60 values('B_FROM', 'B_TO');
insert into so60 values('C_FROM', 'C_TO');
declare
-- foo_t is an associative array
type foo_t is table of varchar2(32767) index by varchar2(32767);
v_foo foo_t;
function f(p_x in varchar2) return varchar2 is
begin
return lower(p_x);
end;
begin
-- initialize from table
for i in (select * from so60)
loop
v_foo(i.to_) := f(i.from_);
end loop;
dbms_output.put_line(v_foo('B_TO'));
end;
/
Example run
SQL> #so60
b_from
PL/SQL procedure successfully completed.
SQL>

How read a value in pl/sql procedure?

I am having problem regarding to scan a value in a pl/sql procedure. When I have execute the procedure, it ignores the a:='&a';.
Procedure Body
create or replace PROCEDURE Testing
IS
a VARCHAR2(3);
BEGIN
DBMS_OUTPUT.PUT_LINE('Enter a : ');
a:='&a';
END Testing;
Procedure Calling
SET SERVEROUTPUT ON;
cl scr;
Execute Testing;
Output
PL/SQL procedure successfully completed.
Enter a :
Can anybody help me, please!?
In SQL*Plus we have the prompt and accept syntax, but there is no direct way to make PL/SQL interactive without using PHP, Apex, Java, Scripting. I am giving you example of scripting.
e.g. In Windows batch, following code will help.
1) Code for the Testing procedure is same what you have
create or replace PROCEDURE Testing (arg varchar2)
IS
a VARCHAR2(3);
BEGIN
a:=arg;
DBMS_OUTPUT.PUT_LINE('Value of a : '||a);
END
2) test.bat
sqlplus nd211/nd211 #Testing.sql te1
sqlplus nd211/nd211 #Testing.sql te4
3) Testing.sql
set serveroutput on
exec Testing('&1');
exit;
Testing;
/
4) Sample output
Value of a : te1
PL/SQL procedure successfully completed.
Value of a : te4
PL/SQL procedure successfully completed.

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.

Executing a variable in oracle

The below procedure compiled successfully. But, when I try to run the its getting error.
CREATE OR REPLACE PROCEDURE SAMPLE_PROCEDURE
AS
VARIABLE1 VARCHAR2(2000);
BEGIN
VARIABLE1:='DECLARE A TIMESTAMP:=LOCALTIMESTAMP;
CREATE GLOBAL TEMPORARY TABLE TEMP_BWXROW
(ROW_ID NUMBER(10),DIVISION VARCHAR2(256),OUTLET VARCHAR2(256),CLASS VARCHAR2(256));';
EXECUTE IMMEDIATE VARIABLE1;
END;
Error is:
6550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Can you help me, what is wrong in this.
Very strange to be dynamically creating a global temporary table. Anyway, I assume this is all part of a learning exercise ...
Try this:
CREATE OR REPLACE PROCEDURE SAMPLE_PROCEDURE
AS
VARIABLE1 VARCHAR2(2000);
BEGIN
VARIABLE1:='DECLARE A TIMESTAMP:=LOCALTIMESTAMP;
BEGIN
CREATE GLOBAL TEMPORARY TABLE TEMP_BWXROW
(ROW_ID NUMBER(10),
DIVISION VARCHAR2(256),
OUTLET VARCHAR2(256),
CLASS VARCHAR2(256));
END';
EXECUTE IMMEDIATE VARIABLE1;
END;
What's wrong with this is that you almost certainly shouldn't be creating a table at runtime and you almost certainly shouldn't be using dynamic PL/SQL and you really, really, really shouldn't be creating a table dynamically inside a dynamic PL/SQL block.
If you are absolutely determined to do so, the CREATE TABLE statement would itself need to use dynamic SQL inside of the dynamic PL/SQL block. If I've got all my quotes escaped correctly, you'd end up with something like this
CREATE OR REPLACE PROCEDURE SAMPLE_PROCEDURE
AS
VARIABLE1 VARCHAR2(2000);
BEGIN
VARIABLE1:='DECLARE
A TIMESTAMP:=LOCALTIMESTAMP;
BEGIN
EXECUTE IMMEDIATE ''CREATE GLOBAL TEMPORARY TABLE TEMP_BWXROW
(ROW_ID NUMBER(10),
DIVISION VARCHAR2(256),
OUTLET VARCHAR2(256),
CLASS VARCHAR2(256))'';
END;';
EXECUTE IMMEDIATE VARIABLE1;
END;
If I came across a piece of code doing this in one of my systems, though, I would have a very strongly worded conversation with the original developer to understand what possessed them to believe that any problem necessitated PL/SQL executing a dynamic PL/SQL block that itself executed a dynamic SQL statement.

Resources