Can someone interpret this query. I am aware that alias, conversion, and linked databases are involved, but not familiar placement of numbers "4,2".
set birthday = convert(datetime, left(a.dob,2)+ '/'+
right(left(a.dob,4),2)+'/'+
right(a.dob,2)+left(right(a.dob,4),2))
from
[plkfsql2k5\prod2k5].st_data.dbo.st_patient a
This left(a.dob,2)+ '/'+right(left(a.dob,4),2)+'/'+right(a.dob,2)+left(right(a.dob,4),2) nightmare of a substring concatenation is taking a date, probably stored as text (ugh) and returning it in a format that can be converted to a date with the convert(datetime, <textdate) formula it's wrapped in.
The text date appears to be in a format where the month is in the first 2 characters, the day is in the 3 and 4th characters and the year... well the years is stored instead of 1999 like 9919 because some psychopath designed this field...
So it takes this mmddyyYY format (that only a crazy person would use) and coverts it to mm/dd/YYyy and the n uses the convert(datetime, <text date>) function to make it into an actual date.
Note that if you are in a country that uses dd/mm/yyyy format, then my explaination may need to be tweaked as the incoming text value may be ddmmyyYY and converts it to dd/mm/YYyy. Still a crazy-banana's starting point though.
Related
I create column in this way:
ALTER TABLE cages
ADD test date;
I add date to this column
for instance
'01/07/21'
and when I use like always select:
select *
from cages
where test = '01/07/21';
I get nothing, it's weird, because in different table it's works... Can it connection with pk or fk or what is the reason of this?
edit:
I use SQL orlace developer.
edit:
thanks everyone for help, problem was that I used calendar to put date to column and it add date with time.
Why is it possible, when I have type date not dateTime?
Not everyone formats date values the same way. When looking at a date like 01/07/21, most of the people on this site will naturally read January 7, 2021*. The group that reads this as July 1, 2021 (today) is significant, but still slightly smaller. A few people come from cultures where July 21, 2001 is the natural interpretation.
To avoid this kind of ambiguity, when writing date literals for SQL you should always format them using the ISO-8601 formats, which always uses four digit years, goes in sequence from most significant term on the left to least significant term on the right, and always uses leading zeroes to fill out the full width of a term:
yyyy-MM-dd HH:mm:ss.fff
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd
yyyyMMdd (unseparated version of the format preferred on Sql Server for date-only values for historical reasons)
Anything else is wrong for SQL.
For completeness, I also want to key in on the word "literals" from the beginning of the second paragraph. We should always use parameterized queries/prepared statements when putting date values into a query from a client code language, rather than using string manipulation to substitute a literal into the SQL command. On strongly typed platforms this usually means using the DateTime type provided by the language to set the value. If you find yourself converting a datetime variable to a string for inclusion in an SQL query, you're making a mistake.
* This isn't just a blind assertion. A few years back I did a basic review of the public portion of the Stack Overflow developer survey, where I first looked up which countries/languages default to which date formats, and then grouped countries together based on their format. I wish I had saved the results :/. I forget how I treated places with mixed heritage like Canada.
Your root problem, and I'm amazed no one seems to have picked up on this, is that your column is a DATE but in your query you are comparing it to a STRING. This may or may not work, depending on your NLS_DATE_FORMAT setting. You need to compare like data types:
select *
from cages
where test = to_date('01/07/21','dd-mm-yy');
I leave it as an exercise for the student to go to the SQL Reference manual and read up on the TO_DATE function.
I also beg and plead with you to not be trying to use 2-digit years. As an industry we were supposed to have solved that problem over 20 years ago. Does the term "Y2k bug" not mean anything to you?
As it is, the date that is represented by the string '01/07/21' could be understood to be any of the following
Jan 7
Jan 21
Jul 1
Jul 21
And who knows the year? 2021? 1921? 1821? 2001? 1901? 2007? 1907?, 1807?
You might want to read this.
Using SQL Developer if you insert a date in a table using user interface it automatically generates hours and minutes like if it's a Timestamp. If the format you are using is correct you should be able to retrieve your rows using like operator instead of equal.
select * from cages where test like '01/07/21%';
The only way to retrieve your rows using equal operator is when the timestamp is set to 00:00:00
1st July 2021 is written date '2021-07-01' in Oracle SQL.
You can read more about literals in the Oracle SQL Reference.
You can also use a to_date expression like
to_date('2021-07-21','YYYY-MM-DD')
or
to_date('1-Jul-21', 'DD-Mon-YY', 'nls_date_language = English')
or indeed
to_date('1-Lug-21', 'DD-Mon-YY', 'nls_date_language = Italian')
but frankly, why would you?
Bear in mind that that the person running the query/report/procedure, or the application server in use, may not have the same territory and language settings as you, so it is dangerous to assume that the century for a 2-digit year will always be what you expect (what year is '50'?) or the language will always be English, or the week always starts on a Monday. I worked on a system once where we deployed some code that used 'DD-MON-YYYY', to offices in London and Paris. We deployed it in September, and we had a production issue in Paris in February, because Sep, Oct, Nov, Dec and Jan still worked, but French has no Feb.
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've got a query that get's a date of a field in a program. This date has to be modified with 10 years.
The query I made is
SELECT DATEADD(yy, +10, '"+thisfield.value+"')
where '"+thisfield.value+"' is coming from the program and is filled in like 01-08-2012.
The result of the query is 2022-07-31 00:00:00.000. The problem I have is that I just need 2022-08-01 but in the format of 01-08-2022 so that I can automatically fill an other field with this result.
In SQL Server 2005 the date function doesn't work only the datetime function and I just don't need that.
I hope this is clear (first time i post something). Can anyone help me?
You can either truncate the result, or cast it to DATE
CAST(DATEADD(yy, +10, '"+thisfield.value+"') AS DATE)"
CONVERT(VARCHAR, DATEADD(yy, +10, '"+thisfield.value+"'), 101)"
CONVERT using style 101 is in the format mm/dd/yyyy, which happens to be the format you want. Keep in mind that you can format the result however you want in your application for display purposes which is better than returning strings from SQL Server.
Also note that you should look into parameterized queries and/or stored procedures.
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.