I have a table with a supposed date field but the data is coming in as a nvarchar in the form 27-01-2023 - 15:18:52. It appears that extra - is causing SQL Server not to recognize it as a date and means I can't use the CAST function without it throwing an error.
Normally I would use REPLACE to change it to a blank then use cast but that obviously affects all the -'s in the field which messes up the date portion. How do I go about telling SQL to remove the 3rd instance of a - from this field?
You could try to combine REPLACE and CONVERT function, which could specify DateTime format style (103 is corresponding of dd/MM/yyyy, British/French standard date format).
SELECT CONVERT(DATETIME,REPLACE('27-01-2023 - 15:18:52', ' - ', ' '), 103)
See demo here
Related
I have over 65 columns among which there are about 30 Date Columnns. I want to set it to MM/DD/YYYY. Presently it is also showing the time YYYY-MM-DD hh:mm:ss. I tried correcting this within the SQL query by using cast. The SQL output shows only date, but it again gets represented in DateTime in SSRS. I dont want to right click on 30 columns manually to set date format. Is there a way to set default date format for all date columns in the report?
"Cast" is not helping here since it is about types, not format.
Try using the "convert" function instead.
In your case, it would be
-- use your field name instead of sysdatetime()
select convert(varchar, sysdatetime(), 101/*mm/dd/yyyy format Id*/);
You should be able to select all the fields in the tablix and change the formatting together. You may wish to consider using a parameter for the formatting.
I have to run column checks for data consistency and the only thing that is throwing off my code is checking for character lengths for dates between certain parameters.
SEL
sum(case when ( A.date is null or (character_length(A.date) >8)) then 1 else 0 end ) as Date
from
table A
;
The date format of the column is YYYY-MM-DD, and the type is DA. When I run the script in SQL Assistant, I get an error 3580 "Illegal use of CHARACTERS, MCHARACTERS, or OCTET_LENGTH functions."
Preliminary research suggests that SQL Assistant has issues with the character_length function, but I don't know how to adjust the code to make it run.
with chareter length are you trying to get the memory used? Becuase if so that is constant for a date field. If you are trying to get the length of the string representation i think LENGTH(A.date) will suffice. Unfortanatly since teradata will pad zeros on conversions to string, I think this might always return 10.
UPDATE :
Okay so if you want a date in a special 'form' when you output it you need to select it properly. In teradata as with most DBs Date are not store in strings, but rather as ints, counting days from a given 'epoch' date for the database (for example the epoch might be 01/01/0000). Each date type in teradata has a format parameter, which places in the record header instructions on how to format the output on select. By default a date format is set to this DATE FROMAT 'MM/DD/YYYY' I believe. You can change that by casting.
Try SELECT cast(cast(A.date as DATE FORMAT 'MM-DD-YYYY') as CHAR(10)) FROM A. and see what happens. There should be no need to validate the form of the dates past a small sample to see if the format is correct. The second cast forces the database to perform the conversion and use the format header specified. Other wise what you might see is the database will pass the date in a date form to SQL Assitant and sql assitant will perform the conversion on the application level, using the format specified in its own setting rather then the one set in the database.
I want to create a function, which has a paramater ( a string which contains a date ) and then the function converts it and returns it. In our company we have workstations with three different languages. We have hungarian, english and german workstations too. I want to read a date from the registry, but this date will be written into the registry according to the current regional setting.
So if the regional setting is hungarian, then date written to date registry is 2012.01.25 (YYY.MM.DD), but if i change the regional setting to german then the value written to the registry will be 25/01/2012 (MM.DD.YYYY). If i change the regional setting to english, then the value will be 01/25/2012 (DD.MM.YYYY).
Unfortunately i don't know which regional setting was used when the date was written into the registry, because it can be changed since the value was written into the registry.
This iy why i want to create a function which gets a date, and then converts it to this format: YYYY.MM.DD. but i don't know how to do it.
Could someone help me how to do this?
Thanks!
Are you managing this registry value directly or it belongs to another software and just trying tomread it?
If it's yours, then
A. if it is a string value, then simply format it before storing, to ISO format (yyyy-MM-dd), format or formatdate function will do the trick
B. if it is a binary value, convert the datetime value to double with cdbl and store that
Well, if it's not yours, then it's not your lucky day. I've done it a couple of years ago and I used the text around the date to make an assumption on the format ...
You can use this expression to convert your strings to SQL type date. This expression uses the DD/MM/YYYY format only when it cannot use its default MM/DD/YYYY format.
CASE
WHEN CHARINDEX('/', val)=5 THEN CONVERT(date,val,111)
ELSE CONVERT(date, val, CASE WHEN LEFT(val,2) <= '12' THEN 101 ELSE 103 END)
END
This expression should be used inside a select statement. I am assuming that the name of your varchar column containing a date string is val.
If you are saving those dates on a date type of column (DATETIME, DATE, SMALLDATETIME, etc), then it won't matter how it is displayed or under what language it was saved. If you want to convert a DATE to a VARCHAR on the format YYYY.MM.DD then you can use: CONVERT(VARCHAR(10),YourDate,102).
I am seeeing my dates are stored in database in this format for a column (datetime datatype) 2011-01-14 10:15:41.787 i.e YYYY-MM-DD way . How could I make the default storage in YYYY-DD-MM format . Do I need to set that for all the DBS, or I can set it for single DB and how ?
I have the column in datetime datatype, right now it is saving as
2011-01-14 10:15:41.787 , my question is how can I set the db to store it as
2011-14-01 10:15:41.787
That is the crux of the confusion. Just because SQL Server Management Studio displays a datetime column in that format does not mean that it is stored AS TEXT YYYY-MM-DD hh:mm:ss.zzz. It is stored as binary, something like 0000101000001010..
Your dates are stored in SQL Server as a series of bytes (bits really) that make up some numeric value that is an offset from 1900-01-01. There is no inherent format the the dates. What you are referring to is that SSMS by default shows [display] datetime columns as YYYY-MM-DD hh:mm:ss.zzz. If you use a front-end programming tool, that too may impose a default [display] format unless you have asked for another one.
There is absolutely NO way to make SSMS show datetime data in another format through options or configuration. If you must, you would have to update the SQL query to convert the datetime column to a VARCHAR column containing the TEXTual equivalent in a particular format. That may be useful in SSMS, but would be bad when used as a data source to front-end GUI/web apps - since the values are not datetime and cannot be used for interval calculation, graphing, bound to date controls etc.
See this example of displaying time (getdate()) as YYYY-DD-MM, a very unusual format. Notice the date field/variable has to be used twice:
select stuff(convert(char(7), getdate(), 120), 5, 0, '-' + convert(char(2), getdate(), 3))
DATETIMEs are stored internally as two 4 byte integers, so firstly you are seeing a formatted representation for the UI - it's not actually stored in a particular date/time format as such.
e.g. if you insert just a date like "2010-01-01" then it will still hold the time element: 2010-01-01 00:00:00.000
If you're only interested in the DATE part, then you can format the DATETIME for output either in your front-end code or via your query:
e.g.
SELECT CONVERT(VARCHAR(8), GETDATE(), 121)
So even if the DATEs you insert contain a time, that will be ignored when returned. You could also ensure you only insert dates without the time specified - you need to handle that in whatever code is doing the INSERTs. e.g. from .NET, instead of passing in DateTime.Now you could pass in DateTime.Now.Date.
In SQL Server 2008, there is a DATE datatype which is there to only store a DATE (without time) which is really what you want in this kind of scenario.
I've got a seamingly simple problem to solve that normally would be fairly easy. I've got a field that contains a DateTime portion, as well as a trailing text portion. I now need to split this field into two discrete fields - DateTime and Varchar. Now for the little gotcha. The data has been saved with two different date formats which has resulted in the filed looking a 'lot' like this:
amendmentnote
----------------------------------------------------------------------
30/07/2010 11:39:55: Booking status change from On Option to Cancelled
5/5/2010 10:1:8 : New
as you can see, the dates are in two completely different formats. I'd like to somehow see it parsed out as:
dateofnote | note
----------------------------------------------------------------------
30/07/2010 11:39:55 | Booking status change from On Option to Cancelled
05/05/2010 10:01:08 | New
is this easily do-able??
cheers
jim
Easily? No. Do-able. Yes, if we can make some assumptions. If it is the case that the text never contains a colon, you could do:
Declare #Data Table ( Data Varchar(max) )
Insert #Data(Data) Values('30/07/2010 11:39:55: Booking status change from On Option to Cancelled')
Insert #Data(Data) Values('5/5/2010 10:1:8 : New')
Set DateFormat DMY
Select Cast(Reverse(Substring(Reverse(Data), CharIndex(':', Reverse(Data)) + 1, Len(Data))) As DateTime)
, LTrim(Reverse(Substring(Reverse(Data), 1, CharIndex(':', Reverse(Data)) - 1)))
From #Data
It's do-able, but it'll be ugly.
You can use string functions to find the third colon in the amendmentnote field, and anything to the right of the third colon will be your note.
As for the date, you should again be able to use string functions to reformat the date portion, although you'll most likely need lots of substrings to make it work.
My only concern would be if the date formats entered are MM/DD/YYYY for one entry, and DD/MM/YYYY for the other.
Based on what's provided, use:
SELECT CONVERT(DATETIME,
SUBSTRING(t.amendmentnote, 1, LEN(SUBSTRING(t.amendmentnote, 1, PATINDEX('%: %', t.amendmentnote)))-1),
103),
LTRIM(SUBSTRING(t.amendmentnote,
LEN(SUBSTRING(t.amendmentnote, 1, PATINDEX('%: %', t.amendmentnote)))+1,
LEN(t.amendmentnote)))
FROM YOUR_TABLE t
Being a DATETIME, you can use CAST/CONVERT to format it as you like - don't store "presentation" data.
Bad data is bad data - this is a mine field you'll have to navigate, isolating rows that won't match the pattern in the query & deal with appropriately.
Once in a DateTime column, they'll be in the standard DateTime format. How they're presented once queried at that point is up to you.
So, once you split your data into your DateOfNote and Note columns, you can Convert the DateOfNote to VarChar and apply a format to get what you want.
Convert(NVARCHAR, DateOfNate, 103) will get you there (I think: double check the format style there at the end).
Edit Based on your question, it looks like you wanted more help with the formatting. However, on the splitting the column, you'll need to use string functions. I'd find the index of that last colon, store it in a local variable, and then use substring to find the datetime (left of that last colon) and the note (right of last colon).