SQL SERVER: What is the difference between PARSE, FORMAT, and CONVERT? - sql

I am trying to understand the idiosyncrasies and appropriate uses of PARSE vs. FORMAT vs. CONVERT in SQL Server 2014.
PARSE
PARSE ( string_value AS data_type [ USING culture ] )
FORMAT
FORMAT ( value, format, [ culture ] )
CONVERT
CONVERT(data_type(length),expression,style)
Seems like they are all similar, just different order of required arguments. And different format of arguments (e.g. CONVERT uses style codes while PARSE uses culture codes).

PARSE and FORMAT were added to SQL 2012 for more precise parsing and string formatting.
PARSE and FORMAT are opposite operations (PARSE converts a string to another type; FORMAT converts a non-string type to a string using a specific format (e.g. currency, date-time).
CONVERT does limited conversions in either direction. It still exists for backwards-compatibility.

Related

T-SQL CONVERT fails with providing ISO formatted string + style

I'm getting an error I didn't expect to see when using CONVERT with an ISO formatted string, but only when specifying a style code (I've tried a few, and they all throw the error).
For example, this succeeds and returns the datetime in my local format:
select CONVERT(datetime, '2020-01-15T00:00:00')
But this fails with an error
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value
select CONVERT(datetime, '2020-01-15T00:00:00', 103)
I feel I must be missing something very basic here. Can anyone explain?
103 forces the format for convert().
Otherwise, convert() is somewhat flexible on the format you can provide. It does not just use the default format.
Your format, in fact, is the standard format for date/time values. And so it recognizes that regardless of the local settings. Similarly, a string YYYYMMDD is always recognized as a valid date, regardless of the local settings.

sql date format "2019-10-30", "2019/10/30", "10-30-2019" and "10/30/2019"

I think it's no doubt that in sql "2019-10-30" is valid date format, and looks like "2019/10/30" accepted as well.
What about "10-30-2019" and "10/30/2019"?
I tried them in mariaDB and they're wrong format, but somehow I think I did see them in some sql tables. Please help me clarify the date format. Thanks
In MariaDB, the format for dates is yyyy-mm-dd. But MariaDB is quite lax and other formats are accepted; from the documentation:
A DATE string is a string in one of the following formats: 'YYYY-MM-DD' or 'YY-MM-DD'. Note that any punctuation character can be used as delimiter. All delimiters must consist of 1 character. Different delimiters can be used in the same string. Delimiters are optional (but if one delimiter is used, all delimiters must be used).
A DATE literal can also be an integer, in one of the following formats: YYYYMMDD or YYMMDD.
All the following DATE literals are valid, and they all represent the same value:
'19940101'
'940101'
'1994-01-01'
'94/01/01'
'1994-01/01'
'94:01!01'
19940101
940101
So, for the examples that you provided:
2019-10-30 -- ok: default format
2019/10/30 -- ok: format with alternative delimiter
10-30-2019 -- NOT ok
10/30/2019 -- NOT ok
You can translate a string to a date with function str_to_date().
str_to_date('10-30-2019', '%m-%d-%Y')
str_to_date('10/30/2019', '%m/%d/%Y')
What you are really doing is converting from a string representation of a date to an internal date time representation or data type. The format you are referring to is ISO 8601. The ISO date (2019-10-30 with hyphens or parentheses) format is usually the native or default string conversion that most databases use, that's why those formats work even if you don't specify the conversion. If you intend to convert from other formats you probably would need to specify them. Your default representation for your local settings might work too, but that depends on the specific database.

String to date question 'style' not working

select convert (date,'27-07-2019',105)
results in 2019-07-27 while I would expect 'DD-MM-YYYY).
Why?
select convert (date,'27-07-2019',105)
You are converting to a date, which is stored and presented using the internal representation and defaults of the server.
The default presentation is YYYY-MM-DD, which is not only a SQL Server standard but also an ISO standard for representing dates. It is simply the best way to represent dates as a string (notably because it sorts correctly as a string).
If you want a bepoke string format, then convert the value to a string, not to a date.

Identify date format SQL Server

I have plenty of columns with timestamps in the following nvarchar format '2016-11-22T20:16:32.573000Z' or 'yyyy-MM-ddThh:mm:ss.[sss]Z' and I need to convert the column type into date and time format.
I know there have been many questions asked about converting string to datetime conversions in SQL Server (Azure) using CAST or CONVERT. But I seem to be unable to identify the right style:
CONVERT ( data_type [ ( length ) ] , expression [ , style ] )
The format looks like ISO 8601 style but e.g. style numbers 126 and 127 don't see to work. So which style should I use to be able to successfully convert the column?
That format is unambiguous but has more digits of precision than datetime can accommodate.
CONVERT(datetime2,'2016-11-22T20:16:32.573000Z') works fine without specifying a style, and you should be avoiding datetime in new work anyway. (Specifying styles 126 or 127 at this point is also fine if you want to, but unnecessary)
Don't know if an update SQL statement with something like this in it might help to populate a new date field and a new time field:
SUBSTRING(MyLongDateTimeStringField,1,10) AS MyNewDateField,
SUBSTRING(MyLongDateTimeStringField,12,8) AS MyNewTimeField

SQL Cast quirkiness

I have always used CONVERT (and not CAST), as I assumed the former would recognize types and do an appropriate conversion where as the latter is simply trying to interpret a stream of bytes differently. But just learned that CAST=CONVERT for most purposes!
But can someone explain why the following happens. CAST produces different results for the same value (101), but represented differently - decimal (101) and hexadecimal (0x65) representations.
select cast(0x65 as varchar(5))
-----
e
select cast(101 as varchar(5))
-----
101
EDIT:
The query was run from SSMS.
I assume you are using SQL Server (where the confusion between the two functions would make sense).
That is simple. 0x defines a binary constant. 101 is a numeric constant. These are not the same thing.
When you convert a binary constant to a string, it attempts to interpret the constant as a character. When you convert a number to a string, SQL Server converts the decimal representation.
You can learn more about constants in the documentation.
You are trying to convert to completely different values. As Gordon mentioned, one is binary representation while the other is numeric.
But you need to note that there is some differences between CAST and CONVERT:
CAST is part of the ANSI-SQL specification; whereas, CONVERT is not. In fact, CONVERT is Microsoft SQL Server implementation specific.
CONVERT differences lie in that it accepts an optional style
parameter which is used for formatting.
Read more here: https://www.essentialsql.com/what-is-the-difference-between-cast-and-convert/