T-SQL Cast versus Convert - sql

What is the general guidance on when you should use CAST versus CONVERT? Is there any performance issues related to choosing one versus the other? Is one closer to ANSI-SQL?

CONVERT is SQL Server specific, CAST is ANSI.
CONVERT is more flexible in that you can format dates etc. Other than that, they are pretty much the same. If you don't care about the extended features, use CAST.
EDIT:
As noted by #beruic and #C-F in the comments below, there is possible loss of precision when an implicit conversion is used (that is one where you use neither CAST nor CONVERT). For further information, see CAST and CONVERT and in particular this graphic: SQL Server Data Type Conversion Chart. With this extra information, the original advice still remains the same. Use CAST where possible.

Convert has a style parameter for date to string conversions.
http://msdn.microsoft.com/en-us/library/ms187928.aspx

To expand on the above answercopied by Shakti, I have actually been able to measure a performance difference between the two functions.
I was testing performance of variations of the solution to this question and found that the standard deviation and maximum runtimes were larger when using CAST.
*Times in milliseconds, rounded to nearest 1/300th of a second as per the precision of the DateTime type

CAST is standard SQL, but CONVERT is only for the dialect T-SQL. We have a small advantage for convert in the case of datetime.
With CAST, you indicate the expression and the target type; with CONVERT, there’s a third argument representing the style for the conversion, which is supported for some conversions, like between character strings and date and time values. For example, CONVERT(DATE, '1/2/2012', 101) converts the literal character string to DATE using style 101 representing the United States standard.

Something no one seems to have noted yet is readability. Having…
CONVERT(SomeType,
SomeReallyLongExpression
+ ThatMayEvenSpan
+ MultipleLines
)
…may be easier to understand than…
CAST(SomeReallyLongExpression
+ ThatMayEvenSpan
+ MultipleLines
AS SomeType
)

CAST uses ANSI standard. In case of portability, this will work on other platforms. CONVERT is specific to sql server. But is very strong function. You can specify different styles for dates

You should also not use CAST for getting the text of a hash algorithm. CAST(HASHBYTES('...') AS VARCHAR(32)) is not the same as CONVERT(VARCHAR(32), HASHBYTES('...'), 2). Without the last parameter, the result would be the same, but not a readable text. As far as I know, You cannot specify that last parameter in CAST.

Related

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/

Are CAST and CONVERT the same in SQL? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
T-SQL Cast versus Convert
What is the major difference between CAST and CONVERT in SQL cause both performs data type conversion?
CAST and CONVERT have similar functionality. CONVERT is specific to SQL Server, and allows for a greater breadth of flexibility when converting between date and time values, fractional numbers, and monetary signifiers. CAST is the more ANSI-standard of the two functions. Check this blog for examples of using both of those: http://sqltutorials.blogspot.com/2007/06/sql-cast-and-convert.html
The convert function can do more complex conversions, for example converting a datetime value into varchar using a specific format:
convert(varchar(16), dateTimeValue, 120)
Assuming you're talking about SQL Server.
From http://msdn.microsoft.com/en-us/library/ms187928.aspx and http://msdn.microsoft.com/en-us/library/aa226054(v=sql.80).aspx
Explicitly converts an expression of one data type to another. CAST and CONVERT provide similar functionality.
So yes, they are functionally the same. They just have different syntax that allows for more complex conversions or (subjectively) improved readability.

Which one is more desired when dealing with dates? sql DateTime or nvarchar string?

Does SQLs built-in DateTime type has any merits over nvarchar type?
If it were you , which one would you use?
I need to store dates in my SQLServer database and I'm curious to know which one is better and why it is better.
I also want to know what happens if I for example store dates as string literals (I mean nvarchar )? Does it take longer to be searched? Or they are the same in terms of performance ?
And for the last question. How can I send a date from my c# application to the sql field of tye DateTime? Is it any different from the c#s DateTime ?
You're given a date datetype for a reason, why would you not use it?
What happens when you store "3/2/2012" in a text field? Is it March 2nd? Is it February 3rd?
Store the date in a date or datetime field, and do any formatting of the date after the fact.
EDIT
If you have to store dates like 1391/7/1, your choices are:
Assuming you're using SQL Server 2008 or greater, use the datetime2 data type; it allows dates earlier than 1753/01/01 (which is what datetime stops at).
Assuming you're using SQL Server 2005 or earlier, store the dates as Roman calendar dates, and then in your application, use date/time functions to convert the date and time to the Farsi calendar.
Use the correct datatype (date/datetime/datetime2 dependant on version and requirement for time component).
Advantages are more compact storage than storing as a string (especially nvarchar as this is double byte). Built in validation against invalid dates such as 30 February. Sorts correctly. Avoids the need to cast it back to the correct datatype anyway when using date functions on it.
If I'm storing a DateTime value, and I expect to perform date-based calculcations based on it, I'll use a DateTime.
Storing Dates as strings (varchars) introduces a variety of logistical issues, not the least of which is rendering the date in a proper format. Again, that bows in favor of DateTime.
I would go with the DateTime since you can use various functions on it directly.
string wouldn't be too much of a hassle but you will have to cast the data each time you want to do something with it.
There is no real performance variance while searching on both type of fields so going with DateTime is better than strings when working with date values.
you must realise the datetime datatype like other datatypes is provided for a reason and you should use the datatype that represents your data clearly.. Besides this you gain all the functionalities/operations that are special to the datetime datatype..
One of the biggest gains is correct sorting of data which will not be possible directly if you use nvarchar as your datatype.. Even if you think you dont need sorting right now there will be a time in the future where this will be useful.
Also date validation is something that you will benefit from. There is no confusion of the dateformat stored i.e dd/mm or mm/dd etc..
There is lot discussed about the subject. There is good post on the SQLCentral forum about this particular subject DateTime or nvarchar.
In short, nvarchar is twice as longer as datetime, so it takes more space and on the long range, any action affecting it will be slower. You will have some validation issues and many more.

Implicit casting when joining fields of different types

I am joining a field that has single digit numbers formatted with a leading 0 to another that does not have leading 0's. When I realized this I tested my query out only to find that it was actually working perfectly. Then I realized what I'd done... I had joined an nvarchar field to an int field. I would have thought sql would have given me an error for this but apparently it converts the character field to an int field for me.
I realize this is probably not a good practice and I plan to explicitly cast it myself now, but I'm just curious if there are rules for how SQL decides which field to cast in these situations. What's to keep it from casting the int field to a character type instead (in which case my query would no longer work properly)?
There are rules indeed.
CAST and CONVERT (Transact-SQL) to learn what can be converted to what ("Implicit Conversions" section).
Data Type Precedence (Transact-SQL) to learn what will be converted to what unless specifically asked.

Stop concat removing leading 0

Hoping someone can help.
I am attempting to add a ||'m' to my query but when I add the concat it removes the leading zero.
With out the ||'m' I get this result:
0.00
With the concat I get this result for example:
.0m
edit:
Here is the query:
round(MAX(city_longitude),1) - round(MIN(city_longitude),1)||'m'
Cheers
Try wrapping the whole ROUND statement in a TO_CHAR giving it a format mask.
TO_CHAR(round(MAX(city_longitude),1) - round(MIN(city_longitude),1), '0.00')||'m'
This way you effectively concatenate a string with a string whereas you are currently concatenating a numeric with a string forcing an implicit conversion.
Implicit conversions are usually frowned upon as they can lead to unexpected results.
Oracle says:
Oracle recommends that you specify explicit conversions, rather than
rely on implicit or automatic conversions, for these reasons:
• SQL statements are easier to understand when you use explicit
datatype conversion functions.
• Implicit datatype conversion can have a negative impact on
performance, especially if the datatype of a column value is converted
to that of a constant rather than the other way around.
• Implicit conversion depends on the context in which it occurs and
may not work the same way in every case. For example, implicit
conversion from a datetime value to a VARCHAR2 value may return an
unexpected year depending on the value of the NLS_DATE_FORMAT
parameter.
• Algorithms for implicit conversion are subject to change across
software releases and among Oracle products. Behavior of explicit
conversions is more predictable.
Number formats are here:
http://www.oradev.com/oracle_number_format.jsp
Hope it helps...