SQL server date conversion - 'Conversion failed' - sql-server

I have problem with converting date from varchar to date format:
Msg 241, Level 16, State 1, Line 15
Conversion failed when converting date and/or time from character string.
I'm trying to convert/cast it like SELECT convert(DATE, '25.02.2019');. Can't change string order bacause the data are from existing table.
I know that the solution is easy but I'm still missing something and didn't get it yet :(

If you are unable to fix the underlying problem (that the table uses the wrong data type), you need to apply the correct DATETIME Style, which for dd.MM.yyyy is 104:
SELECT CONVERT(DATE, '25.02.2019', 104);
If at all possible though you should correct the original table. You should never store dates using VARCHAR, there is not one good reason to do so, and lots of good reasons not to. It will save you a lot of headaches if you change your datatype to DATE and then you won't have to worry about conversion errors. The longer you leave it the worse it will get. If you can't change the table, have a word with your DBA, and tell them to change the table. If you don't have a DBA, find someone who can.
Some good articles on this below:
Bad habits to kick : choosing the wrong data type
Bad habits to kick : mis-handling date / range queries
ADDENDUM
If you are unable to change the actual column because it is used by other processes, you can still sanitise the column by using a check contraint, and optionally include a computed column so you always have access to a real date, and not a varchar:
e.g.
IF OBJECT_ID(N'tempdb..#DateTest', 'U') IS NOT NULL
DROP TABLE #DateTest;
CREATE TABLE #DateTest
(
StringDate CHAR(10) NOT NULL,
RealDate AS CONVERT(DATE, StringDate, 104),
CONSTRAINT CHK_DateTest__RealDate CHECK (TRY_CONVERT(DATE, StringDate, 104) IS NOT NULL)
);
This will allow you to continue to add/edit varchar dates:
-- insert valid date and check output
INSERT #DateTest (StringDate) VALUES ('25.02.2019');
SELECT RealDate
FROM #DateTest;
The check constraint will prevent you from adding any dates that are not dates:
--Try to insert invalid date
INSERT #DateTest (StringDate) VALUES ('29.02.2019');
This will throw an error:
The INSERT statement conflicted with the CHECK constraint "CHK_DateTest__RealDate". The conflict occurred in database "tempdb", table "dbo.#DateTest___________________________________________________________________________________________________________000000000704", column 'StringDate'.
You can even index the column:
CREATE NONCLUSTERED INDEX IX_DateTEst ON #DateTest (RealDate);
With the index on you can take advantage of the benefits storing dates properly gives.

Your string is in the wrong format.
Should be:
SELECT convert(DATE, '2019-05-02')
Edit: If you can't get the date in that format, put 104 as a third argument.
Here's a list of the optional format arguments. https://www.w3schools.com/SQL/func_sqlserver_convert.asp

Related

Date convertion Issue in Ms sql

My table name as tbl_event
Event_ExpiryDate, Event_Date fields data type is varchar, I have using the following query for getting data from the table:
select * from tbl_event
WHERE
LEFT (CONVERT(VARCHAR,Event_ExpiryDate,103),12)>= LEFT(CONVERT(varchar,GetDate(),103),12) and
LEFT (CONVERT(VARCHAR,Event_Date,103),12)<= LEFT(CONVERT(varchar,GetDate(),103),12)
but I am getting a result like this
1 data to be missing. Why? this issue only on some month's date only. Months are 2,4,8,12
The real problem here is your data, and that you're using the wrong data type. Fix the data type, fix the problem.
You can fix that by firstly changing your varchar representation of a date to an unambiguous Date format, yyyyMMdd (This assumes your dates are in the format dd/MM/yyyy):
UPDATE dbo.tbl_event
SET Event_Date = CONVERT(varchar(8),CONVERT(date,Event_Date,103),112),
Created_Date = CONVERT(varchar(8),CONVERT(date,Created_Date,103),112),
Event_ExpiryDate = CONVERT(varchar(8),CONVERT(date,Event_ExpiryDate,103),112);
Then you can ALTER the table to fix your data types:
ALTER TABLE dbo.tbl_event ALTER COLUMN Event_Date date NULL; --Use NOT NULL if not NULLable
ALTER TABLE dbo.tbl_event ALTER COLUMN Created_Date date NULL; --Use NOT NULL if not NULLable
ALTER TABLE dbo.tbl_event ALTER COLUMN Event_ExpiryDate date NULL; --Use NOT NULL if not NULLable
Note: If any of your dates have bad values, for example '31/04/2019', the above will fail. You can get around this by changing the CONVERT functions to TRY_CONVERT, however any values that fail to convert will have the value NULL. If your columns have the NOT NULL property you will need to ensure you handle that too. If you do have bad values in your table, I strongly suggest taking a backup, or copy of the database/table first, so that you have a historical copy. (Of course, does a date like '31/04/2019' or '12/13/2018' have any meaning anyway?)
You can use only convert() :
where convert(date, Event_ExpiryDate, 103) >= convert(date, getdate()) and
convert(date, Event_Date, 103) <= convert(date, getdate());
However, storing varchar date is really bad idea. It will lead you lots of in trouble.

Have a field that is a time, need to find those outside of HH:MM AM/HH:MM PM format

I am looking a table that has from and to times for the hours that a particular business is open in a SQL Server table and the data is entered char, not a time format. It needs to be in the 12 hour format of MM:HH AM or PM. There many not entered with the correct time format. How can I create a Case statement or something to catch those in wrong format.
I've not tried anything, I don't know where to begin.
No code to show
I would expect 8am or 23:59 for example to show up in the case statement column with whatever fail message is entered.
My comments from under the question stand on this, but to reiterate them: Don't use a char to store date and time values. Using the wrong data type can (and will) cause you problems. You should be using the appropriate datatype (in this case time) and have your presentation layer handle the formatting.
Firstly, however, to explicitly answer your question, you state you want the format HH:MM AM/PM, which means you could use a LIKE expression:
SELECT TimeColumn
FROM YourTable
WHERE TimeColumn NOT LIKE '[0-1][0-9]:[0-5][0-9] [AP]M';
This does, still, however, have flaws as it'll allow a value like '19:00 AM'. Thus, you could be more specific and do this:
SELECT TimeColumn
FROM YourTable
WHERE TimeColumn NOT LIKE '0[0-9]:[0-5][0-9] [AP]M'
AND TimeColumn NOT LIKE '1[0-2]:[0-5][0-9] [AP]M';
Personally, I would actually add the above as a CHECK CONSTRAINT to stop the insertion of bad data, but you'll need to fix the data first:
ALTER TABLE YourTable
ADD CONSTRAINT ck_ValidTime
CHECK (TimeColumn NOT LIKE '0[0-9]:[0-5][0-9] [AP]M' AND TimeColumn NOT LIKE '1[0-2]:[0-5][0-9] [AP]M');
But, like I said, you could really be fixing your data type. I would firstly add a new column to store the old data:
ALTER TABLE YourTable ADD TimeStringColumn char(8);
GO
UPDATE YourTable SET TimeStringColumn = TimeColumn;
Then correct the values of your column and then alter the datatype:
UPDATE YourTable SET TimeColumn = TRY_CONVERT(char(8),TRY_CONVERT(time,'12:17 AM'),114);
ALTER TABLE YourTable ALTER COLUMN TimeColumn time(0);
If you want one good reason why you need to change your data type, according to your data '12:58 AM' is after '10:01 PM'.

Oracle DML Error Logging field type

I wanna ask about the DML Error Logging in Oracle
I have an original table with this structure
table_test(
ID Int PK,
test_time date
)
I also create an error logging table for this
ERR$_table_test
As I know, the field 'ID' and 'test_time' in ERR$_table_test is VARCHAR(4000)
Let me take an example
1. Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss'))
==> successful, 1 row inserted
2. Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss'))
==> 0 row inserted in table_test, 1 row in ERR$_table_test with this error: ORA-00001: unique constraint violated
3. select * from ERR$_table_test
1 record found: but the field test_time is '18/08/2015' with no time <== I want full time stamp for this field
After that, I try to alter table ERR$_table_test
alter table ERR$_table_test modify test_time date
I redo exactly above example
This time I got full time stamp for test_time in ERR$_table_test
But, then I try
Insert into table_test values (2,to_date('abc xyz' , 'dd/mm/yyyy hh24:mi:ss'))
==> An SQL error occurs when insert wrong type in ERR$_table_test
This is the thing I concerned about
Could I get full time stamp in ERR$_table_test without changing it's column type ?
If I have to change the column type into DATE, could I still receive the error log for the second case, when the format of time is wrong ?
Thank you for any support,
If it can evaluate the date then it converts it back to a string to put into the varchar2(4000) column using your session settings. As it's a date field you can control that by setting the NLS_DATE_FORMAT prior to executing the insert:
alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS';
Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss')) log errors into err$_table_test;
Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss')) log errors into err$_table_test;
Insert into table_test values (2,to_date('abc xyz' , 'dd/mm/yyyy hh24:mi:ss')) log errors into err$_table_test;
column id format a10
column test_time format a20
select ora_err_number$, id, test_time from ERR$_table_test;
ORA_ERR_NUMBER$ ID TEST_TIME
--------------------------------------- ---------- --------------------
1 1 2015-08-18 15:00:00
1858 2 abc xyz
Which isn't ideal, particularly if you might be inserting from multiple clients, whose settings you can't control.
But as the documentation notes, if you use a date datatype in your error logging table rather than the recommended (and default, if created through DBMS_ERRLOG) varchar2(4000), a failure to convert - as with your abc xyz value - will cause the whole statement to fail:
Because type conversion errors are one type of error that might occur, the data types of the optional columns in the error logging table must be types that can capture any value without data loss or conversion errors. (If the optional log columns were of the same types as the DML table columns, capturing the problematic data into the log could suffer the same data conversion problem that caused the error.) The database makes a best effort to log a meaningful value for data that causes conversion errors. If a value cannot be derived, NULL is logged for the column. An error on insertion into the error logging table causes the statement to terminate.
So to answer your second question, no; if you change the error log data type to DATE then you won't get errors logged for invalid date/time formats, the statement will just terminate.

How to prevent insertion of invalid dates into a SQLite table?

SQLite tables can't have a column of type date or timestamp. Dates are stored as either text or a number.
That being the case:
How can I prevent an invalid date like February 31st from being inserted into a table?
I'm know you can validate the date in the application before inserting, but that's not what I'm looking for, since that will not prevent an invalid date from being entered using the SQLite prompt or using some SQLite GUI tool.
The built-in date functions return NULL when they cannot interpret their date parameter, so you could add a check that this does not happen:
CREATE TABLE MyLittleTable (
MyDate CHECK (date(MyDate) IS NOT NULL)
);
However, these functions do not do much checking:
> SELECT date('2014-02-31');
2014-02-31
To normalize the date, you have to do some computation on it:
> SELECT date('2014-02-31', '+0 days');
2014-03-03
So you can check that this normalization does not change the value:
CREATE TABLE MyLittleTable (
MyDate CHECK (date(MyDate,'+0 days') IS MyDate)
);
(IS is needed to handle NULLs correctly.)

how to know the format of a date

hi i am trying to update my tables consisting of dates i am encountering errors due to white spaces the date fields was given a varchar type by the pass programmer i want to convert my dates to this format mm/dd/yyyy but it seems the date fields are littered with this type of date APRIL 8, 2014 the question is how would i know that the date being updated are in this format sample APRIL 8, 2014? before updating it to proper format e.g mm/dd/yyyy
i have tried this SELECT convert(datetime, date_field, 101) but still it gives error
any suggestions?
The date and time datatypes in SQL Server do not have any implicit format. They are stored in an internal representation. The formatting is only applied when they are presented to a user on-screen or in a report etc. To store dates in a varchar() column was a mistake by the previous programmer which you should not repeat. Add a new column to your table of type date (http://msdn.microsoft.com/en-us/library/bb630352.aspx). Copy values from the current varchar to this new column, converting as you go. Both these statements work
select CONVERT(date, 'APRIL 8, 2014')
select CONVERT(date, '04/08/2014')
To be sure these are the only combinations you should do some analysis on the current values using regular expressions (outside of SQL) or SUBSTRING() (inside SQL).
Drop the old varchar and rename the new date column. You may have to drop and re-create constraints, indexes and foreign keys etc.
When passing these values back to the application keep them in date format. Let the user interface or reporting application format the date however it needs to.

Resources