How to scheduled a job on an Oracle standby database - plsql

Can anybody tell me how to schedule a job on a standby database using dbms_scheduler? The following PLSQL works on the primary but doesn't work on the standby. It schedules a job to drop a restore point.
DECLARE
rp_drop_time DATE;
BEGIN
SELECT to_date(to_char(next_working_day, 'DD-MON-YYYY')||' 19:00', 'DD-MON-YYYY HH24:MI') rp_drop
INTO rp_drop_time
FROM (
SELECT
CASE WHEN to_char(sysdate, 'D') IN (5,6) THEN next_day(sysdate, 'Monday')
ELSE sysdate + 1 END next_working_day
FROM dual
);
dbms_scheduler.create_job
( job_name => 'RP0567901235'
, job_type => 'PLSQL_BLOCK'
, job_action => 'BEGIN EXECUTE IMMEDIATE ''DROP RESTORE POINT "RP0567901235"''; END;'
, number_of_arguments => 0
, start_date => rp_drop_time
, enabled => TRUE
);
END;
/

It's not possible to schedule a job on a physical standby DB as it's in mount mode (normally). Use an alternative method to drop a GRP at a future date - like a cronjob, 'at' cmd, OEM Job etc.

Related

How to ignore "Application collection already exists" error?

How can I ignore the errors below?
create_co - errc=-20104 errm=ORA-20104: create_collection_from_query_b Error:ORA-20101: Application collection exists
create_co - errc=-20104 errm=ORA-20104: create_collection_from_queryb2 Error:ORA-00001: Schending van UNIQUE-beperking (APEX_180200.WWV_FLOW_COLLECTIONS_UK).
This error is confusing for users.
declare
pl_query varchar2(4000);
cl_collectie constant varchar2(255) := 'MY_COLLECTION';
begin
--
if apex_collection.collection_exists( p_collection_name => cl_collectie )
then
apex_collection.delete_collection( p_collection_name => cl_collectie );
end if;
--
pl_query := q'[select QUERY]' ;
--
apex_collection.create_collection_from_queryb2( p_collection_name => cl_collectie
, p_query => pl_query );
end;
We're using Application Express 18.2.0.00.12.
if you run the dynamic action for example on button click then you have to disable the button until the dynamic action is finished. generally you need to find a way to prevent your users from running the dynamic action a second time if the first time isn't finished yet.

PLSQL is it possible to update a table column on a certain date?

I have this table :
penalities(player,dateofpenality,penalityDays,status)
Based on certain criteria a player is added to this table where the status goes to 'yes'. I want his status to change to 'no' jusrt after the penality period (=penalityDays) is gone.
I thought of a trigger on date but I couldn't find it in plsql.
Please note that I don't want to delete the player as I need the history .
The only way to do this is to schedule a background job which kicks off once a day.
Write a simple stored procedure to apply the change of status:
create or replace procedure update_penalty_status as
begin
update penalties
set status = 'no'
where sysdate >= dateofpenality + penalityDays
and status = 'yes';
commit;
end update_penalty_status;
Then submit a job to run once a day. This uses DBMS_SCHEDULER (available since 10g) rather than the older DBMS_JOB.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'your_schema.my_job1',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN update_penalty_status; END;',
start_date => trunc(sysdate)+1,
repeat_interval => 'FREQ=DAILY'
enabled => TRUE,
comments => 'Revoke expired penalties');
END;
/
Note that you will need the CREATE JOB privilege to do this. You may need to ask your DBA for help and guidance. Normally I would link to the Oracle documentation at this point, but I think the Oracle-Base article is a friendlier place to start.

Oracle Scheduled Job Succeeded, but Stored Procedure isn't executed

I've come across several posts that almost have the same problem as I do, but I haven't found an answer that fits my situation.
I have a stored procedure, that when run manually through SQL Developer, the procedure runs and finishes successfully, I see data updated which suggests that the commits are working.
I have a job that is scheduled to run daily, and it does.
I can run the job manually, i.e. an anonymous block in SQL Developer that
executes it.
I can "right-click" --> "Run Job"
Each of these methods work, and they report a Status of "SUCCEEDED" in the run log. However, the execution time is always 00:00:00; and no data is updated in the database.
This is the anonymous block that SQL Developer created when I created the job.
DBMS_SCHEDULER.CREATE_JOB (
job_name => '"OWNER"."GSS"',
job_type => 'STORED_PROCEDURE',
job_action => 'OWNER.PKG_GSS.GENERATE_GSS_DATA',
number_of_arguments => 2,
start_date => TO_TIMESTAMP_TZ('2018-05-09 11:47:15.000000000 AMERICA/NEW_YORK','YYYY-MM-DD HH24:MI:SS.FF TZR'),
repeat_interval => 'FREQ=DAILY;BYDAY=MON,TUE,WED,THU,FRI;BYHOUR=6',
end_date => NULL,
enabled => TRUE,
auto_drop => FALSE,
comments => '');
The 2 arguments are set as well, I just didn't add it here.
Any suggestions would be greatly appreciated!!!!!
I have the same issue, my issue is resolved by granting the permission to the Procedure and recreating the job scheduler on daily basis.
Below is the procedure I wrote:
create or replace PROCEDURE dist_auto_eod AS
v_sp_code VARCHAR2(100);
v_count_eod NUMBER;
v_count_atn NUMBER;
BEGIN
FOR data IN (
SELECT
sp_code,
company_code,
branch_code
FROM
dist_login_user
WHERE
is_mobile = 'Y'
) LOOP
BEGIN
SELECT
COUNT(track_type)
INTO
v_count_eod
FROM
dist_lm_location_tracking
WHERE
track_type = 'EOD'
AND
TO_DATE(submit_date) = trunc(SYSDATE)
AND
sp_code = data.sp_code;
END;
BEGIN
SELECT
COUNT(track_type)
INTO
v_count_atn
FROM
dist_lm_location_tracking
WHERE
track_type = 'ATN'
AND
TO_DATE(submit_date) = trunc(SYSDATE)
AND
sp_code = data.sp_code;
IF
v_count_eod = 0 AND v_count_atn = 1
THEN
INSERT INTO dist_lm_location_tracking (
sp_code,
submit_date,
latitude,
longitude,
track_type,
company_code,
branch_code,
remarks
) VALUES (
data.sp_code,
TO_DATE(
trunc(SYSDATE) || ' 07:22 PM',
'dd-mon-yy hh:mi AM'
),
'',
'',
'EOD',
data.company_code,
data.branch_code,
'Automatic EOD'
);
END IF;
END;
END LOOP;
COMMIT;
END;

How to create a procedure to run through table and send an email in Oracle Apex?

I'm currently using Oracle Apex 4.2 and I need a way to have the program run through a table and send a email if it has not been sent yet. What is the best way to do this and how?
It sounds like you just want something like this (I'm speculating about your table definition, the names of your columns, etc.)
FOR m IN (SELECT *
FROM email_table
WHERE sent_yet = 'N')
LOOP
apex_mail.send( p_to => m.to,
p_from => <<your email address>>,
p_body => m.text_of_email,
p_subj => m.subject );
UPDATE email_table
SET sent_yet = 'N'
WHERE primary_key = m.primary_key;
END LOOP;
The apex_mail.send procedure documentation shows more options that you can pass in. Note that if you're not already sending email in this environment using apex_mail, you probably want to have a separate job that actually sends the queued up emails. For example, this will submit a job that sends queued up emails every minute.
DECLARE
l_jobno pls_integer;
BEGIN
dbms_job.submit( l_jobno,
'begin apex_mail.push_queue( <<smtp server>>, <<port>> ); end;',
sysdate + interval '1' minute,
q'{sysdate + interval '1' minute}' );
commit;
END;
I figured out what was the issue. I need a line of code to allow apex to send emails through my application.
BEGIN
wwv_flow_api.set_security_group_id;
for rst in (
select aud.LAN_ID, aud.ID, sent.TEMPLATE_TEXT, temp.TEMPLATE_NAME from EMAIL_Audit aud
INNER JOIN EAMAIL_SENT sent
ON aud.TEMP_TEXT_ID = sent.id
INNER JOIN EMAIL_TEMP temp
ON sent.PROCESS_ID = temp.id
WHERE SENT_IND is null
)
loop
APEX_MAIL.SEND(
p_to => 'someEmail#email.com',
p_from => 'otherEmail#email.com',
p_body => rst.TEMPLATE_TEXT,
p_subj => rst.TEMPLATE_NAME );
END loop;
APEX_MAIL.PUSH_QUEUE;
END;​

What is the syntax for creating a queue subscriber in PL/SQL?

I'm trying to create a queue and a callback that triggers when a message is queued, but I can't get the callback to trigger. What am I doing wrong?
I have a trigger that enqueues a message, and I can see it on the queue message table, and I can dequeue it by hand and process it, I just can't get the callback to fire on enqueue.
BEGIN
DBMS_AQADM.CREATE_QUEUE_TABLE (
queue_table => 'queue_message_table',
queue_payload_type => 'queue_message_type',
multiple_consumers => TRUE);
DBMS_AQADM.CREATE_QUEUE (
queue_name => 'message_queue',
queue_table => 'queue_message_table');
DBMS_AQADM.START_QUEUE (queue_name => 'message_queue');
END;
CREATE OR REPLACE PROCEDURE queue_callback(
context RAW, reginfo SYS.AQ$_REG_INFO, descr SYS.AQ$_DESCRIPTOR, payload RAW, payloadl NUMBER) AS
queue_options DBMS_AQ.DEQUEUE_OPTIONS_T;
message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
my_message queue_message_type;
ret varchar2(200);
message_id RAW(16);
BEGIN
DBMS_OUTPUT.PUT_LINE('Callback');
queue_options.msgid := descr.msg_id;
queue_options.consumer_name := descr.consumer_name;
DBMS_AQ.DEQUEUE(
queue_name => descr.queue_name,
dequeue_options => queue_options,
message_properties => message_properties,
payload => my_message,
msgid => message_id );
ret := handle_message(my_message);
commit;
END;
BEGIN
DBMS_AQADM.ADD_SUBSCRIBER (queue_name => 'message_queue',
subscriber => SYS.AQ$_AGENT('queue_subscriber', 'message_queue',NULL));
DBMS_AQ.REGISTER (
SYS.AQ$_REG_INFO_LIST(
SYS.AQ$_REG_INFO(
'MESSAGE_QUEUE:QUEUE_SUBSCRIBER',
DBMS_AQ.NAMESPACE_AQ,
'plsql://QUEUE_CALLBACK',
HEXTORAW('FF')
)
), 1
);
END;
At first glance, it appears you're neither starting the queue (dbms_aqadm.start_queue), neither are you enqueueing anything to it (dbms_aq.enqueue).
I'd recommend following this demo.
You need to be careful with the database version. some bugs has been reported about issues with Oracle Aq.
In particular I've followed this link to built my own sample, executing the demo in a Oracle 11gR2 enterprise database. I was abled to enqueue, dequeue, purge the queue but the listener created with Dbms_Aq.Register didn't work.
I ran the same example downloading a Oracle 11g R2 xe database and it worked.
The same example was runned in a Oracle 10gR2 instance and it works perfectly.
There are some things that you need to be careful on using aq:
use the appropriate parameters adding the subscriber
use the appropriate namespace registering the listener with Dbms_Aq.Register
use the multiple consumers flag declaring the queue table
use the appropriate permissions to packages and to handle the queues
use the qualified name of the queues in some cases if it didn't works.
'
First create the schema
connect / as sysdba
-- #?/rdbms/admin/dbmsaqad.sql --(install if you don't have aq installed yet)
-- create the user and permissions
create user aqadmin identified by aqadmin default tablespace users temporary tablespace temp;
GRANT create session TO aqadmin;
grant connect, resource to aqadmin;
GRANT aq_administrator_role TO aqadmin IDENTIFIED BY aqadmin;
GRANT execute ON dbms_aq TO aqadmin;
GRANT execute ON dbms_aqadm TO aqadmin;
Create the ddl objects
CREATE TABLE demo_queue_message_table
( message VARCHAR2(4000) );
Create the aq-objects
create or replace type demo_queue_payload_type as object(message varchar2(4000)) ;
/
begin
DBMS_AQADM.CREATE_QUEUE_TABLE (queue_table => 'demo_queue_table', queue_payload_type => 'demo_queue_payload_type',multiple_consumers => TRUE);
DBMS_AQADM.CREATE_QUEUE (queue_name => 'demo_queue', queue_table => 'demo_queue_table');
DBMS_AQADM.START_QUEUE('demo_queue');
end;
/
CREATE or replace PROCEDURE demo_queue_callback_procedure(
context RAW,
reginfo SYS.AQ$_REG_INFO,
descr SYS.AQ$_DESCRIPTOR,
payload RAW,
payloadl NUMBER
) AS
r_dequeue_options DBMS_AQ.DEQUEUE_OPTIONS_T;
r_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
v_message_handle RAW(16);
o_payload demo_queue_payload_type;
BEGIN
r_dequeue_options.msgid := descr.msg_id;
r_dequeue_options.consumer_name := descr.consumer_name;
DBMS_AQ.DEQUEUE(
queue_name => descr.queue_name,
dequeue_options => r_dequeue_options,
message_properties => r_message_properties,
payload => o_payload,
msgid => v_message_handle
);
INSERT INTO demo_queue_message_table ( message )
VALUES ( 'Message [' || o_payload.message || '] ' ||
'dequeued at [' || TO_CHAR( SYSTIMESTAMP,
'DD-MON-YYYY HH24:MI:SS.FF3' ) || ']' );
COMMIT;
END;
/
BEGIN
DBMS_AQADM.ADD_SUBSCRIBER (
queue_name => 'demo_queue',
subscriber => SYS.AQ$_AGENT(
'demo_queue_subscriber',
NULL,
NULL )
);
DBMS_AQ.REGISTER (
SYS.AQ$_REG_INFO_LIST(
SYS.AQ$_REG_INFO(
'DEMO_QUEUE:DEMO_QUEUE_SUBSCRIBER',
DBMS_AQ.NAMESPACE_AQ,
'plsql://DEMO_QUEUE_CALLBACK_PROCEDURE',
HEXTORAW('FF')
)
),
1
);
END;
/
And finally test the queue
DECLARE
r_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
r_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
v_message_handle RAW(16);
o_payload demo_queue_payload_type;
BEGIN
o_payload := demo_queue_payload_type(
TO_CHAR(SYSTIMESTAMP, 'DD-MON-YYYY HH24:MI:SS.FF3' )
);
DBMS_AQ.ENQUEUE(
queue_name => 'demo_queue',
enqueue_options => r_enqueue_options,
message_properties => r_message_properties,
payload => o_payload,
msgid => v_message_handle
);
COMMIT;
END;
/

Resources