I'm currently working on an assignment where I have to port some Oracle scripts to MS SQL. I ran into a problem at the scheduled jobs. The Oracle script looks like this:
dbms_job.submit(job =>v_job,
what =>'begin pkg_report.REFRESH_MVIEWS; end;',
next_date =>Trunc(sysdate, 'HH24')+70/1440, interval =>'Trunc(sysdate, ''HH24'')+70/1440');
dbms_job.submit(job =>v_job, what =>'begin pkg_housekeeping.cleanup_daily; end;', next_date =>trunc(sysdate)+1, interval =>'trunc(sysdate)+1+1/24');
The problem is, I don't understand what this truncing is supposed to do. I tried to replicate it in SQL Developer, played around with it a bit, most of the format strings have very obvoius outcome (YEAR, MONTH, ...), but I don't know what HH24 is supposed to do. And what's with the +70/1440, +1, +1+1/24 suffixes at the end?
I'd appreciate a little help. Thanks in advance!
TRUNC removes the time element of the current date, so the code sets the date to midnight of today (sysdate) and then adds 70/1440 of a day to it.
70/1440 of a day is 01:10 (ten past one in the morning)
+1+1/24 adds one day and 1/24th of a day, so 1am the following day
Related
What's the best way to get a timestamp that consists of the actual date but a fixed time part in oracle.
e.g.Today and always 09:00:00
2020-10-20 09:00:00
in MSSQL I would use FORMAT(GETDATE(),'yyyy-MM-dd 09:00:00')
Assuming you want a date rather than a varchar2, I'd use
trunc(sysdate) + interval '9' hour
trunc(sysdate) returns today at midnight and then interval '9' hour adds 9 hours to give you 9am. You can also add fractions of a day to a date so you could say
trunc(sysdate) + 9/24
I tend to find the interval notation more self-explanatory particularly if you're coming from a non-Oracle background.
You can use something like this:
SQL> alter session set NLS_DATE_FORMAT='YYYY-MM-DD';
Session altered.
SQL> set head off
SQL> select sysdate||' 09:00:00' from dual;
2020-10-19 09:00:00
Hope this is what you were looking for :)
I have a datetime column in Oracle (MM/DD/YYYY HH:MM:SS AM/PM) but when I do this:
SELECT MAX(D_DTM)-1 FROM tbl1
...it goes back a day. How do I remove one hour from the column rather than one day?
I've also noticed that the datetime records for 12AM look like MM/DD/YYYY and not MM/DD/YYYY 00:00:00; I'm not sure if that matters.
Randy's answer is good, but you can also use intervals:
SELECT MAX(D_DTM)- interval '1' hour FROM tbl1
yes - dates go by integer days.
if you want hours you need to do some math - like -(1/24)
Or use the INTERVAL function. It has the same result but I think it reads more clearly - that's of course just an opinion :)
SELECT MAX(D_DTM) - INTERVAL '1' HOUR FROM tbl1
The nice thing about the INTERVAL function is that you can make the interval be years, months, days, hours, minutes or seconds when dealing with a DATE value, though the month interval can be tricky when dealing with end-of-month dates.
And yes, the quote around the 1 in the example is required.
You can also use the Oracle-specific NumToDSInterval function, which is less standard but more flexible because it accepts variables instead of constants:
SELECT MAX(D_DTM) - NUMTODSINTERVAL(1, 'HOUR') FROM tbl1
select sysdate - numtodsinterval(1,'hour') from dual
Its simple.
sysdate - 5/(24*60*60) --> Subtracts 5 seconds from systime
sysdate - 5/(24*60) --> Subtracts 5 minutes from systime
sysdate - 5/(24) --> Subtracts 5 hours from systime
Hence
select (sysdate - (1/24)) from dual
Another method of using intervals is
NUMTODSINTERVAL( number, expression )
examples
NUMTODSINTERVAL(150, 'DAY')
NUMTODSINTERVAL(1500, 'HOUR')
NUMTODSINTERVAL(15000, 'MINUTE')
NUMTODSINTERVAL(150000, 'SECOND')
I bring this up because it is useful for situations where using INTERVAL wont work.
I have a query to run on oracle that gives output as sid,serial#,transaction start time,sql_id,transaction id.
What I need to do is, whenever a transaction's start time is more than 1 hour behind the system time, I need to run another query with that sql_id and send it as an email.
How do I compare this time output from ORACLE sql and compare it with the system time?
I need to automate this process and add it to the cron on UNIX.
Please help!
The function SYSDATE returns the current system date. When you subtract two dates, you get a difference measured in days. Multiply by 24 and you get a difference in terms of hours.
SELECT *
FROM v$transaction
WHERE (sysdate - start_date)*24 > 1
will give you the transactions that started more than 1 hour ago. You can also use interval arithmetic if you find that clearer.
SELECT *
FROM v$transaction
WHERE sysdate - interval '1' hour > start_date
I have stored procedure.In procedure there are three cursors.I have to run procedure daily in production.I want only two cursors should run daily and the remaining cursor should run only on 1st of every month.So what are the changes should be made to third cursor.Please provide the solution.
The cursor itself doesn't actually run. It is your code that uses the cursor. So you can check in code if it is the first day of the month:
-- Check if today is first day of the month
if trunc(sysdate, 'MM') = trunc(sysdate) then
-- Use cursor here
end if;
Possibly a better solution is to create two separate procedures and create jobs for each of them. You can specify intervals for the job so one runs daily while the other runs monthly.
Look into dbms_scheduler
In Oracle, this returns 03/01/2010. That does not make sense to me. Anybody know why?
SELECT TO_DATE( '2010' ,'yyyy' ) AS STRANGE_YEAR_RESULT
FROM DUAL
I've tried on Oracle 10g and 11g.
Oracle needs a complete DateTime in its Date type value field, thus making it take the first day of the current month, I would guess, since you required no other information than the year. Remember that you always need to cast through TO_DATE() and TO_CHAR() dates in Oracle. Assuming so, Oracle "knows" that you will get the information required.
I don't think there is any sensible reason, it's just "what it does". It also got discussed on the OTN forums about a year ago.
Don't know, but my guess is that months are zero based, so Jan = 0, Mar = 2, etc.
"10" might be a Y2K problem in the making, but it's being interpreted as 2010.
And if no day of month is given, perhaps it's assuming the first day of the month.
Why test this? You'd never want to code this way.