Why the Time is missing? - sql

I have code below:
declare
v_rst varchar2(200);
cursor c_cur is
select sysdate from dual;
begin
open c_cur;
fetch c_cur
into v_rst;
close c_cur;
dbms_output.put_line(v_rst);
end;
the output result for it is 23-DEC-14
When I run below query, the result is 12/23/2014 11:21:06 AM:
select sysdate from dual;
I do not know why the TIME part is gone when I run the first code.

The time is not "gone". That format is just the default. You need to set the NLS_DATE_FORMAT for the default value:
ALTER SESSION SET NLS_DATE_FORMAT='YYYY/MM/DD HH:MI:SS';
or whatever format your want.
Or, change your query to format the date field using the to_char function
select to_char(sysdate, 'MM/DD/YYYY HH:MM:SS') from dual;
See the format model here.

Related

Working with dates in PL SQL

I have a simple PL SQL code. However it is failing at date level. The date column is CODT. I declared CODT as date. And in database level, it is date with format YYYY-MM-DD.
I also tried alter session set nls_date_format = 'YYYY-MM-DD'; But it is throwing error.
The error message is ORA-01830: date format picture ends before converting entire input string
00000 - "date format picture ends before converting entire input string"
Could you let me know where I need to change it to date format/ where I am making a mistake ?
DECLARE
RID VARCHAR2(100);
KY VARCHAR2(200);
CODT DATE;
CURSOR FETCH_DTLS IS
SELECT ROW_ID,
KEY,
CUT_OFF_DT,
FROM TMP1
WHERE RN = 1;
BEGIN
OPEN FETCH_DTLS;
LOOP
FETCH FETCH_DTLS
INTO RID,
KY,
CODT;
EXIT WHEN FETCH_DTLS%NOTFOUND;
INSERT INTO tmp2
VALUES
(RID,
KY,
CODT
);
END LOOP;
COMMIT;
CLOSE FETCH_DTLS;
COMMIT;
END;
if you have date column which defined varchar2 in db you should use it like this:to_date(your_column/*CUT_OFF_DT*/, 'yyyy-mm-dd')
when you use VARCHAR2 field and insert it in a table with DATE data-type, then you tell oracle to: Cast VARCHAR2 to DATE
So your mistake is casting without providing any format, here are some date format examples used in oracle:
'YYYY-MM-DD'
'YYYY-MM-DD HH24:MI:SS'
there is also another function in oracle called TO_DATE which will do the job, it simply casts the string(char or varchar) to date with provided date-format and also provided calendar! Here is some examples:
TO_DATE('2016-12-15','YYYY-MM-DD')--uses default calendar of session
TO_DATE('2016-12-15','YYYY-MM-DD', 'nls_calendar=gregorian')
TO_DATE('1395-09-25','YYYY-MM-DD', 'nls_calendar=persian')--Solar base date used in IRAN
and reverse function is TO_CHAR
TO_CHAR(SYSDATE,'YYYY-MM-DD')--SYSDATE is in Date type so this works
there is another data-type related to dates, which is called TIMESTAMP
TO_CHAR(SYSTIMESTAMP,'YYYY-MM-DD HH24:MI:SSxFF')--SYSTIMESTAMP is in TIMESTAMP type so this works
finally we can use INTERVAL type to calculate interval between 2 dates(Specially timestamps) and there is a useful function called numtodsinterval which converts numbers to intervals, you can use it like this:
SYSDATE+NUMTODSINTERVAL(1,'Minute')
and this is an example:
SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS'),
TO_CHAR(SYSDATE+NUMTODSINTERVAL(1,'Minute'),'YYYY-MM-DD HH24:MI:SS')
FROM DUAL
which outputs:
1 2016-12-15 15:05:10 2016-12-15 15:06:10
I hope it will be useful in your future usages of DATE, goodluck

PL/SQL - Cannot convert string to desired date format using to_date()

I have a string like "01-JAN-15 13:05:01". I used to_date() function to convert the string to date format and store it to a date field. However, the time value stored is not correct, which is "01/01/2015 04:12:43 PM". I used to_char() function to show the value of the converted date, but the returned value does not have any problem.
Input(String): 01-JAN-15 13:05:01
Desired Output(Date): 01/01/15 01:05:01 PM
Actual Output(Date): 01/01/15 04:12:43 PM
Code for conversion:
select to_date('01-JAN-15 13:05:01', 'dd-mon-yy hh24:mi:ss') into result_date from dual;
to_char()
to_char(result_date, 'dd/mm/yyyy hh:mi:ss');
UPDATE:
whenever sqlerror exit 99 ROLLBACK;
set echo on;
set verify on;
set serverout on;
declare
result_date date;
begin
select to_date('01-JAN-15 13:05:01', 'dd-mon-yy hh24:mi:ss') into result_date from dual;
insert into temp_table values (result_date);
commit;
end;
Above code should not give a problem. I ran below code snippet and gave me the expected result. Double check once if you are using above code only.
DECLARE
result_date DATE;
BEGIN
select to_date('01-JAN-15 13:05:01', 'dd-mon-yy hh24:mi:ss') INTO result_date from dual;
DBMS_OUTPUT.PUT_LINE(to_char(result_date, 'dd/mm/yyyy hh:mi:ss AM'));
END;

Appending the HH:MI:SS to to_date function

I have a table in DB from which I take values from a date field.I store this date value in a cursor. currently the date value is of the format DD:MON:YY. Now I convert this date into character using to_char function so as to append time 00:00:00 to it. now I tried converting back to the date format , but the timestamp is not appended and the date format is not as I have given( format is same as that of the date field in DB).but the to_char function returns the correct format as I have given.
Some of the code snippets are as follows:
Initialized a cursor as
cursor cur is
select to_char(STV_FROM_DATE,'DD:MON:YYYY:')STV_FROM_DATE :---from a table in DB
cur1 cur%rowtype;
begin
open cur;
loop
fetch cur into cur1;
dbms_output.put_line(cur_1.STV_FROM_DATE);
This is giving the value correctly as:
01:JAN:2000:
01:JAN:2000:
01:JAN:2000:
01:JAN:2000:
Now I appended the timestamp 00:00:00 to this and did the to_date operation as follows:
STV_FROM_DATE_BC := cur_1.STV_FROM_DATE;
STV_FROM_DATEBCKUP:=to_date(STV_FROM_DATE_BC,'DD:MM:YY:HH24:MI:SS');
dbms_output.put_line(STV_FROM_DATEBCKUP);
The result obtained is:
01-JAN-00
01-JAN-00
01-JAN-00
Could anyone help me to solve this issue and convert the timestamp appended character to date?
DBMS_OUTPUT is to DISPLAY. so, to display a DATE, you need TO_CHAR.
STV_FROM_DATEBCKUP:=to_date(STV_FROM_DATE_BC,'DD:MM:YY:HH24:MI:SS');
dbms_output.put_line(STV_FROM_DATEBCKUP);
Never use YY, always mention 4 digits YYYY for the complete year. You don't want to introduce the Y2K bug again. Above, you are trying to display the date value, but you did not mention the format model that you want to display. So simply use TO_CHAR along with proper format model.
Reason Without providing a proper format model, your client would just display according to your locale-specific NLS settings. For example, if I just display the sysdate, I would see the format that is mentioned in my NLS_DATE_FORMAT in v$parameters.
SQL> select parameter, value from v$nls_parameters where parameter='NLS_DATE_FORMAT';
PARAMETER VALUE
-------------------- --------------------
NLS_DATE_FORMAT DD-MON-RR
SQL> select sysdate from dual;
SYSDATE
---------
27-JAN-15
SQL>
So, I got 27-JAN-15 as SYSDATE, since my NLS_DATE_FORMAT is DD-MON-RR. You could set it at system level or at session level.
SQL> alter session set NLS_DATE_FORMAT='DD:MM:YYYY:HH24:MI:SS';
Session altered.
SQL> select sysdate from dual;
SYSDATE
-------------------
27:01:2015:11:54:07
SQL>
So, you could either set your NLS_DATE_FORMAT to set the format model that suits you. Let's see a test case -
SQL> set serveroutput on
SQL> DECLARE
2 STV_FROM_DATE_BC VARCHAR2(20);
3 STV_FROM_DATEBCKUP DATE;
4 BEGIN
5 STV_FROM_DATEBCKUP:= NULL;
6 STV_FROM_DATE_BC :='01:JAN:2000:';
7 STV_FROM_DATE_BC :=STV_FROM_DATE_BC||'00:00:00';
8 dbms_output.put_line('Input date literal = '||STV_FROM_DATE_BC);
9 STV_FROM_DATEBCKUP:=to_date(STV_FROM_DATE_BC,'DD:MON:YYYY:HH24:MI:SS');
10 dbms_output.put_line('Date without format model = '||STV_FROM_DATEBCKUP);
11 dbms_output.put_line('Date with proper format model = '||TO_CHAR(STV_FROM_DATEBCKUP,'DD:MM:YYYY:HH24:MI:SS'));
12 END;
13 /
Input date literal = 01:JAN:2000:00:00:00
Date without format model = 01-JAN-00
Date with proper format model = 01:01:2000:00:00:00
PL/SQL procedure successfully completed.
SQL>

ORA-06502: PL/SQL: numeric or value error: character string buffer too small in Oracle sql query

I want to calculate the time difference between two dates in Oracle sql query. I have written the following query:
DECLARE
v_time varchar2(40);
diff_hours varchar2(40);
BEGIN
select substr(((select date_time from observation_measurement where observation_measurement_id=2861971)), 1,17)
into v_time
from dual;
dbms_output.put_line(v_time);
select 24 * (to_date('06-25-2014 09:46:36', 'MM-DD-YYYY hh24:mi:ss')
- to_date(v_time, 'YY-MM-DD hh24:mi:ss')) into diff_hours
from dual;
END;
The first select statement returns correct result. When I am trying to calculate the time difference from current date to the previous calculated date then it is showing error. How can I get the correct result?
Thanks!!!!
Increasing the size of diff_hours variable working. Thanks Krishna. :-)
Make diff_hours a NUMBERvariable instead of a VARCHAR2 variable!
Of course you can make diff_hours long enough to hold all the insignificant decimals your query produces, but declaring it VARCHAR2 is pointless anyway!
Hi I have made some corrections in your query . Tell me if that works
DECLARE
v_time varchar2(40);
-- Increase the size
diff_hours varchar2(200);
BEGIN
select substr(((select date_time from observation_measurement where observation_measurement_id=2861971)), 1,17)
into v_time
from dual;
dbms_output.put_line(v_time);
-- using the same format mask for both the dates
select 24 * (to_date('06-25-2014 09:46:36', 'MM-DD-YYYY hh24:mi:ss')
- to_date(v_time, 'MM-DD-YYYY hh24:mi:ss')) into diff_hours
from dual;
END;
You can increase diff_hours and it might work in some cases, but the problem is it might not work in other cases.
To be sure, you need explisitly convert number to string (example with 2 digits after dot):
select trunc(24*...., 2) into diff_hours

Identify date format in PLSQL

I'm trying to write a plsql stored procedure which identifies any date format and converts it into single datetime format 'mm/dd/yyyy hh:mi:ss'. How do I do it. I tried using case statment but there are so many date combinations that its not possible to write case statment for all of them.
For ex: 27-Oct-1967, October 27 1967 11:15:45, 1967-OCT-27, etc.
How do I convert all these to single format.
Thank you.
Simply to_char() will do,
select to_char(yourDateField,'mm/dd/yyyy hh:mi:ss') from dual;
Maybe this can help you:
CREATE TABLE temp_date
AS
SELECT '1967-OCT-27' some_date
FROM dual
UNION
SELECT '27-Oct-1967' FROM dual
UNION
SELECT 'October 27 1967 11:15:45' FROM dual
/
Declare
CURSOR i_cur IS
Select some_date
From temp_date;
--
v_date1 Varchar2(30);
v_date2 Varchar2(30);
v_date3 Varchar2(30);
v_char Varchar2(30);
v_cnt Number:= 0;
Begin
For i_rec IN i_cur
Loop
v_cnt:= v_cnt + 1;
Begin
v_date1:= to_char(to_date(i_rec.some_date), 'MM/DD/YYYY hh24:mi:ss');
dbms_output.put_line(v_cnt||'.'||chr(9)||v_date1);
EXCEPTION
When Others Then
Begin
v_date2:= to_char(to_date(i_rec.some_date, 'MM/DD/YYYY hh24:mi:ss'), 'MM/DD/YYYY hh24:mi:ss');
dbms_output.put_line(v_cnt||'.'||chr(9)||v_date2);
EXCEPTION
When Others Then
Begin
v_date3:= to_char(to_date(i_rec.some_date, 'YYYY-MON-DD'), 'MM/DD/YYYY hh24:mi:ss');
dbms_output.put_line(v_cnt||'.'||chr(9)||v_date3);
EXCEPTION
When Others Then
-- Insert into Exceptions table (or any temp table) then convert... --
v_char:= i_rec.some_date;
dbms_output.put_line(v_cnt||'. '||chr(9)||i_rec.some_date||' : '||v_char);
End;
End;
End;
End Loop;
End;
/
1. 10/27/1967 00:00:00
2. 10/27/1967 00:00:00
3. 10/27/1967 11:15:45
The most desired way of would be to formatting date into the format that you need. Then do whatever calculations that you require on it.
Otherwise you will have to write ridiculously large number of select cases to define the format. Not to say that it doesn't make sense since dates can come in many different formats....as Mat mentioned. And further Date is a component that can be influenced by your system.
You may try the following:
Convert date input into the desired format using To_Date() given you may not even know if this input comes as a String or a real date. So you may need some validations to make sure it's a proper date.
SELECT TO_DATE(mydate,'mm/dd/yyyy hh:mi:ss') FROM Dual;