Cast XML to money - sql-server

I have some XML data that I need to add up as currency. Every conversion I try gets the error
Explicit conversion from data type xml to ____ is not allowed.
Here's a simple example, containing several failed attempts.
DECLARE #xmlstuff xml
SET #xmlstuff = '3'
SELECT
CAST (#xmlstuff AS varchar(80)) as worksButDontCare,
--CAST (#xmlstuff AS MONEY) as dollars, -- Explicit conversion from data type xml to money is not allowed.
--CAST (#xmlstuff AS NUMERIC) as number, -- Explicit conversion from data type xml to numeric is not allowed.
--CONVERT (decimal(18,2),#xmlstuff ) AS cd1_feeAmount, -- Explicit conversion from data type xml to decimal is not allowed.

The answer that I found is to convert to varchar as an intermediate step.
CAST ((CAST (#xmlstuff AS varchar(80))) AS MONEY) AS xmlToVarcharToMoney

TSQL does not allow for direct conversion from xml to any numeric type.
So, as #incircuitous pointed, you will have to convert first to text, and then to Money
For more information about TSQL data type conversion, look for the big table on MSDN.

The conversion table in MSDN is indeed useful for reference, +1 for #GabrielRainha.
To get value out of XML data type I would recommend to look into XML specific methods, namely value() for this particular case :
DECLARE #xmlstuff xml
SET #xmlstuff = '3'
SELECT #xmlstuff.value('.', 'money') as dollars
SQL Fiddle
The 2nd parameter of value() is the data type of return value. And the first parameter is XQuery expression to locate the value within XML structure. Assuming you don't have any structure in the XML -simply the value, because of which you expect it to be convertible directly using CAST-, you can always pass . as the 1st parameter.

Related

How do I convert a varchar containing a number in scientific notation to a numeric in SQL Server?

I made some calculations using function and get the following value. I want to divide this value with 1000.
1.83673e+006
I want to convert the value into numeric.
When I try to convert it to numeric it throws
Error converting data type nvarchar to numeric.
Is it possible to convert this value to numeric? Please help me to get this.
Thanks in advance
try it
SELECT CONVERT(numeric(16,0), CAST(1.83673e+006 AS FLOAT))
In SQL Server, scientific notation (...+e...) is only used for floating-point data types, not for decimal/numeric data types.
Thus, SQL Server recognizes this format only when converting to a floating-point data type (such as float or real), not when converting directly to numeric.
Obviously, nothing prevents you from converting the value to float first and then to numeric:
SELECT CONVERT(numeric(19,4), CONVERT(float, '1.83673e+006'))
yields 1836730.0000.
Just try this
Declare #data varchar(100)='1.83673e+006'
SELECT #data=CAST(CAST( #data AS float) AS NUMERIC)/1000
SELECT #data Result
Result
1836.730000

Conversion failed when converting the varchar value '12/31/'

I have the following code:
declare #StartDate date
declare #EndDate date
set #StartDate='09/01/2016'
set #EndDate='11/30/2016'
SELECT
1 AS Segment,
'C' AS Subsegment,
100 AS Ent,
'KPAR' AS LOB,
'ATLB' AS Cov,
ClaimNumber AS [Claim#],
'12/31/'+AccidentYear AS AYDate,
convert(date, cast(AccountingPeriodDate as date),101) AS EvalDate
However I get an error
Conversion failed when converting the varchar value '12/31/' to data type int.
I haven't gotten this error before, and was wondering it it's due to a datatype change.
First, you should use ISO standard date formats, such as YYYYMMDD and YYYY-MM-DD.
Then, be explicit about the conversion and use try_convert(). So, I would write this as:
select try_convert(date, concat(accident_year, '1231'))
concat() will automatically convert the number to a date.
Or, alternatively, use datefromparts():
select datefromparts(accident_year, 12, 31)
This is probably the simplest solution.
Probably need to cast accidentyear as varchar
DECLARE #accidentyear AS INT
SET #accidentyear = 2016
SELECT '12/31/' + CAST(#accidentyear AS VARCHAR(4))
try this:
SELECT 1 AS Segment
,'C' AS Subsegment
,100 AS Ent
,'KPAR' AS LOB
,'ATLB' AS Cov
,ClaimNumber AS [Claim#]
,'12/31/'+ CAST(AccidentYear as nvarchar(4)) AS AYDate
,convert(date, cast(AccountingPeriodDate as date),101) AS EvalDate
The advice you got from other users to cast/convert accidentYear to varchar is correct. The reason this is necessary is because the data types are not the same. '12/31' is clearly a string. We also know that AccidentYear is an int because the error message says it's an int.
Since the data types are different, SQL Server attempts an implicit data type conversion. When SQL Server does this, the string is converted to an integer and then math is performed on it.
Since implicit conversion is not possible, you need to use explicit conversion instead. By using the cast or convert function, you are doing an explicit conversion.
The rules for implicit data type conversions can be found here: https://msdn.microsoft.com/en-us/library/ms190309.aspx?f=255&MSPPError=-2147217396

data conversion from varchar to decimal

I have a column with varchar data type. I need to convert it into decimal data type in sql server 2014?
For example, varchar value .0462500 into decimal 4.62500
I have seen some similar questions in so, but it didn't work for me.
Thank you for your time and help!
If you know that your VARCHAR variables will require roughly the same conversion rate, you could simply use the CAST() function to convert them and then perform the necessary multiplication :
SELECT CAST(YourValue AS DECIMAL(7,5)) * 100
Likewise the CONVERT() method will essentially accomplish the same thing via a different syntax :
SELECT CONVERT(DECIMAL(7,5),YourValue) * 100
You can use Cast or Convert functions.
Convert:
select convert(decimal(10,5),.0462500)*100
Cast:
select cast(.0462500 as decimal(10,5))*100
Note: If there is malformed data(data which can not be converted), you may need to use Try_Convert or Try_Parse functions instead.
Try_Convert:
select try_convert(decimal(10,5),.0462500)*100
Try_Parse:
select try_parse('.0462500' as decimal(10,5))*100

SQL Server User Defined Function taking arguments of any type like ISNULL

I need to create a user defined function that would operate similarly to ISNULL system function in the respect that it would accept arguments of any type and would return the value of the same type.
How is this done?
Using SQL_VARIANT as a datatype would not work as SQL_VARIANT values require explicit casting. ISNULL does the data type conversions implicitly.
How to declare the generic types that do not require explicit casting?
Let me make it clear. I am not looking to replicate the functionality of ISNULL function. I used ISNULL function as a pattern of a function that takes two arguments of any data type supported by SQL Server and returns the value of the same data type as the arguments.
There are other SQL Server functions that implement the same pattern: accept arguments which data type is not explicitly declared and to return the value of some other data type, which is also not explicitly declared at function definition. The examples are: NULLIF, CAST, CONVERT.
I am wondering how this pattern could be accomplished, because any UDF requires explicit definition of arguments and return value data types.
I just answered a question which is somehow related: https://stackoverflow.com/a/32985478/5089204
There is no secure way to deal with empty values. ISNULL is very good in most cases, but won't compile if you do not have both parameters of an implicitly convertable type.
Look how this is treated in XML. Just paste this into an empty query window and execute:
--The NULL-element is not there at all
SELECT 'text' AS filled
,'' AS empty
,NULL AS NotThere
FOR XML PATH('row');
--The NULL-element is rendered using "nil"
SELECT 'text' AS filled
,'' AS empty
,NULL AS NotThere
FOR XML PATH('row'),ELEMENTS XSINIL
--Look at this: Both columns are called "TheName". They are implicitly concatenated
SELECT 'a' AS TheName
,'b' AS TheName
FOR XML PATH('row')
--That leads to: Concatenate nothing with an empty string will at least return the empty string.
--this is other/better than ISNULL, because it will work with any type...
SELECT NULL AS TheName
,'' AS TheName
FOR XML PATH('row')
--now an example with table data
DECLARE #tbl TABLE(int1 INT, int2 INT);
INSERT INTO #tbl VALUES(NULL,1); --first value is null
--int1 is swallowed
SELECT *
FROM #tbl
FOR XML PATH('row')
--both elements are there
SELECT int1, '' AS int1 --ISNULL(int1,'') would not compile here...
,int2, '' AS int2
FROM #tbl
FOR XML PATH('row')
--This is the result of the last example: Look what happens to the empty int element, its Zero!
--This is the way this is handled in XML conversions. Try it with other types (like 'date' [result is 1900-01-01] or any other type)...
DECLARE #a XML='<row><int1></int1><int2>1</int2></row>';
SELECT a.b.value('int1[1]','int') AS int1
,a.b.value('int2[1]','int') AS int2
FROM #a.nodes('/row') a(b)

Converting DBCLOB/CLOB to XML

We are facing a problem in converting/casting DBCLOB to XML.
Background
We are storing some xml data in a column of type DBCLOB (1073741823). For one of our requirements, we have to convert this data to XML type so that we can take advantage of Xquery to filter the result. For doing this conversion, we are using the following SQL query to convert DBCLOB to XML data type.
SELECT XMLCAST (XMLPARSE (DOCUMENT (CAST (CAST (COLUMN1 AS DBCLOB(32672)) AS VARCHAR (32672)))) AS XML from TABLE1
Problem
For some scenario the size of data in DBCLOB column is more than 32672
and, since we are converting DBCLOB to XML via VARCHAR, so the output
get limited to 32672, and XML conversion fails.
What would be the way to achieve this casting (clob to xml)
Thanks in advance
Actually i was casting it to varchar as XMLPARSE function was expecting a string expression.
After going through the documentation again, i converted it to blob and then to XML. It worked, the sample query which worked is given below for reference.
SELECT
XMLCAST (
XMLPARSE (
DOCUMENT CAST (
COLUMN1 AS BLOB
)
PRESERVE WHITESPACE
) as XML
)
FROM
TABLE1
Thanks for support
Any casting you perform in the database will be contstrianed by the limits of the data types you're using (e.g. varchar 32672 KB in your example).
Try using XMLSERIALIZE instead.

Resources