Oracle: problem with constructing JMS message - oracle

After some struggle with Oracle Advanced Queuing and dbms_aq package
I encountered another issue. I copied code from Oracle tutorials
but when I compile this code:
create or replace
procedure jms_test(msg varchar2)
is
id pls_integer;
message sys.aq$_jms_stream_message;
enqueue_options dbms_aq.enqueue_options_t;
message_properties dbms_aq.message_properties_t;
begin
message := sys.aq$_jms_stream_message.construct(0);
message.set_string_property('FROM', 'TEST');
id := message.clear_body(-1);
end;
it complains with:
Error(9,40): PLS-00302: component 'CONSTRUCT' must be declared
Error(10,10): PLS-00302: component 'SET_STRING_PROPERTY' must be declared
Error(11,16): PLS-00302: component 'CLEAR_BODY' must be declared
I think this code works out of procedure body, because I tried with success
recipes from What's in my JMS queue?
My Oracle version is:
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
Any idea what can be wrong?

Looks like a database version problem. AQ$_JMS_STREAM_MESSAGE has a construct method in 10G but not in 9i. What version of Oracle Server are you using?

Looks like grants again
GRANT EXECUTE ON SYS.aq$_jms_stream_message To <your-user>;
Does:
desc sys.aq$_jms_stream_message
work in SQL*Plus from both the SYS + your schema?
Note that SYS.AQ$_JMS_STREAM_MESSAGE is a datbase object/type, whereas SYS.DBMS_AQ is a package
EDIT
Ok... maybe the TYPE body is missing / invalid. What does:
SELECT owner, object_name, object_type, status
FROM dba_OBJECTS
WHERE OBJECT_NAME = 'AQ$_JMS_STREAM_MESSAGE'
return?

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;

PLS-00201 identifier must be declared referencing user defined type as SYS

I am having a problem with certain defined TYPEs in my package create scripts -
I receive the following for certain TYPEs
PLS-00201 identifier must be declared
For instance;
Error(7,23): PLS-00201: identifier 'another_schema.some_table_type' must be declared
Error(8,23): PLS-00201: identifier 'another_schema.some_object_type' must be declared
I should note that I am changing these scripts - which ran fine before - where previously they were run as the script owner, which now is a container schema/user only - and the create scripts are being executed as SYS. (it is a dev database and they have not created a user yet for me to use to do this other than SYS so far)
(The packages compiled previously -when run as the schema owner with appropriate privileges.)
This package (and various other objects, views procedures and functions) access both objects in its schema owns as well as those in another schema.
In this case - the issue is with SOME defined TYPEs (and tables of type) that are in the referenced schema - where I get the PLS-00201 error.
In the code below, when compiling the error is generated for the references to;
l_tc_data another_schema.some_table_type := another_schema.some_table_type();
l_tc_obj another_schema.some_object_type;
but not;
l_loc_t another_schema.location_ref_t;
which are in the same "other" schema.
create or replace PACKAGE BODY example_schema.example_pkg
AS
function getSomeData (p_project in varchar2, p_start_date in date, p_end_date in date, p_timezone in varchar2 := 'UTC')
return fancydatatabletype is
l_cursor SYS_REFCURSOR;
l_tsdata fancydatatabletype := fancydatatabletype();
l_tc_data another_schema.some_table_type := another_schema.some_table_type();
l_tc_obj another_schema.some_object_type;
t_data fancydatatype;
l_project VARCHAR2(20);
l_timezone VARCHAR2(40);
l_start DATE;
l_end DATE;
l_loc_t another_schema.location_ref_t;
BEGIN
l_tc_obj := another_schema.some_object_type(null, 1, 2, 3, 'test');
-- .... more stuff
END getSomeData;
So my questions are;
1. could it possibly be an issue with privileges ? (running as SYS)
2. what other things should I look at that could produce this error ? (since they do exist)
I can successfully query the TYPES, so they do exist, are named the same and the user (SYS in this case) can "see" them;
select * from ALL_TYPES where type_name like 'some_table_type%';
I know I am being dumb, blind or just plain at the limits of my Oracle skills - so hoping someone can help me figure it out and learn for the next time !
The referenced objects are owned by ANOTHER_SCHEMA. You are attempting to use them in PL/SQL owned by EXAMPLE_SCHEMA. So the most likely explanation is the grants between the two schemas.
In order to use them in code, ANOTHER_SCHEMA must have granted privileges directly to EXAMPLE_SCHEMA, that is by name and not through a role. This is due to the way Oracle's security model works.
You can check the extant grants like this:
select table_name as object_name
, privilege
, grantor
from dba_tab_privs
where grantee = 'EXAMPLE_SCHEMA'
and table_owner = 'ANOTHER_SCHEMA'
/

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

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

Websphere JDBC-adapter fails to call an oracle stored procedure

I've posted to the mqseries forum too, but haven't got any answers yet.
I have problems using a Websphere adapter for JDBC in order to call an Oracle stored procedure. The procedure looks like this:
create or replace
procedure sp_myproc(par_out out SYS_REFCURSOR)
as
begin
open par_out for select * from my_table;
end;
I have generated the BO definition using ODA. I have also read this:http://pic.dhe.ibm.com/infocenter/dmndhelp/v7r0mx/index.jsp?topic=%2Fcom.ibm.wsadapters.jca.jdbc.doc%2Fdoc%2Fcjdb_ov_storedproc_bo.html
My question is how to specify the ASI for the RetrieveSP correctly?
If I use: SPN=sp_myproc;RS=true;OP=RS I get the following error: "ResultSet as output parameter for Stored Procedure not supported for database Oracle and JDBC Driver oracle.jdbc.OracleDriver".

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.

Resources