We want to move our automated statistics gathering from an external script into Oracle 9i's job scheduler. It's a very simple job, and the code basically looks like this:
DBMS_JOB.SUBMIT(
JOB => <output variable>,
WHAT => 'DBMS_STATS.GATHER_DATABASE_STATS(
cascade => TRUE, options => ''GATHER AUTO'');',
NEXT_DATE => <start date>,
INTERVAL => 'SYSDATE + 7');
The job gets created successfully and runs, but fails with the error:
ORA-12012: error on auto execute of job 25
ORA-20000: Insufficient privileges to analyze an object in Database
ORA-06512: at "SYS.DBMS_STATS", line 11015
...
The part I don't get is that the user I submitted the job under has the right permissions to gather those database statistics -- if I run the command manually it works. I was curious if Oracle was ignoring any role-based privileges the user had like it does with creating procedures so I directly granted the user ANALYZE ANY, but still no dice.
Are there some other permissions I'd have to directly grant the user to make this work? I'd rather not have to make a separate job for each schema (which does work if I submit the job under the schema's owner).
What version of 9i are you on. I recall reading on a AskTom thread about 9.2.0.1 having an issue and needing to do a grant select ( i will look up the thread )
Also since you are running DB stats not subroutine ANALYZE ANY DICTIONARY
Related
Trying to set up a scenario of record locks due to pending distributed transactions.
Goal: get some rows into DBA_2PC_PENDING for training purposes and forcing commits/rollbacks/purging entries etc.
According to Database Administrator's Guide (12c)
https://docs.oracle.com/database/121/ADMIN/ds_txnman.htm#ADMIN12285
in section 35.9 Simulating Distributed Transaction Failure
the following code should accomplish what I need:
DECLARE
l_tran_id VARCHAR2(200);
BEGIN
l_tran_id := dbms_transaction.local_transaction_id(true);
DBMS_OUTPUT.PUT_LINE('l_tran_id: ' ||l_tran_id);
abc.package1.proc1#DB2 ( parm1 => 'XXX' );
COMMIT COMMENT 'ORA-2PC-CRASH-TEST-5';
END;
But when I run this, I get ORA-01031: insufficient privileges with error pointing to line holding the commit.
If I change to COMMIT COMMENT 'hooray';
I don't get error, but of course I don't get my results of a pending transaction.
What privileges is it complaining about?
i have oracle database (11g) trigger run after inserting on table, i need to run external program by this trigger through windows command like this:
c:\my_external_apps\app1.exe arg1 arg2 arg3
i am trying this code but it doesn't work:
create or replace TRIGGER GE_MAIN_NOTIFICATION_SEND AFTER INSERT ON TABLE
REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW BEGIN
SYS.DBMS_SCHEDULER.create_program(program_name => 'UPLOADNC', program_type => 'EXECUTABLE',
program_action => 'C:\WINDOWS\SYSTEM32\CMD.exe /C c:\my_external_apps\app1.exe arg1 arg2 arg3 ',
enabled => TRUE);
END;
and this is the error
ORA-04088: error during execution of trigger 'DURRA.GE_MAIN_NOTIFICATION_SEND'
27486. 00000 - "insufficient privileges"
*Cause: An attempt was made to perform a scheduler operation without the
required privileges.
*Action: Ask a sufficiently privileged user to perform the requested
operation, or grant the required privileges to the proper user(s).
how i can do that?? i am beginner with oracle database
The error is telling you that you haven't been granted the privileges necessary to call dbms_scheduler.create_program. I expect that you are missing the create job privilege.
However, if you resolve that problem, your next problem will be that dbms_scheduler.create_program does an implicit commit and commits are not allowed inside triggers. That means that you cannot call dbms_scheduler.create_program from a trigger (unless you made the trigger an autonomous transaction which would create a separate set of issues). The right way to solve the problem would almost certainly be to use the older dbms_job package. Since that package doesn't implicitly commit, you can submit a job as part of a larger transaction.
Of course, if you're using the dbms_job package to do your job scheduling, you lose out on the ability of dbms_scheduler to call out to the operating system. Instead, you'd need to do something like creating a Java stored procedure that calls out to the operating system. There are multiple examples of this on the web, I linked to one from Tom Kyte.
So, at a high level, your trigger would call dbms_job.submit to submit the job. The job would then call your Java stored procedure. Your Java stored procedure would make the actual call out to the operating system of the database server.
I am trying to schedule a job using DBMS_JOB (I can't use DBMS_SCHEDULER for security reasons), which uses a DDL statement.
DECLARE
job_num NUMBER;
BEGIN
DBMS_JOB.SUBMIT(job => job_num,
what => 'BEGIN EXECUTE IMMEDIATE ''CREATE TABLE temp1 (ID NUMBER)''; END;'
);
DBMS_OUTPUT.PUT_LINE('JobID'||job_num);
DBMS_JOB.RUN(job_num);
END;
/
It fails to execute giving me an error message :
ORA-12011: execution of 1 jobs failed
ORA-06512: at "SYS.DBMS_IJOB", line 548
ORA-06512: at "SYS.DBMS_JOB", line 278
ORA-06512: at line 8
On removing the DBMS_JOB.RUN() statement from inside the anonymous block, I am able to at least create (and save) the job. When I check the job, it has saved this as the code to execute
BEGIN EXECUTE IMMEDIATE 'CREATE TABLE temp1 (id NUMBER) '; END;
If I execute it standalone, it obviously executes. The only time it fails it when I try to execute the entire thing through the call to DBMS_JOB.RUN().
Is there a restriction on using DDL statements as a parameter in DBMS_JOB? I can't find any pointer in documentation for this.
While echoing the sentiments of the other commenters-- creating tables on the fly is a red flag that often indicates that you really ought to be using global temporary tables-- a couple of questions.
Is there a reason that you need the DBMS_JOB.RUN call? Your call to DBMS_JOB.SUBMIT is telling Oracle to run the job asynchronously as soon as the parent transaction commits. So, normally, you'd call DBMS_JOB.SUBMIT and then just `COMMIT'.
Does the user that is submitting job have the CREATE TABLE privilege granted directly? My guess is that the user only has the CREATE TABLE privilege granted via a role. That would allow you to run the anonymous PL/SQL block interactively but not in a job. If so, you'll need the DBA to grant you the CREATE TABLE privilege directly, not via a role.
When a job fails, an entry is written to the alert log with the error message. Can you (or, more likely, the DBA) get the error message and the error stack from the alert log and post it here (assuming it is something other than the privileges issue from #2).
I have a table in Oracle 11.2 database. I want the database to run an executable file on a remote server if a specific cell in table1 is updated to a value of 1 AND if the number of existing rows in table2 is > 0. I don't have much experience with what is possible in databases -- is the following possible to achieve this?
create a job using Oracle Scheduler. The job runs immediately, and is used to run an external executable program on a remote server. The job exists, but is not run until step 5 below (is this possible?).
http://docs.oracle.com/cd/E11882_01/server.112/e17120/schedadmin001.htm#BAJHIDDC
attach a DML trigger to the column of the table that fires on an UPDATE statement.
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#CIHEHBEB
have the trigger invoke a PL/SQL subprogram
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#CIHEGACF
in the PL/SQL subprogram, perform the following business logic: if a specific cell in table1 equals 1, AND if the number of rows in table 2 is greater than 0, proceed to step 5, otherwise stop (exit, quit).
Run the job in step 1
Or, if the job/scheduler is not made to provide this functionality, is there another way to achieve the same thing? That is, have a change in a database table trigger an external job.
UPDATE 1:
I wonder if it's possible to implement steps 1-5 above by just using Oracle Scheduler with DBMS_SCHEDULER.CREATE_JOB using parameter event_condition?
http://docs.oracle.com/cd/E11882_01/server.112/e25494/scheduse005.htm#CHDIAJEB
Here's an example from the above link:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'process_lowinv_j1',
program_name => 'process_lowinv_p1',
event_condition => 'tab.user_data.event_type = ''LOW_INVENTORY''',
queue_spec => 'inv_events_q, inv_agent1',
enabled => TRUE,
comments => 'Start an inventory replenishment job');
END;
The above code creates a job that starts when an application signals the Scheduler that inventory levels for an item have fallen to a low threshold level.
Could the above code somehow be modified to perform the intended steps? For example, could steps 2-4 above be eliminated by using event_condition here instead? etc. If so, what would it look like, for example, how to set the queue_spec?
Assuming that you install the Oracle Scheduler Agent on the remote server, DBMS_SCHEDULER can run an executable on the remote machine. I would have the DML trigger enqueue a message into an Oracle Advanced Queue (AQ) and use that queue to create an event-based job (DML triggers are not allowed to commit or rollback the transaction but running a DBMS_SCHEDULER job implicitly issues a commit so DML triggers cannot directly run a job). The event-based job and the job that runs the remote executable would be part of a job chain.
I have written one procedure and one job.
From job I am running procedure. Following is the script for creating job
DBMS_SCHEDULER.create_job (job_name => 'IBPROD2.RUN_FETCH_ACCT_ALERTS',
job_type => 'STORED_PROCEDURE',
job_action => 'FETCH_ACCT_ALERTS',
start_date => sysdate,
repeat_interval => 'FREQ=HOURLY;INTERVAL=2;',
enabled => TRUE,
auto_drop => FALSE
);
After creating job I am running following command to get job details for owner IBPROD2 where I can see failure_count column value as 1 for RUN_FETCH_ACCT_ALERTS job.
There is no problem in procedure FETCH_ACCT_ALERTS when I run it manually.
Can anyone help me in why the job is failing? Am I missing something?
Query the ALL_SCHEDULER_JOB_RUN_DETAILS view (or perhaps the DBA equivalent).
select *
from all_scheduler_job_run_details
where job_name = 'IBPROD2.RUN_FETCH_ACCT_ALERTS'
You'll be particularly interested in the error# which will give you an Oracle error number you can look up. Also, the additional_info column might have some, er, additional info.
The error code means this:
ORA-28179: client user name not provided by proxy
Cause: No user name was provided by the proxy user for the client user.
Action: Either specify a client database user name, a distinguished name or an X.509 certificate.
So it's something to do with your security set up. Authentication is failing for reason. As I lack a detailed knowledge of your architecture (and I'm not a security specialist) I'm not in a position to help you.
Because I have already created many jobs to run different procedures
with same owner. All are running successfully.
So in what way does this procedure differ from all the others?