-1

It may just be me, but... Despite the fact that most sql developers may consider cast & convert to be very basic stuff, and that may be true, I find Microsoft's documentation page on CAST & CONVERT to be one of the most hideous, not-intuitively-laid-out, hard to understand things I have ever seen. Much of their documentation is great. Like constantly trying to blend the entire page into a mix of both cast and convert, jumping back and forth in each sentence... rather than dealing with them separately. And who puts the target_type as the first argument? Putting the expression as the first argument would be more intuitive - and follow the other 99% of numerous programming languages' syntax. UH

MS says that I can only convert to 3 data types: (well actually I'm not really sure if this applies to both CAST and CONVERT, since they ARE, in fact, different... But according to the layout of that webpage, it apparently applies equally to both - even though I already know for a fact that it is not true for CAST, which I use much more frequently).

It says: "Is the target data type. This includes xml, bigint, and sql_variant"

Putting aside for the moment the fact that I CAST things as many other datatypes all the time (date, varchar),

My immediate question is: if I can only CONVERT to those data types, then why does this work?

select CONVERT(varchar(200), cast(50 as smallint))

And finally, I'd like to run an INSERT that will be getting a smallint and putting it into a varchar(200) column.

All I'm trying to do is avoid any failures, so maybe I don't really "need" to convert or cast over to varchar, but any commments on

  1. answer on what is my apparent misunderstanding about the CONVERT documentation

or

  1. how to safely convert it to insert to varchar

are welcome. As long as you're not just overly unpleasant, since there are always those MS fans who get hot under the collar at all critiques of MS .. :|

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Isaac
  • 351
  • 1
  • 4
  • 21
  • 1
    You forgot to end with, "/rant" :) – Jeff.Clark Apr 21 '16 at 15:58
  • Which documentation page are you referring to? https://msdn.microsoft.com/en-GB/library/ms187928.aspx ? – Simon Apr 21 '16 at 15:58
  • 2
    It isn't limited too those 3 datatypes. Those 3 datatypes are included. – SQLChao Apr 21 '16 at 15:59
  • Presumably so from the line "This includes xml, bigint, and sql_variant". These are just examples of types you can use, not the only ones you can use. – Simon Apr 21 '16 at 16:00
  • Yeah, I guess "includes" would mean includes, not necessarily limited to, you're right. What an incredibly useless/troublesome statement to make, though. Imagine if I made a program & said, "On the next screen, fill in the critical parameter with an allowed values. Allowed values include RED & BLUE". But really there were 50 allowed values. Dang . And yes Jeff, I did forget the /rant. Isn't it interesting though that most comments were actually more interested IN the rant rather than the question that followed? Hmm, maybe says something about all of our ranting enjoyment perhaps? :) – Isaac Apr 21 '16 at 16:11
  • Yes, the #1 google result for "t-sql cast and convert", or almost anything like that https://msdn.microsoft.com/en-us/library/ms187928.aspx – Isaac Apr 21 '16 at 16:14
  • I enjoy a good rant :) I also am too ignorant on the subject to give an educated answer, but I got a good laugh! – Jeff.Clark Apr 21 '16 at 16:21
  • A good rant is always worthwhile. :) I usually find msdn documentation generally unhelpful. – Simon Apr 21 '16 at 16:23
  • LOL - thanks for the reassurance, I was interpreting it as maybe you were sternly disapproving :) .. because I know on S.O. they do try to strictly avoid useless posts, which I totally agree with, and I often have a bit of whining in my posts but always include an actual question - glad to hear that I can, (presumably? still guessing?) = CONVERT to anything...well anything that can be converted to I guess...(!?) I dunno, this is very unlike MS. I agree Simon, I usually admire and respect their doc. That page just creates a million unanswered questions, to me at least. – Isaac Apr 21 '16 at 16:26
  • I think the graph on that MSDN page about 1/3 the way down would have saved you a lot of typing. It clearly states FROM smallint TO varchar is an implicit conversion. – TTeeple Apr 21 '16 at 18:09

2 Answers2

2

Yes, you can convert from smallint to varchar.

1) answer on what is my apparent misunderstanding about the CONVERT documentation

This may be product of general lack of understanding on what data types are, how can they be converted from one type to another and equally important; what styles are when it comes to the aesthetic representation of a data type.

CAST is an explicit cast operation with no style options. CONVERT is also an explicit cast that gives you the ability to specify a style for the output.

The documentation clearly states:

Implicit Conversions

Implicit conversions are those conversions that occur without specifying either the CAST or CONVERT function. Explicit conversions are those conversions that require the CAST or CONVERT function to be specified. The following illustration shows all explicit and implicit data type conversions that are allowed for SQL Server system-supplied data types. These include xml, bigint, and sql_variant. There is no implicit conversion on assignment from the sql_variant data type, but there is implicit conversion to sql_variant.

For your second question

2) how to safely convert it to insert to varchar

Depending of what you mean by safe. Converting to varchar is the convertion that most likely succeed. But whenever to cast to any toher datatype you are intrinsically changing the very nature of the data and will lose precision when casting to smaller types (or applying styles).

The documentation clearly states:

Truncating and Rounding Results

When you convert character or binary expressions (char, nchar, nvarchar, varchar, binary, or varbinary) to an expression of a different data type, data can be truncated, only partially displayed, or an error is returned because the result is too short to display. Conversions to char, varchar, nchar, nvarchar, binary, and varbinary are truncated, except for the conversions shown in the following table.

in other words, casting is never safe.

Ricardo C
  • 2,205
  • 20
  • 24
  • Okay, well - I knew a strong admonishing was coming at some point, so your comments--which I think are to some extent perhaps a bit overly pointing toward incompetence on my part more than is fair, which precisely misses the point of my 'documentation' comment--are expected, and more or less received. Of course I could say, "Conclusion: Learn more about written communication" ... Documentation has that element to it too. I stated originally, I usually love MS documentation; that page however seems far less clear than it could be. – Isaac Apr 21 '16 at 17:37
  • I have a LOT of experience in basic programming concepts, but am still in the "moderate" at MS-SQL experience, it's true. A typical mistake SQL dev's make is assuming that all programming is like MS SQL. – Isaac Apr 21 '16 at 17:37
  • Actually in many contexts, the idea of MS SQL's seemingily innumerable "implicit" things happening behind the scenes would make devs from many platforms vomit, it creates a bottomless pit of things to keep track of. I'd much rather they do less implicit things and instead we be required to directly control more of that, raising an error if we don't. It just gets to be a ridiculously large amount of interrelated, spiderweb of conditions to memorize – Isaac Apr 21 '16 at 17:38
  • Again, I am NOT an MS hater, I like almost all things Microsoft, I like 99% of their documentation, but that page brought out what you see as my weakness (ok, true), or their weakness (for making this be such a major study in the first place), because of all of the implicit, explicit, etc... And you know that that really isn't the end of it. Now multiple that times 5 SQL Server versions and database setup options and SET statements – Isaac Apr 21 '16 at 17:38
  • Finally, I do appreciate your answer, and I've provided answers on other platforms for years to relatively ungrateful OPs, so take my words at face value please - I thank you for the reply, and your time in resolving what you feel is 100% the need to study on my part. Honestly, I believe the best thing a dev community can do for a platform owner (MS SQL) is to be honest, critique as much as necessary, allow the pain points to come out. You do them no good by pretending all is perfect-they are greatly helped by developers who show them what seems overly hokey or cumbersome rather than yes-men – Isaac Apr 21 '16 at 17:38
  • AppSheet is a great example, new product which I LOVE, but most of their users are analyst/excel types who just can't understand why I ask for parameterized reporting mechanisms, hooking into EVENTS, and stricter documentation on many things. But AppSheet loves the feedback, seems they've received precious little from academic minded developers – Isaac Apr 21 '16 at 17:38
  • @Isaac Sr, I have removed my snarky remarks, they don't contribute to the answer and I do apologize, they were out of place. However cynical my original answer was, I hope they offer at least a little bit of clarification for you. – Ricardo C Apr 21 '16 at 19:26
  • Thanks Ricardo, that's certainly more than I expected and I thank you for your last comment. The answer truly is valuable--I know S.O. is a crowded place and I really do respect the need to discourage over-posting (about things easily found already, just that 'easily' is so relative), so I always feel a bit guilty about posting in general - because there is always someone (or a lot of people), who could have found out the answer without a new post - but your answer stands as a very useful reference, that's for sure. Thanks again! – Isaac Apr 21 '16 at 19:55
0

Numbers always get silently truncated for me. I would propose:

Option 1

Compare the converted value with the original value.

DECLARE @ORIGINAL DECIMAL(13,2) = -99999999999.99 -- 
DECLARE @EXPECTED VARCHAR(15) = ''
SELECT @EXPECTED = CONVERT(VARCHAR(15),@ORIGINAL)
IF CONVERT(DECIMAL(13,2),@EXPECTED) != @ORIGINAL SELECT 'Ooops'

Option 2

Make sure that all possible values will fit in target varchar.

Decimal(13,2). Widest number possible will be "-99999999999.99" needs varchar(15):

  • 13 chars for digits
  • 1 char for decimal separator
  • 1 char for minus sign

Smallint stores 2 bytes, from "-32768" to "32767", needs varchar(6): - 5 chars for digits - 1 char for minus sign

Not sure if you need chars for thousands separators, or if you can change it via settings.

Enric Naval
  • 164
  • 1
  • 7