Sybase convert issue from float to varchar - sql

First, I need to mention that my current sybase db version is Adaptive Server Enterprise 12.5.4. I aim to convert float data type into varchar via sybase convert function in order to concat several of these kinds of variables, format and store in string type.
Unfortunately, it is not the case. Simply using convert(varchar(20), float_var) or cast() function cannot correctly return the precise value.
For example, ...
declare #float_var float
begin
select #float_var =345.1237 --from table actually
select convert(varchar(20),#float_var) --return 345.1236999999
end
The incorrect string results returned occasionally have 99999 or 00001 suffix.
I tried many function including specify the precision, but there are still several cases not working on it. The sybase internal function does not exactly work on it.
I suppose this is a gerneral issue while using Sybase DB, however few answer found in serach. During my past experience, Sybase store procedure gammer always has sort of tolerance in runtime and internal fix when error encounter. This issue make me confused how Sybase works internally. Any advice would be appreciated, thanks in advance.

there are a couple of possible solutions for this.
firstly, let's try to convert the float to decimal first, then to varchar.
select cast(cast(#float_var as decimal(13,4)) as varchar)
alternatively, and this is where my ASE memory might fail me a little, would be to use the STR function like so:
Select ltrim(str(#float_var, 25, 5))
You have to TRIM the output as the STR function padding empty spaces on to the left of the result

this works for me:
declare #float_var float
begin
select #float_var = 96.332
select cast(cast(#float_var as decimal(13,4)) as varchar) -- Returns 96.3320
end
declare #float_var float
begin
select #float_var = 345.1237
select cast(cast(#float_var as decimal(13,4)) as varchar) -- Returns 345.1237
end

Related

Roundoff error in sql

DECLARE #TAX VARCHAR(30)=120.45
DECLARE #TaxRoundOf VARCHAR(30)
SET #TaxRoundOf=ROUND(#TAX,1)
SELECT #TaxRoundOf
This Gives Result (#TaxRoundOf=120.5)
DECLARE #TAX VARCHAR(30)=146.45
DECLARE #TaxRoundOf VARCHAR(30)
SET #TaxRoundOf=ROUND(#TAX,1)
SELECT #TaxRoundOf
This Gives Result (#TaxRoundOf=146.4)
But I need to return 146.50 . why this mismatch between two results?
any one can help plz?
Since you are using VARCHAR to store your numbers, SQL Server is having to do implicit conversion to float behind the scenes, which is having knock on effects on your calculations. You can reproduce this using the below query:
SELECT ROUND(CONVERT(FLOAT, 120.45),1), -- 120.5
ROUND(CONVERT(FLOAT, 146.45),1), -- 146.4
ROUND(CONVERT(DECIMAL(10, 2), 120.45),1), -- 120.50
ROUND(CONVERT(DECIMAL(10, 2), 146.45),1) -- 146.50
Since floating point numbers are not exact, 146.45 cannot be exactly represented as a float, and ends up being stored as a very slightly smaller number, so when this is passed to the round function, it is rounded down, instead of up.
The solution, as demonstrated by the 3rd and 4th columns in the above query, is to use a more precise data type.
You can use this:
SET #TaxRoundOf=ROUND(10 * CAST(#TAX AS FLOAT)) / 10
instead of:
SET #TaxRoundOf=ROUND(#TAX,1)
DEMO
PS as #GarethD already mentioned I wouldn't use #TAX as VARCHAR type.
You can also rely on numeric rounding instead of converting your string to a float, which can lose information.
Cast a string to numeric and then round:
select round(cast('146.45' as numeric(18,2)), 1)
-- 146.50
A decimal constant is already a decimal so there's no need to cast it:
select round(146.45, 1)
-- 146.50

Can I convert centigrade to farenheit in a query (not a function)

In Oracle I can convert centigrade to farenheit in an SQL query, see below. It seems SQL Server does not have full regex functionality. Is it possible to do this without dropping into a function, which I currently do?
(UNISTR('00B0') is the degree symbol we use)
The requirement is for any string that contains [digits]°C to be converted to same string with [new_digits]°F.
SELECT replace(replace(v_text_f,replace(regexp_substr(v_text_f,'\-? [[:digit:]]+\.?[[:digit:]]*'||UNISTR('\00B0')||'C'),UNISTR('\00B0')||'C'),
replace(regexp_substr(v_text_f,'\-?[[:digit:]]+\.?[[:digit:]]*'||UNISTR('\00B0')||'C'),UNISTR('\00B0')||'C')*9/5+32||UNISTR('\00B0')||'F'),
UNISTR('\00B0')||'F'||UNISTR('\00B0')||'C',UNISTR('\00B0') ||'F')
FROM (SELECT '38'||UNISTR('\00B0')||'C' as v_text_f FROM DUAL)
Try this, comparing to Oracle code, extremely simplified version:
DECLARE #C nvarchar(10) = '38'+CHAR(0x00B0)+'C' --38°C
SELECT CONVERT(nvarchar(10),CONVERT(int ,LEFT(#C, CHARINDEX(CHAR(0x00B0), #C)-1))*9/5+32)+CHAR(0x00B0)+'F'
--100°F

How to compare two different data type variables in where condition of SQL query

I have one column which is integer in first table and second is varcha. Now I need to compare these 2 variables which are of different data types and retrieve data if it matches.
Please could please help me out how to work on this?
Please specify which DBMS you're using please.
Sql Server?
CAST / CONVERT
EDIT:
Well, I see you mentioned Sql*Plus above which to me says Oracle so for the sake of thoroughness. CAST appears to be what you're looking for. CONVERT does something a bit different in Oracle so you'd be doing something like
CAST(#YourStringValue AS INTEGER) = #YourOtherIntegerValue
or whatever datatype you want to cast your column to and then compare it against your other value. The syntax may be off a bit as I'm no Oracle guy but this should point you in the right direction.
If it is about MS SQL, then it will cast those for you implicitly, no need to cast or convert.
declare #IntVariable int
set #IntVariable = 3
declare #VarcharVariable varchar(10)
set #VarcharVariable = '3'
select case when #IntVariable = #VarcharVariable then 1 else 0 end
You can either cast varchar to int or int to varchar and then compare.
Short example of casting:
CAST(ColumnName as datatype)as CertainName
Here CertainName means u can show that to display as your new column name
if yo are using c# java or other strict type programming languase then you will have to convert the int type into string then you will be able to compare them if you are using PHP then no conversion will be required

SQL Convert float to comma varchar with decimals

I have a couple floats that are kinda big. They're around a 100 million.
I would like this number to show like the following 123,456,789.01234
I've found that I can use CONVERT if its a money datatype but this doesn't do the full trick (it leaves off some decimal places).
I have to have commas on the left and five decimal places on the right.
Is there any built in SQL function to help with this? Or do I have to write a custom function?
Thanks
*** Update
I forgot to mention that I'm just displaying these as varchars. So there isn't any calculations after this.
This is running on an SQL database so MySQL and Oracle won't work.
DECLARE #f FLOAT
SET #f = 123456789.01234
SELECT LEFT('$' + CONVERT(VARCHAR(20), CAST(#f AS MONEY), 1), LEN(#f) - 2)
this will cut it up to two places of decimal for formatting. You can change LEN(#f) - 2 to modify this setting.
if you are just displaying this as text you can do the following:
oracle :
select to_char(123456789.01234,'999,999,999.99999') from dual; => 123,456,789.01234
MySQL :
select format(123456789.01234,5) => 123,456,789.01234<br>
the MySQL function rounds

Converting a String to HEX in SQL

I'm looking for a way to transform a genuine string into it's hexadecimal value in SQL. I'm looking something that is Informix-friendly but I would obviously prefer something database-neutral
Here is the select I am using now:
SELECT SomeStringColumn from SomeTable
Here is the select I would like to use:
SELECT hex( SomeStringColumn ) from SomeTable
Unfortunately nothing is that simple... Informix gives me that message:
Character to numeric conversion error
Any idea?
Can you use Cast and the fn_varbintohexstr?
SELECT master.dbo.fn_varbintohexstr(CAST(SomeStringColumn AS varbinary))
FROM SomeTable
I'm not sure if you have that function in your database system, it is in MS-SQL.
I just tried it in my SQL server MMC on one of my tables:
SELECT master.dbo.fn_varbintohexstr(CAST(Addr1 AS VARBINARY)) AS Expr1
FROM Customer
This worked as expected. possibly what I know as master.dbo.fn_varbintohexstr on MS-SQL, might be similar to informix hex() function, so possibly try:
SELECT hex(CAST(Addr1 AS VARBINARY)) AS Expr1
FROM Customer
The following works in Sql 2005.
select convert(varbinary, SomeStringColumn) from SomeTable
Try this:
select convert(varbinary, '0xa3c0', 1)
The hex number needs to have an even number of digits. To get around that, try:
select convert(varbinary, '0x' + RIGHT('00000000' + REPLACE('0xa3c','0x',''), 8), 1)
If it is possible for you to do this in the database client in code it might be easier.
Otherwise the error probably means that the built in hex function can't work with your values as you expect. I would double check the input value is trimmed and in the format first, it might be that simple. Then I would consult the database documentation that describes the hex function and see what its expected input would be and compare that to some of your values and find out what the difference is and how to change your values to match that of the expected input.
A simple google search for "informix hex function" brought up the first result page with the sentence: "Must be a literal integer or some other expression that returns an integer". If your data type is a string, first convert the string to an integer. It looks like at first glance you do something with the cast function (I am not sure about this).
select hex(cast SomeStringColumn as int)) from SomeTable
what about:
declare #hexstring varchar(max);
set #hexstring = 'E0F0C0';
select cast('' as xml).value('xs:hexBinary( substring(sql:variable("#hexstring"), sql:column("t.pos")) )', 'varbinary(max)')
from (select case substring(#hexstring, 1, 2) when '0x' then 3 else 0 end) as t(pos)
I saw this here:
http://blogs.msdn.com/b/sqltips/archive/2008/07/02/converting-from-hex-string-to-varbinary-and-vice-versa.aspx
Sorrry, that work only on >MS SQL 2005
OLD Post but in my case I also had to remove the 0x part of the hex so I used the below code. (I'm using MS SQL)
convert(varchar, convert(Varbinary(MAX), YOURSTRING),2)
SUBSTRING(CONVERT(varbinary,Addr1 ) ,1,1) as Expr1