create xml schema collection maximum value of fractionDigits restriction - sql-server

I'm trying to load third party XSD Scheme to my SQL Server 2008 throught "create xml schema collection" statement
There is a complex type based on "xs:decimal" with restrictions:
<xs:totalDigits value="31"/>
<xs:fractionDigits value="14"/>
inside the XSD.
And SQL Server returns error
Msg 6960, Level 16, State 2, Line 2
Component 'NAME' is outside of allowed range. Maximum for 'fractionDigits' is 10 and maximum number of digits for non fractional part is 28
But I still able to create a variable with type "numeric(31,14)"
I didn't find any restrictions neither on w3c documentations nor in MSDN. Can you please guide me to some documentation on this restrictions. May be I can fix it with some Service Pack or Setting.
SQL Server version: Microsoft SQL Server 2008 (SP3) - 10.0.5500.0 (X64) Sep 21 2011 22:45:45 Copyright (c) 1988-2008 Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 (Build 7601: Service Pack 1)
I found an answer on the MSDN (http://msdn.microsoft.com/en-us/library/ms190665(v=sql.100).aspx)
SQL Server does not support variable precision decimals. The
xs:decimal type represents arbitrary precision decimal numbers.
Minimally conforming XML processors must support decimal numbers with
a minimum of totalDigits=18. SQL Server supports totalDigits=38, but
limits the fractional digits to 10. All xs:decimal instanced values
are represented internally by the server by using the SQL type numeric
(38, 10).
They map xs:decimal not to numeric type, but decimal

I found an answer on the MSDN (http://msdn.microsoft.com/en-us/library/ms190665(v=sql.100).aspx)
SQL Server does not support variable precision decimals. The
xs:decimal type represents arbitrary precision decimal numbers.
Minimally conforming XML processors must support decimal numbers with
a minimum of totalDigits=18. SQL Server supports totalDigits=38, but
limits the fractional digits to 10. All xs:decimal instanced values
are represented internally by the server by using the SQL type numeric
(38, 10).
They map xs:decimal not to numeric type, but decimal

Related

SQL is removing leading zeros

Problem: I have large tables from the data warehouse with Course Numbers stored as nvarchar(20).
For the last 50 years, these course numbers have all been 8-digits, including many leading zeros for lower numbers.
But now, our cloud provider has decided to operate with 10-digit Course Numbers
A numerically equivalent value with leading zeroes is NOT recognized by the cloud provider as being equivalent. They are using strict string logic. But SQL Server 2008 seems to be trying to do me "favors" by treating strings of digits as if they were numbers.
If I query a table with no WHERE clauses, I get only the 8-digit (8-character) records.
The records with 10-digit (10-character) CourseNbr have disappeared.
But If I explicitly ask for records WHERE (LEN([CourseNbr]) = 10), it returns the almost 200 missing records. This just seems intollerable. How can I do business this way? Migrating to a new SQL Server 2017 server. Maybe this anomaly will disappear?
##VERSION = Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64)
EDIT: I changed the storage type in my local copy of the table [CourseNbr] from nvarchar(20) to varchar(10) and now the 10-digit string/numbers appear! And I can search for 10-character/digit records and they appear OK. Have I answered my own question? Why should that make a difference?
You can try this
Return varchar without leading zeros
SELECT CONVERT(varchar(20), CONVERT(int, [CourseNbr])) as CourseNbrWithNoLeadingZeros
FROM CourseNbrTable
Return int without leading zeros
SELECT CONVERT(int, [CourseNbr]) as CourseNbrWithNoLeadingZeros
FROM CourseNbrTable

Difference when casting a datetime to a decimal on different SQL servers

On two different sql servers I run the following query:
declare #myDatetime as datetime = '2017-07-04 23:42:32.400'
select CAST(#myDatetime AS DECIMAL(20,5))
I get two different results:
42918.98788 and 42918.98787
If I cast to a DECIMAL(20,6) it works fine (42918.987875) but let's say I need to put it in a decimal(20,5).
Where can I found the source of this difference in behaviour when rounding? Is it an option somewhere that rounds the final 5 up or down? Is it a sort of locale, international setting, collation or else?
Is it the different verions of SQL (12.0.5000.0 vs 13.0.4202.2)?
According to this document:
https://support.microsoft.com/en-us/help/4010261/sql-server-2016-improvements-in-handling-some-data-types-and-uncommon
Microsoft have made some changes to how it handles some "uncommon" conversions:
SQL Server 2016 includes improvements to the precision of the following operations under compatibility level 130:
Uncommon data type conversions. These include the following:
float/integer to/from datetime/smalldatetime
real/float to/from numeric/money/smallmoney
float to real
So I would suspect that might be what we see for the different rounding, in this specific situation.

MS SQL server - convert HEX string to integer

This answer to what looks like the same question:
Convert integer to hex and hex to integer
..does not work for me.
I am not able to go to a HEX string to an integer using MS SQL server 2005 CAST or CONVERT. Am I missing something trivial? I have searched extensively, and the best I can find are long-winded user functions to go from a hex string value to something that looks like a decimal int. Surely there is a simple way to do this directly in a query using built in functions rather than writing a user function?
Thanks
Edit to include examples:
select CONVERT(INT, 0x89)
works as expected, but
select CONVERT(INT, '0x' + substring(msg, 66, 2)) from sometable
gets me:
"Conversion failed when converting the varchar value '0x89' to data type int."
an extra explicit CAST:
select CONVERT(INT, CAST('0x89' AS VARBINARY))
executes, but returns 813185081.
Substituting 'Int', 'Decimal', etc for 'Varbinary' results in an error. In general, strings that appear to be numeric are interpreted as numeric if required, but not in this case, and there does not appear to be a CAST that recognizes HEX. I would like to think there is something simple and obvious and I've just missed it.
Microsoft SQL Server Management Studio Express 9.00.3042.00
Microsoft SQL Server 2005 - 9.00.3080.00 (Intel X86) Sep 6 2009 01:43:32 Copyright (c) 1988-2005 Microsoft Corporation Express Edition with Advanced Services on Windows NT 5.1 (Build 2600: Service Pack 3)
To sum up: I want to take a hex string which is a value in a table, and display it as part of a query result as a decimal integer, using only system defined functions, not a UDF.
Thanks for giving some more explicit examples. As far as I can tell from the documentation and Googling, this is not possible in MSSQL 2005 without a UDF or other procedural code. In MSSQL 2008 the CONVERT() function's style parameter now supoprts binary data, so you can do it directly like this:
select convert(int, convert(varbinary, '0x89', 1))
In previous versions, your choices are:
Use a UDF (TSQL or CLR; CLR might actually be easier for this)
Wrap the SELECT in a stored procedure (but you'll probably still have the equivalent of a UDF in it anyway)
Convert it in the application front end
Upgrade to MSSQL 2008
If converting the data is only for display purposes, the application might be the easiest solution: data formatting usually belongs there anyway. If you must do it in a query, then a UDF is easiest but the performance may not be great (I know you said you preferred not to use a UDF but it's not clear why). I'm guessing that upgrading to MSSQL 2008 just for this probably isn't realistic.
Finally, FYI the version number you included is the version of Management Studio, not the version number of your server. To get that, query the server itself with select ##version or select serverproperty('ProductVersion').

SQL Server: Must numbers all be specified with latin numeral digits?

Does SQL server expect numbers to be specified with digits from the latin alphabet, e.g.:
0123456789
Is it valid to give SQL Server digits in other alphabets?
Rosetta Stone:
Latin: 01234567890
Arabic: ٠١٢٣٤٥٦٧٨٩
Bengali: ০১২৩৪৫৬৭৮৯
i know that the client (ADO) will convert 8-bit strings to 16-bit unicode strings using the current culture. But the client is also converting numbers to strings using their current culture, e.g.:
SELECT * FROM Inventory
WHERE Quantity > ২৩৪,৭৮
Which throws SQL Server for fits.
i know that the server/database has it's defined code page and locale, but that is for strings.
Will SQL Server interpret numbers using the active (or per-login specified) locale, or must all numeric values be specifid with latin numeral digits?
From what I can tell, T-SQL requires latin digits, and decimal points specified as ..
Neither ISNUMERIC() nor CAST() can successfully test these digits, so a numeric constant using those characters would not work either.
Allowing a client to pass non-Latin digits sounds dangerously promiscuous (I'm not sure what path your data travels, but there seems to be a potential for SQL injection if user's localized input isn't being tested to be numeric.

Connecting to SQL Server with CL-SQL via unixODBC/FreeTDS

I've managed to connect from SBCL running on debian to an SQL Server 2000 instance over the network using FreeTDS/unixODBC.
I can actually get data back from the server, so all is working.
However, many of the columns trigger what seem to be unsupported data types a-la:
The value 2147483647 is not of type FIXNUM.
and
-11 fell through ECASE expression.
Wanted one of (-7 -6 -2 -3 -4 93 92 91 11 10 ...).
Anyone have experience using CLSQL with SQL Server would be able to help out?
This (error with 2147483647) occurs because the FreeTDS driver doesn't handle OLEDB BLOBs so well.
You have to issue the following SQL command to make it work:
set textsize 102400
You can see the FreeTDS FAQ entry here. Excerpt:
The text data type is different from char and varchar types. The maximum data length of a text column is governed by the textsize connection option. Microsoft claims in their documentation to use a default textsize of 4000 characters, but in fact their implementation is inconsistent. Sometimes text columns are returned with a size of 4 GB!
The best solution is to make sure you set the textsize option to a reasonable value when establishing a connection.
As for the ECASE expression, I haven't really solved it but I have hacked it away by doing a data conversion of timestamp into a binary value, and a uniqueidentifier into a varchar(36).

Resources