Float to varchar with style 3 is failing in sql server 2016 - sql

I am getting Arithmetic overflow error while executing following query on sql server 2016.
"select convert(varchar(20), cast('0' as float), 3)"
The same query works fine on sql server 2014.

you are getting this error cause casting '0' to float of style 3 returning 23 charter value which is unable to convert to varchar of length 20 only.
try something like,
select convert(varchar(23), cast('0' as float), 3)
Or
select convert(varchar(max), cast('0' as float), 3)

CONVERT ( data_type [ ( length ) ] , expression [ , style ] )
The same query works fine
on sql server 2014.
style in sql 2014
Other values are processed as 0.
A maximum of 6 digits. Use in scientific notation, when appropriate.
style in sql 2016
3 Always 17 digits. Use for lossless conversion. With this style, every distinct float or real value is guaranteed to convert to a
distinct character string.Applies to: Azure SQL Database, and starting in SQL Server 2016.
https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql

Related

SQL Convert & Cast Nvarchar Time to a decimal

I'm working on a legacy database and need to parse info from one database to another, parsing it into the new database is easy enough but first I need to create the query to convert and cast the following in the legacy SQL Server database:
WorkedHours(NVARCHAR(10)) is in text format 07:30
I need to convert and cast this as a decimal ie 7.5
I have searched around for the answer to this but can not find anything that has worked, so thought I would put it out there to see if any of you has any ideas.
Edit - What I should of asked is. What is causing an error converting to an int from a character with a value of 0 when trying to trying to convert and cast a time to a decimal?
DATEDIFF(
MINUTE,
0,
CAST('07:30' AS TIME)
)
/
60.0
Works up to '23:59' only
EDIT:
Based on a comment elsewhere, you have some 'bad' values.
This may find them...
SELECT
*
FROM
yourTable
WHERE
TRY_CONVERT(TIME, worked_hours) IS NULL
And as such, this is a safer version of my expression....
DATEDIFF(
MINUTE,
0,
TRY_CONVERT(TIME, worked_hours)
)
/
60.0
(Returns NULL for values that failed to parse.)
There's no reason to pull out the date/time types. Just do some simple string parsing:
cast(left(right('0' + WorkedHours, 5), 2) as int)
+ cast(right(WorkedHours, 2) as int) / 60.00
This won't have any limitations on 24 hours or anything like that. It just assumes that you've got one or two digits before a colon and two digits after.
This should work in SQL Server and an example-string "1101:56" (1101h & 56 minutes) | in general from 0h to >24h:
-- Take all hours before ":" and all Minutes (2 digits) after ":" and convert it to decimal.
select convert(decimal,left('1101:56',CHARINDEX(':','1101:56')-1)) + ( convert(decimal,right('1101:56',2))/60 );
-- with column-placeholder "time_str_from_table"
select convert(decimal,left(time_str_from_table,CHARINDEX(':',time_str_from_table)-1)) + ( convert(decimal,right(time_str_from_table,2))/60 );
If the source table have NULL-Values, than use "ISNULL" with substitution-value "0.0":
-- with column-placeholder "time_str_from_table"
select isnull( ( convert(decimal,left(time_str_from_table,CHARINDEX(':',time_str_from_table)-1)) + ( convert(decimal,right(time_str_from_table,2))/60) ), 0.0);

error of change a year date format on MS Access 2012 by running a SQL query

I am working on Access 2012 on win 7.
In a table, I need to change a year date format from '1-Jan-06' to 2006 and from '1-Jan-90' to 1990. I only need year.
This is my query
SELECT *,
CASE
WHEN CAST(right(year_date,2) , INT) <= 12
THEN 2000 + CAST(right(year_date,2) , INT)
ELSE 1900 + CAST(right(year_date,2) , INT)
END
FROM my_table;
I got error:
syntax error (missing operator) in the query expression of 'CASE -- END'.
Access SQL does not support CASE WHEN or CAST.
In Access, you can use IIf() and CInt() to do what you intended with CASE WHEN and CAST.
SELECT
IIf(CInt(Right(year_date, 2)) <= 12, 2000, 1900)
+ CInt(Right(year_date, 2))
FROM my_table;

Casting to Time in SQL fails after 1762 rows

(Updated followings comments)
I got a strange behaviour on SQL server 2012, this request is ok :
select top 2002 cast(myTimeStr as time) from tbWithTime
order by ID
but
select top 2003 cast(myTimeStr as time) from tbWithTime
order by ID
failed with
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
Whereas line 2002 and 2003 both equals to '14:30'
Then when i try to specifically cast this 2003 line, it succeeded.
My configuration :
Name Version
Microsoft SQL Server Management Studio 10.50.1600.1
Microsft SQL Server 2012 11.0.3339.0
To find the actual row(s) causing you issues, try this:
SELECT * FROM tbWithTime WHERE TRY_CONVERT(time,myTimeStr) IS NULL
TRY_CONVERT:
Returns a value cast to the specified data type if the cast succeeds; otherwise, returns null.
You could try this to find the funny rows:
select myTimeStr
from tbWithTime
where myTimeStr not like '[0-1][0-9][:][0-5][0-9]'
and myTimeStr not like '2[0-3][:][0-5][0-9]'
Or you could just select the valid rows:
select cast(myTimeStr as time)
from tbWithTime
where myTimeStr like '[0-1][0-9][:][0-5][0-9]'
or myTimeStr like '2[0-3][:][0-5][0-9]'

decimal to hex conversion in sql server 2008

the hex value of 2716455883 is A1E9D3CB but using
SELECT CONVERT(VARBINARY(8), 2716455883)
getting answer 0x0A000001CBD3E9A1
SELECT CONVERT(VARBINARY(8), cast(2716455883 as bigint))
It is due to the way SQL Server interprets literals without qualified types. Check this out
select sql_variant_property(2716455883, 'basetype'); -- numeric
select sql_variant_property(2716455883, 'precision'); -- 10
select sql_variant_property(2716455883, 'scale'); -- 0

SQL Server 2008: Varchar Conversion to Numeric Data Overflow, Probably Because Some Are Ranges

I'm working on a query with a varchar column called ALCOHOL_OZ_PER_WK. Part of the query includes:
where e.ALCOHOL_OZ_PER_WK >= 14
and get the errors:
Arithmetic overflow error converting varchar to data type numeric.
and:
Error converting data type varchar to numeric.
Looking into the values actually stored in the column, the largest look close to 100, but some of the entries are ranges:
9 - 12
1.5 - 2.5
I'd like to get the upper limit (or maybe the midpoint of the range) from rows with entries like this and have it be the value being compared to 14.
What would be the (or an) easy way to do this?
As always, thank you!
Your DB is obviously result of some survey, and it seems to contain the original survey data. The usual way is to run this through an ECCD (Extract, Clean, Conform, Deliver) process and store clean and standardized data into a separate database (maybe a warehouse) which can then be used for analytics and reporting.
If you have SSIS use data profiling task to get an idea of types of strings you have in there. The Column Pattern Profile reports a set of regular expressions on the string column, so you will get an idea of what's inside those strings. If you do not have SSIS, you can use eobjects DataCleaner to do the same.
If you can not spare a new database or at least a new table -- at minimum add a numeric column to this table and then extract numeric values form those strings into the new column. You may want to use "something else" (SSIS, Pentaho Kettle, Python, VB, C#) to do this -- in general T-SQL in not very good at string processing.
My guess is that this is not the only column that has garbage inside, so any analysis that you may run on this may be worthless.
And if you still think that the ranges are the only problem, this example may help:
First some data
DECLARE #myTable TABLE (
AlUnits varchar(10)
) ;
INSERT INTO #myTable
(AlUnits )
VALUES ( '10' )
, ( '15' )
, ( '20' )
, ( '7 - 12' )
, ( '3 - 5' )
;
The query splits records into two groups, numeric and not numeric -- assumed ranges.
;
WITH is_num
AS ( SELECT CAST(AlUnits AS decimal(6, 2)) AS Units_LO
,CAST(AlUnits AS decimal(6, 2)) AS Units_HI
FROM #myTable
WHERE ISNUMERIC(AlUnits) = 1
),
is_not_num
AS ( SELECT CAST( RTRIM(LTRIM(LEFT(AlUnits,
CHARINDEX('-', AlUnits) - 1)))
AS decimal(6,2)) AS Units_LO
,CAST(RTRIM(LTRIM(RIGHT(AlUnits,
LEN(AlUnits)
- CHARINDEX('-', AlUnits))))
AS decimal(6,2)) AS Units_HI
FROM #myTable
WHERE ISNUMERIC(AlUnits) = 0
)
SELECT Units_LO
,Units_HI
,CAST(( Units_LO + Units_HI ) / 2.0 AS decimal(6, 2)) AS Units_Avg
FROM is_num
UNION ALL
SELECT Units_LO
,Units_HI
,CAST(( Units_LO + Units_HI ) / 2.0 AS decimal(6, 2)) AS Units_Avg
FROM is_not_num ;
Returns:
Units_LO Units_HI Units_Avg
----------- ----------- ----------
10.00 10.00 10.00
15.00 15.00 15.00
20.00 20.00 20.00
7.00 12.00 9.50
3.00 5.00 4.00
Not sure about easy ways.
A proper way is to store the numbers in two columns, ALCOHOL_OZ_PER_WK_MIN and ALCOHOL_OZ_PER_WK_MAX.
As you say you need to calculate numeric values, which you can then use in your query.
Probably the easiest way is to use some simple logic to calculate the average or upper limit using string functions, and string to numeric functions.
If all you want is the upper limit, just get the characters after the '-' and use that.
"probably because some are ranges" - do you get that "range" is not a SQL Server Data type? You've got non-numeric data you're trying to convert into numeric data, and you've got a scalar value you're comparing to a non-scalar value.
This database has some issues.