Oracle stored procedure - difference between 10g and 11g perhaps? - oracle

The following stored procedure code works in our DEV and TEST environments which run with Oracle 11G but will not work in our 10G PROD environment:
first, I created my own data structure in Oracle to hold any array of VARCHAR2:
create or replace
type MAT_MULTIPLES_ARRAY as table of VARCHAR2(100);
here is the procedure code:
create or replace PROCEDURE MAT_SUBMIT_JOB (v_multiples_columns_to_add IN our_schema.MAT_MULTIPLES_ARRAY)
v_jobno number;
v_job_name VARCHAR2(100);
v_error_message VARCHAR2(32000);
begin
v_job_name := 'doesnt matter right now';
dbms_scheduler.create_job(v_job_name,program_name=>'MAT_JOB_PROGRAM');
dbms_scheduler.set_job_anydata_value(v_job_name,1,sys.anydata.convertCollection(v_multiples_columns_to_add));
dbms_scheduler.enable(v_job_name);
end;
again, this same code works in 11G in our DEV and TEST environments, and it compiles in our 10G environment, but then it appears to barf during runtime, on the second dbms_scheduler line (in bold).
Does dbms_scheduler work in 10G? Or perhaps there is a problem with 'sys.anydata.convertCollection(v_multiples_columns_to_add)'
Here is the error message:
ORA-22370: incorrect usage of method originated from line 19 in my procedure.
line 19 is the line with convertCollection() call.
Please help!

I found this in the documentation:
http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sched.htm#i1000820
SET_JOB_ANYDATA_VALUE requires that you be the owner of the job or have ALTER privileges on that job. You can also set a job argument value if you have the CREATE ANY JOB privilege.
This might also be related as well:
ANYDATA with Collections based on rowtype

Related

How to create and drop a table inside Oracle function?

I have the function in which I need to drop and create tables. In the example below I try to create the table but it fails
CREATE OR REPLACE FUNCTION DEVTEST
RETURN NUMBER
IS
COMMAND VARCHAR2(256);
ID VARCHAR2(128);
NAME VARCHAR2(128);
TMP_LIST VARCHAR2(128);
BEGIN
ID := '12345';
NAME := 'ABCdef';
TMP_LIST := 'tmpTest';
command := 'create table ' || TMP_LIST || ' ( USER_ID VARCHAR2(11), USER_NAME VARCHAR2(36))';
DBMS_OUTPUT.PUT_LINE('command = ' || command);
EXECUTE IMMEDIATE command;
return 0;
END;
I call the function:
select NSB_DEVTEST() from dual
And get the error:
ORA-14552: cannot perform a DDL, commit or rollback inside a query or DML ORA-06512: at "DEV1_SERVER.DEVTEST", line 15
How do I correct this to create/drop a table inside a function?
My server details:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
PL/SQL Release 10.2.0.5.0 - Production
CORE 10.2.0.5.0 Production
TNS for Solaris: Version 10.2.0.5.0 - Production
NLSRTL Version 10.2.0.5.0 - Production
The problem is not with the function but with it being called from a SQL statement rather than from a pl/sql block.
A SELECT statement in SQL is equivalent to a READ operation that comes with read consistency. It cannot make any changes to the database. The database should always be the same before and after the "READ" operation completed, otherwise it would be a WRITE operation and the entire database consistency would go havoc.
Also, like the error says, DDL operations do a COMMIT behind the scenes before they start. Any read consistent operation should never do any COMMITS and write to the database without the user knowing.
You can instead call the function from pl/sql like this -
DECLARE
l_result NUBMER;
BEGIN
l_result := DEVTEST;
DBMS_OUTPUT.PUT_LINE(l_number);
END;
Still I would prefer writing a procedure for this, so others don't get confused by why this can't be called from SQL. The general rule that I follow for myself is that - Functions "get" things and Procedures "do" things (like DML).
The answer to your question is: don't. Production code, on the whole, shouldn't be creating tables on the fly. If you need a table to hold data temporarily, then create a Global Temporary Table (GTT) once and have your code refer to it.
The reason why you're getting that error (apart from it being self-evident from the error message) is because you're calling the function from within a SQL statement. You can't do that; you'd have to call it directly in PL/SQL.
I'm curious as to why you think this approach is a good, feasible approach, and also what you're going to be doing with the table once you've created it.
Your code is perfect no problem in the code . the problem is while you try to execute
you can only execute a pure function in select statement, which means a function without ddl & dml . ( if you use pragma autonomous_transaction while performing dml inside a function then you can use it in select statement ). When function has DDL command you can never ever execute it in select statement , but instead you can only execute it in PLSQL block like this
declare
a number;
begin
a:= devtest;
end;
/
and you can check your table
select * from tmptest;

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.

Including the schema name when calling a PL/SQL procedure doesn't work in one schema but does in another

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.

How to execute an oracle stored procedure?

I am using oracle 10g express edition. It has a nice ui for db developers. But i am facing some problems executing stored procedures.
Procedure:
create or replace procedure temp_proc is
begin
DBMS_OUTPUT.PUT_LINE('Test');
end
it is created successfully. But when i execute:
execute temp_proc;
it shows ORA-00900: invalid SQL statement
So help needed here
Execute is sql*plus syntax .. try wrapping your call in begin .. end like this:
begin
temp_proc;
end;
(Although Jeffrey says this doesn't work in APEX .. but you're trying to get this to run in SQLDeveloper .. try the 'Run' menu there.)
Oracle 10g Express Edition ships with Oracle Application Express (Apex) built-in. You're running this in its SQL Commands window, which doesn't support SQL*Plus syntax.
That doesn't matter, because (as you have discovered) the BEGIN...END syntax does work in Apex.
Both 'is' and 'as' are valid syntax. Output is disabled by default. Try a procedure that also enables output...
create or replace procedure temp_proc is
begin
DBMS_OUTPUT.ENABLE(1000000);
DBMS_OUTPUT.PUT_LINE('Test');
end;
...and call it in a PLSQL block...
begin
temp_proc;
end;
...as SQL is non-procedural.
I use oracle 12 and it tell me that if you need to invoke the procedure then use call keyword.
In your case it should be:
begin
call temp_proc;
end;
Have you tried to correct the syntax like this?:
create or replace procedure temp_proc AS
begin
DBMS_OUTPUT.PUT_LINE('Test');
end;
In Oracle SQL Developer (GUI), using 12c, also don't forget to enable the DMBS Output window (click View => Dbms Output, then click "+" sign, and select your connection), by default the window is not enabled.
The following syntax will then output to this window:
begin
temp_proc
end;
You can do simply the following on the Command Window:
Connected to Oracle Database 19c Enterprise Edition Release 19.0.0.0.0
Connected as XXX#YYY
SQL> call temp_proc();
Or:
SQL> execute temp_proc();

Running Oracle stored Procedure

I have a sql file that contains a simple procedure to print "Hi" like,
CREATE OR REPLACE PROCEDURE skeleton
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Hi');
END;
When I try to execute this from sql file itself, it just gets compiled and it is not running.
I added the as,
CREATE OR REPLACE PROCEDURE skeleton
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Hi');
END;
/ /* this is required else it throws me compilation error*/
set serveroutput on
EXECUTE skeleton;
I tried calling the same skeleton from other sql file also and even from the sqldeveloper GUI, that also didnt execute this. Only the sqlplus commandline helps me. Let me know what I am missing and the solution for this.
Here are the steps I took using SQL Plus
SQL> CREATE OR REPLACE PROCEDURE skeleton
2 IS
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE('Hi');
5 END;
6 /
Procedure created.
SQL> set serveroutput on
SQL> EXECUTE skeleton;
Hi
PL/SQL procedure successfully completed.
SQL>
Can you start a new sqlplus session replicate these steps and post the content?
The only change I had to make to your sql to allow running it as an #file was to remove the comment. This is the whole content of the the .sql file:
CREATE OR REPLACE PROCEDURE skeleton
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Hi');
END;
/
set serveroutput on
EXECUTE skeleton;
You should get an output something like this:
C:\Temp>sqlplus username/password #skeleton.sql
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Oct 5 17:10:46 2009
Copyright (c) 1982, 2007, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Procedure created.
Hi
PL/SQL procedure successfully completed.
SQL>
Try setting set serveroutput on before the dbms_output.
In SQL Developer, you need the "execute script" button which is the second button at the top left (little green arrow in front of document) instead of the one with the big green arrow.
That threw me the first time I used it.
(source: devshed.com)
The reason your first example gets compiled and not run, is that you are not actually asking it to run. You are creating a procedure inside the database, which works correctly, but not calling it. In your second block you have an EXECUTE which is where it actually runs.

Resources