how to know the format of a date - sql-server

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.

Related

T-SQL MIN on Date type resulting in INT

I have a table with a column called ThisDayOfTherapy which is of datatype DATE in SQL Server.
Later, I have an aggregate query using Min(ThisDayOftherapy). This query populates a #temp table with the result of Min(ThisDayOfTherapy) as column name StartDate_Min
In a 3rd location I am finally doing something with StartDate_Min. When I hold my mouse over StartDate_Min, it says the datatype is INT.
Shouldn't it simply be DATE? Will it still work as if it were a date for all practical purposes?
I see the same behavior, but I think you will be fine. SQL Server would not execute any date functions if it was not a valid date. Adding one day to my MinDate column from my temp table is working as expected.

Creating SQL views in VBA

I am trying to create a view on a table called petients in my database. The table has five columns. One of them is the column which I want to keep patient admitted date. It data type is datetime so I want to create a query that filters the data in this table based on current date. For example I want create a view that shows only details of petients who have been recorded on the current day.
Here is my code:
CREATE VIEW [dbo].[recent petients]
AS
SELECT petient_id, name, age, contact
FROM [petients]
WHERE [date] = 'date.Today'
I am getting an error saying that failed to convert date to string. Can you help me to solve it, or where is my code wrong?
Your code looks like SQL Server code. If so, I would recommend:
SELECT petient_id, name, age, contact
FROM [patients]
WHERE [date] = CONVERT(date, GETDATE());
As a note: This version is much better than DATEDIFF() because it allows the use of an index on patient([date]).
If the "date" column has a time component, you can use:
WHERE CONVERT(date, [date]) = CONVERT(date, GETDATE())
Note that this is also index-safe in SQL Server.
I'm assuming you are using Transact-SQL from Microsoft SQL Server, but you should specify the sql dialect you are using.
Since the datetime field type generally includes also a time, it is better to use the DATEDIFF function: https://learn.microsoft.com/it-it/sql/t-sql/functions/datediff-transact-sql?view=sql-server-ver15
In your case, to consider only the record where date=today, the difference in days must be zero:
--SQL QUERY
WHERE DATEDIFF(day, GETDATE(), [date]) = 0
day identifies the element you want to consider the difference. A list of names or abbreviations can be found in the link
GETDATE() returns now datetime
2nd and 3rd arguments are the dates you want to make the difference between

SQL server date conversion - 'Conversion failed'

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

SQL Server - Select between 2 dates of type DD/MM/YYYY

I want to query a datetime field using a range of dates provided in the format DD/MM/YYYY.
I know that to convert datetime to a DD/MM/YYYY format that I can use:
CONVERT(CARCHAR(10), ORDERDATE,103)`
And this works fine when querying a single date, eg:
SELECT DISTINCT
CONVERT(DATE, ORDERDATE),
CONVERT(CARCHAR(10), ORDERDATE,103)
FROM ORDERS
WHERE CONVERT(CARCHAR(10), ORDERDATE,103) = '19/10/2017'
Returns: 2017-10-19, 19/10/2017
However it does not work on a range of dates, eg:
WHERE CONVERT(CARCHAR(10), ORDERDATE,103) BETWEEN '17/10/2017' AND '19/10/2017'
Returns:
2014-02-05
2016-12-12
2013-04-30
I know there are hundreds of threads about SQL dates, but they all seem to be regarding reformatting the output and not preparing the input. Do I need to reformat my DD/MM/YYYY inputs?
To query a range of dates, use the DATE-datatype instead of VARCHAR.
If datatype of column ORDERDATE is DATETIME:
WHERE CONVERT(DATE, ORDERDATE) BETWEEN
CONVERT(DATE, '17/10/2017', 103) AND CONVERT(DATE, '19/10/2017', 103)
The conversion of ORDERDATE is only necessary if the start and end date are the same. (in this case, when no conversion is done, only dates with a time value of '00:00:00.000' will be returned)
EDIT:
To omit the conversion of ORDERDATE you can add the time to the dates and convert them to DATETIME instead of DATE, like this:
WHERE ORDERDATE BETWEEN
CONVERT(DATETIME, '19/10/2017 00:00:00') AND CONVERT(DATETIME, '19/10/2017 23:59:59.999');
Or even simpler, like suggested in #Used_By_Already's answer:
WHERE ORDERDATE >= '20171017' AND ORDERDATE < '20171020' --Note the end date is here +1 day
SQL Server date information should NOT be stored "in a format". If if they are literally stored in that format then they are NOT dates as far as the database is concerned (they are "strings" that look like dates) and you will have a nightmare to deal with if they are DD/MM/YYYY because they simply will not behave like dates should.
There are several specific data types in SQL Server for date/time information (datetime, datetime2, smalldatetime, date, time) but ALL of these do not store data in a human readable format at all. Instead they stored as groups of numbers, which will be displayed in a human readable manner, and in your case - by default - you are seeing then in DD/MM/YYYY format. A user in China might prefer to see a date in YYYY.MM.DD or in the USA as MM/DD/YYYY. This is possible because a human format is applied on top of the numbers that are stored before they get displayed.
So. In SQL Server there is a "safe" date literal in the form of 'YYYYMMDD' and this may be used without the need to CONVERT or CAST:
IF your [ORDERDATE] column is a date (or smalldatetime/datetime/datetime2) then this will work:
WHERE ORDERDATE BETWEEN '20171017' AND '20171019'
OR, you may explicitly convert a string to but you need a "style number" to be present to make these fully reliable. Style 103 for example is for DD/MM/YYYY
WHERE ORDERDATE BETWEEN CONVERT(date, '17/10/2017',103) AND CONVERT(date, '19/10/2017',103)
Although "between" has been used in the discussion above a far more reliable method of forming date ranges is to NOT use "between", instead do it this way:
WHERE ORDERDATE >= '20171017' AND ORDERDATE < '20171020'
With this pattern (note the second day is now +1) it does not matter which date precision is stored in the column. For example, see Bad habits to kick : mis-handling date / range queries

SQL Server: How to query date in a certain format

I am pretty new to SQL and hope someone here can help me with the following:
I have a table in SQL Server with one column storing dates and I have a simple stored procedure to select data from this table.
Currently it fetches the date including hours and minutes.
How can I achieve that it fetches the date in format yyyy-mm-dd (without the hours and minutes) ?
My column is called "logDate" and my table is called "logTable".
Thanks for any help with this, Tim
If you only want to store the date, convert the column to a date type, not a datetime.
If you want to keep the date and time in the data, but just display the date
select convert(date, logDate) from logTable
If you want to return the date as a string, use convert
select convert(varchar(10), logDate, 120) from logTable

Resources