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.
Related
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;
/
I want to create schema dynamically i.e. it should prompt for the input. Or how to use collections, nested table to create users from PL/SQL code blocks i.e. procedures, functions etc?
I give you a small example for that:
create or replace procedure p(p_user varchar2) is
begin
execute immediate 'create user '||p_user||' identified by x';
end;
/
begin
p('&user');
end;
/
Here the procedure gets a parameter which can be used to put together your DDL commands. The procedure must be called somehow. You can call it from sqlplus, or execute it via web server, or from a desktop app, etc. I wrote the last 4 lines as example how to call it from sqlplus. Sqlplus can prompt and read input from user.
I'm new to PL/SQL & would greatly appreciate help in this. I've created a procedure to copy contracts. Now I want to call another procedure from within this procedure which shall copy all the programs related to the contract I'm copying. One contract can have multiple programs.
You cal call another procedure in another package by using PackageName.ProcedureName(vcParameters => 'InputParameter1'); If the procedure is in the same package you could do it without the PackageName, so just ProcedureName(vcParameters => 'InputParameter1');
You call a procedure by simply putting its name and parameters in your code, e.g.
begin
dbms_output.put_line('Demo');
end;
or within a procedure,
create or replace procedure demo
as
begin
dbms_output.put_line('Demo');
end;
I have used dbms_output.put_line as an example of a procedure, but obviously any other procedure would be called the same way:
begin
foo;
bar(1);
demo(true, 'Bananas', date '2018-01-01');
end;
For some reason, many beginners are tempted to add exec before the procedure call. I don't know where that comes from because PL/SQL has no such keyword. Possibly they are thinking of the SQL*Plus execute command, which can be abbreviated to exec. However, SQL*Plus is a separate command line utility with its own commands that have nothing to do with the PL/SQL language.
This question already has answers here:
Parsing PL/SQL code to check against syntax and semantic errors
(4 answers)
Closed 6 years ago.
I would like to be able to validate that a piece of code is correct using only PL/SQL.
For example, I have the following code in a variable, I would like to validate it:
my_code:='BEGIN
package1.get_wordlist_keywords_PG;
package1.get_wordlist_keyword_cat_PG;
END;
'
I would like to do something like:
result:=validate_code(my_code);
and result would be "valid" or "invalid" (or with error message etc.)
I am sure this would be possible, as Oracle Apex allows users to enter PL/SQL and runs a validation on the code when it is saved.
I am on Oracle 12c.
Thanks!
P.S. - I do not need to validate a simple sql select, it needs to be a PL/SQL code block.
Probably put your code in a procedure instead of anonymous block.
CREATE OR REPLACE PROCEDURE p1 AS
BEGIN
package1.get_wordlist_keywords_PG;
package1.get_wordlist_keyword_cat_PG;
END;
/
show errors;
After the execution, the procedure may or may not be created successfully. Though the procedure is created successfully, the code inside the procedure
is not executed.
CREATE OR REPLACE PROCEDURE VALIDATE_PLSQL
(
PLSQL IN VARCHAR2
, MY_RESULT OUT VARCHAR2
) AS
my_code varchar2(31900);
validate_code varchar2(32000);
status varchar2(4000);
BEGIN
my_code:=PLSQL;
validate_code:='create or replace procedure testp1 AS '||my_code;
BEGIN
status:='PASSED';
EXECUTE IMMEDIATE validate_code;
exception
when OTHERS then
status:='FAILED';
END;
EXECUTE IMMEDIATE 'drop procedure testp1';
MY_RESULT:=status;
END VALIDATE_PLSQL;
Pass in the block to be validated in "PLSQL" get the results in "MY_RESULT"
Clunky, but works!
This problem came up when trying out the Unit Testing capabilities of SQLDeveloper.
When running a test for a procedure that is created within my schema I am seeing an error however when the same procedure is run in one of the oracle supplied schemas it works without an issue.
SQL Developer generates the following calls:
1) This one doesn't work (error is shown below):
BEGIN
"IANC"."SIMPLE_PARAMETER"(P_X => 123);
END;
2) This one does:
BEGIN
"HR"."SIMPLE_PARAMETER"(P_X => 123);
END;
This is the procedure:
CREATE OR REPLACE PROCEDURE SIMPLE_PARAMETER
(
P_X IN NUMBER
)
IS
BEGIN
null;
END SIMPLE_PARAMETER;
The following is the output from SQLPLUS, where you can see when the procedure is run in my schema I see an error whilst when running the same procedure in another schema the procedure works as expected:
In case of need my I am using Oracle Enterprise Edition 11.2.0.1.0
Update
Screen shot showing procedure signatures
I should also mention that if I remove the schema name from the procedure call then the procedure runs and completes as expected.
Thanks in advance for any help received.
Are you sure that the SIMPLE_PARAMETER procedure in IANC is the same (or at least has the same signature) as the one in HR? What do you get from `DESCRIBE "IANC"."SIMPLE_PARAMETER".
(P.S. since your identifiers are all upper-case, you shouldn't need the double quotes at all.)
Added: Another possibility is that you have a package called IANC in the IANC schema, so Oracle is looking for a procedure in that package called SIMPLE_PARAMETER that does not exist. Example:
SQL> exec bigdecimaltest
PL/SQL procedure successfully completed.
SQL> exec dcosta.bigdecimaltest
PL/SQL procedure successfully completed.
SQL> create or replace package dcosta as
2 end;
3 /
Package created.
SQL> exec dcosta.bigdecimaltest
BEGIN dcosta.bigdecimaltest; END;
*
ERROR at line 1:
ORA-06550: line 1, column 14:
PLS-00302: component 'BIGDECIMALTEST' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
This seems like buggy behavior -- if the attempt to resolve the name as package.member doesn't succeed, I think Oracle ought to then try it as schema.object, but it looks like once it has found a match on the package name it won't reconsider that.