Apex Audit log - Insert Query - sql

I am creating a custom audit log as a process in the Apex application I have developed.
Below is the code I have used to log the actions by the user when they use the application. The LOGON_DT and LOGOFF_DT will only need to be in a date format. However, QUERY_SEARCH_TIME will need the time.
INSERT INTO AUDIT_LOG
(USERNAME, ORDER_NO, ORDER_NAME, CUSTOMER_NAME, LOGON_DT, LOGOFF_DT, QUERY_SEARCH_TIME)
VALUES
(:APP_USER, :P10_ORDER_NO, :P10_ORDER_NAME, :P10_CUSTOMER_NAME, SYSDATE, SYSDATE,
SYSDATE(HH24:MI:SS));
The above code works perfectly when HH24:MI:SS is taken off, and I'm not sure where I'm going wrong with this?
Any guidance will be great. Thank you!

Oracle has it's own internal representation for a DATE datatype. You can't dictate its format in the way you are attempting.
It is common to apply a date format on retrieval, which you can do by applying the appropriate format mask as you convert to a string.
TO_CHAR(QUERY_SEARCH_TIME, 'HH24:MI:SS')

A DATE column already captures a time component. It may not be necessary to cut it off. And if you do, you do not want a DATE column as such a column will always capture a whole date, and what would be the point if you want only time.
To visualize the time component of a date you have to apply a format mask to it:
TO_CHAR(SYSDATE, 'HH24:MI:SS'). If you want to capture just that, the time, then change the datatype of the column to a VARCHAR2 type of sufficient length for the format mask you apply.
Read up on datetime datatypes here: Oracle documentation on datetime types
Read up on datetime format models here: Oracle documentation on format models

If you need time part of date only for output, you can use answer of Tom, but if you really need to store time part only, you can calculate it as
sysdate - trunc(sysdate)

Related

SQL: date type column with only mm-dd

I want to create a column of data type having only 'mm-dd' values.
Is it possible and if yes how should I do it?
Note: Instead of "2022-06-07", I want "07-06"
There is no date type that can store that format - in fact none of the date types store a date and/or time in any of the formats you typically recognize.
For your specific requirement, that looks like a char(5) for the data type, but how you constrain it so that it will only accept valid date values, I have no idea. You'd think this would work:
CHECK (TRY_CONVERT(date, string_column + '-2022', 105) IS NOT NULL)
But what about leap years? February 29th is sometimes valid, but you've thrown away the only information that can make you sure. What a bunch of mess to store your favorite string and trust that people aren't putting garbage in there.
Honestly I would store the date as a date, then you can just have a computed column (or a column in a view, or just do this at query time:
d_slash_m_column AS CONVERT(char(5), date_column, 105)
Why not just in your query (or only in a view) say:
[output] = CONVERT(char(5), data_in_the_right_type, 105)
?
I'd personally stay away from FORMAT(), for reasons I've described here:
FORMAT() is nice and all, but…
FORMAT is a convenient but expensive function - Part 1
FORMAT is a convenient but expensive function - Part 2
You can use the SQL Server FORMAT function:
FORMAT(col1, 'dd/MM')
Check the demo here.
In such cases using char or varchar is not the best option as in those cases the underlying DB constraints that validate the integrity of the data do not kick in.
Best option is to use an arbitrary year and then put in a proper date, so for example for storing 01-Jan, the db column should store proper date with year as any arbitrary value, e.g. 2000. So your db should say 2000-01-01.
With such a solution you are still able to rely on the DB to raise an error if you tried month 13. Similarly sorting will work naturally as well.

Insert date and time in formats mm/dd/yyyy and time in the format hh24:mm:ss in plsql

Lets say I have a table Student with columns Name,DOJ,TOJ.
Inorder to enter date in mm/dd/yyyy format and timestamp in the format hh24:mm:ss I used ALTER SESSION SET NLS_DATE_FORMAT='MM/DD/YYYY' and ALTER NLS_TIMESTAMP_FORMAT='HH24:MI:SS' but i want to know an alternative solution to enter in this format without involving session. Please guide me through this.
CLICK HERE TO VIEW COLUMNS AND THEIR DATA TYPES
We store dates/times either in a DATE column (which is Oracle's inappropriate name for a datetime) or a TIMESTAMP column (which has more precision and can handle timezones, too). These types have no format. This is important, because thus comparing and sorting them in the database works fine, because the DBMS knows how to handle datetimes, while the users see the date in their format. I, for instance, have set my Windows to German, so I will see the datetimes in some German format, while you will see the same date in a format you are used to.
There are few situations where you want to store date and time separately. The reason is typically that you can set them null. A date without a time means "the whole day". A time without a date means "every day this time". But then you often want this even more advanced anyway ("every Tuesday and Wednesday", "every December 24", etc.) for which you need soemthing more sophisticated then just date and time split into two.
So, usually we just store date and time combined. For a precision down to seconds we use DATE. If we wanted them separately we'd have to think of an appropriate data type, because Oracle has no real date type and no time type either. So we'd either use DATE and ignore the date part or the time part or we use strings. The former solution is usually preferred, because you cannot mistakenly enter invalid data like February 30 or 23:66:00.
If you want to store formatted dates and times, you are talking about strings. I don't recommend this. Strings are not the appropriate data types for dates and times. And a format '01/02/2000' is ambiguous. Some people will read this as February 1, others as January 2.
If you wanted to do this, you would have to change the column types to VARCHAR2 and simply store values like '02/25/2021' and '13:28:56'.
But if you wanted to sort your data or compare dates/times then or just show them to a foreign user in a format they are used to, you would always have to convert them. E.g.:
select *
from mytable
order by to_date(doj || ' ' || toj, 'mm/dd/yyyy hh24:mi:ss');
I am afraid that to change default format you have no other option but to change NLS_DATE_FORMAT either in database level or session level.
But If your purpose is to show the date in a specific format in the front end then you can use to_char() function as below:
SELECT NAME, to_CHAR(DOJ,'dd/mm/yyyy'),to_CHAR(TOJ,'HH24:MI:SS') FROM table
To change the default date format in system level:
ALTER SYSTEM SET NLS_DATE_FORMAT='DD/MM/YYYY' scope=both;
You can also change the default date format at startup time with a login trigger to change the nls_date_format:
CREATE OR REPLACE TRIGGER CHANGE_DATE_FORMAT
AFTER LOGON ON DATABASE
call DBMS_SESSION.SET_NLS('NLS_DATE_FORMAT','YYYYMMDD');

Converting a Time to 24 hour time in DB2

I am running on DB2 and I am trying to convert a H:MI:SS AM/PM format, like this '3:33:38 PM' into 24HH:MI:SS format, like this '15:33:38'
This is frequently asked. Different methods exist, cyou an use TO_DATE aka TIMESTAMP_FORMAT combined with TIME or similar.
example, to create a time result
time(to_date('3:33:38 PM', 'HH12:MI:SS AM'))
which yields
15:33:38
It would be unusual to store a time in Db2 as a string..
select timefld
from mytable
Might indeed return, 3:33:38 PM, but if timefld is an actual time data type, then the value return you are seeing is a function of whatever tool you're using to query Db2.
Look around in your client's config for an option to change the format used for dates and times
Note that this only affects how the UI displays the data stored in the database.
It doesn't affect the internal format used to actually store the time, nor the external format used to return the data to clients.

TO_CHAR and TO_DATE use and the right context to use them

If I have a query like:
select *
from CAT_ACCT_AUDIT_TRAIL cataccount0_
where cataccount0_.CAAT_EXECUTED_DATE >=TO_DATE(’26-AUG-2016′, ‘DD-MM-YYYY’) AND
to_Date(TO_CHAR(cataccount0_.CAAT_EXECUTED_DATE , ‘dd -mon-yyyy’), ‘DD-MM-YYYY’)<=TO_DATE('31-AUG-2016', 'DD-MM-YYYY')
Here why do we require the to_char or to_date functions? What is the right context to use them?
If I do either of these:
select TO_DATE('26-AUG-2016', 'DD-MM-YYYY') from dual;
select TO_DATE('01-12-2016', 'DD-MM-YYYY') from dual;
I get the output in NLS variable format as I set in the session, irrespective of date input in format conversion; I get the same result for both. Wy is this so?
What is the correct way to solve this query? I mean when i need to fetch the values in date range.
You use to_date() to convert a string like '01-12-2016' to the date datatype. You use to_char() to convert a date to a string. In both cases you specify the format of the string - if you don't then your session NLS settings are used, which is not good practice for anything except ad hoc queries as someone else running your code later may get a different output or an error.
A general rule - which your code is following - is to compare data of one type with values/constants of the same type. As your column is a date, you're supplying the filter values as dates - by converting strings to the date datatype. If you didn't do that then implicit conversion would happen, but you should not rely on that either as it can also lead to NLS issues, and depending on the type it can prevent indexes being used. Read more about data conversion in the documentation.
Oracle tries to be flexible when interpreting the string when you do to_date(). When you do TO_DATE('26-AUG-2016', 'DD-MM-YYYY') you are supplying the month as a string (in a specific language, which is another topic), but telling the function to expect a number. Oracle 'helpfully' interprets that anyway, so it usually works. But whatever format you use for to_date(), you aren't specifying the display format, so your client is deciding how to display the converted date as a string for you - usually using your NLS settings, again.
Doing this:
to_Date(TO_CHAR(cataccount0_.CAAT_EXECUTED_DATE , ‘dd -mon-yyyy’), ‘DD-MM-YYYY’)
is usually pointless, but even so should be using consistent format models. One reason this is sometimes done is if the source date (caat_executed_date here) has its time set to something other than midnight, and you want to discard the time. But there are better ways to do that - specifically the trunc() function, which by default sets the time to midnight.
When you have constant values, like TO_DATE('31-AUG-2016', 'DD-MM-YYYY'), you can also use ANSI date literals, in the form of DATE '2016-08-31'.
It is unclear what you want to do, but you don't actually need those functions on constants. Just use the date keyword for date literals. For instance:
where cataccount0_.CAAT_EXECUTED_DATE >= date '2016-08-26'
If you want to remove the time component from a date, then use trunc():
where trunc(cataccount0_.CAAT_EXECUTED_DATE, 'dd') -- the `'dd'` is optional for this purpose
This can be used in any context where a date constant is accepted.

I have date stored in the format mm/dd/yyyy but i need to view as August 22nd, 2014

I have date stored in format mm/dd/yyyy in the database, but I need to view as Month Date(with superscript), Year. I am using Oracle 11g
The database just stores dates, in an internal format. It doesn't store them in mm/dd/yyyy, or anything human-readable.
You are sending them to the database in mm/dd/yyyy format, by the sound of things; but how you display them is down to your client application. You should be retrieving them from the database, and then formatting them at the client end.
In other words, don't do this in SQL at all.
The returned date can be manipulated as part of the query.
Example:
SELECT TO_CHAR(ts_col, 'DD-MON-YYYY') FROM date_tab;
The format string you would probably want is: 'MONTH DDTH, YYYY'
I would advise to just take whatever format the database gives you and handle it client-side though.
More information about TO_CHAR can be found in the oracle docs. A full list of format models can be found here. There is also Datetime Format Element Suffixes allowing for 2nd, 3rd, etc.
heres a work around if you want ... i dont know if this exactly what you want
SELECT REPLACE(TO_CHAR(SYSDATE, 'MonthDD,YYYY'),',','nd,') FROM DUAL;