I am having some issues dealing with numeric columns and data stored in tables. The columns are of type Number(14,2). If there are any decimal digits in numbers (like 1234.65) then it works fine. But when the numbers like 1234.00 are stored the decimal zeroes are removed when stored in tables. Another case is when numbers like 1234.50 are stored it stores as 1234.5
This is causing issue when I am retrieving the values, it is not consistent when it is displayed on User screens. We are handling the decimal digits based on flag whether to display or not. When chosen to display the number wont align because of this mismatch stored in database. The UI would display like this.
0
0
14922.9
14922.9
14922.93
But I want it to look like this if I wanted to show values after decimal point -
0.00
0.00
14922.90
14922.90
14922.93
This can be fixed on UI side, but the problem is every application using this table has to fix on its own UI part. We have a SQL view which is reading this table.
So I was wondering if there a way to fix this from SQL side and can be handled in SQL view query.
Any help is appreciated.
You can use the number format when select the values:
SELECT TO_CHAR(number, '90.99')
FROM DUAL;
http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements004.htm#SQLRF51075
Let's cast first before using the string function to make sure we have correct numeric type.
SELECT TO_CHAR(CAST(0 AS NUMERIC(10,2)), '9999999999990.99') AS output
FROM dual;
Related
I am trying to insert data from a staging table into the master table. The table has nearly 300 columns, and is a mix of data-typed Varchars, Integers, Decimals, Dates, etc.
Snowflake gives the unhelpful error message of "Numeric value '' is not recognized"
I have gone through and cut out various parts of the query to try and isolate where it is coming from. After several hours and cutting every column, it is still happening.
Does anyone know of a Snowflake diagnostic query (like Redshift has) which can tell me a specific column where the issue is occurring?
Unfortunately not at the point you're at. If you went back to the COPY INTO that loaded the data, you'd be able to use VALIDATE() function to get better information to the record and byte-offset level.
I would query your staging table for just the numeric fields and look for blanks, or you can wrap all of your fields destined for numeric fields with try_to_number() functions. A bit tedious, but might not be too bad if you don't have a lot of numbers.
https://docs.snowflake.com/en/sql-reference/functions/try_to_decimal.html
As a note, when you stage, you should try and use the NULL_IF options to get rid of bad characters and/or try to load them into stage using the actual datatypes in your stage table, so you can leverage the VALIDATE() function to make sure the data types are correct before loading into Snowflake.
Query your staging using try_to_number() and/or try_to_decimal() for number and decimal fields of the table and the use the minus to get the difference
Select $1,$2,...$300 from #stage
minus
Select $1,try_to_number($2)...$300 from#stage
If any number field has a string that cannot be converted then it will be null and then minus should return those rows which have a problem..Once you get the rows then try to analyze the columns in the result set for errors.
I have a database lookup step that is retrieving 3 fields from a SQL Server table. One of the fields is a decimal (8,6). When retrieved, the field values appear to be integers, losing all decimal places. I have spent several hours trying to resolve this issue and have found a reference to using an alter step to ensure the decimal places are available.
In the database lookup step I have tried different data types (number, string etc.) and I've followed this with a select values step, where I'm altering the field to a number field with decimal places. Nothing has worked, so any help with what I'm sure should be a simple problem to solve would be greatly appreciated. Apologies if the answer is obvious and I've missed it.
The Group By step has a similar issue when the Sum function is used, it uses a new mask that rounds up the number, thuough in the Group By case it is just a mask. I usually fix it using a Select Values step, altering the meta-data to Number, precision 2, format 0.00 and expliciting the decimal sign, like so:
Note that the decimal sign shown in the format does not alter the decimal sign to a dot, it's just a mask.
I am having to create a second header line and am using the first record of the Query to do this. I am using a UNION All to create this header record and the second part of the UNION to extract the Data required.
I have one issue on one column.
,'Active Energy kWh'
UNION ALL
,SUM(cast(invc.UNITS as Decimal (15,0)))
Each side are 11 lines before and after the Union and I have tried all sorts of combinations but it always results in an error message.
The above gives me "Error converting data type varchar to numeric."
Any help would be much appreciated.
The error message indicates that one of your values in the INVC table UNITS column is non-numeric. I would hazard a guess that it's either a string (VARCHAR or similar) column or something else - and one of the values has ended up in a state where it cannot be parsed.
Unfortunately there is no way other than checking small ranges of the table to gradually locate the 'bad' row (i.e. Try running the query for a few million rows at a time, then reducing the number until you home in on the bad data). SQL 2014 if you can get a database restored to it has the TRY_CONVERT function which will permit conversions to fail, enabling a more direct check - but you'll need to play with this on another system
(I'm assuming that an upgrade to 2014 for this feature is out of the question - your best bet is likely just looking for the bad row).
The problem is that you are trying to mix header information with data information in a single query.
Obviously, all your header columns will be strings. But not all your data columns will be strings, and SQL Server is unhappy when you mix data types this way.
What you are doing is equivalent to this:
select 'header1' as col1 -- string
union all
select 123.5 -- decimal
The above query produces the following error:
Error converting data type varchar to numeric.
...which makes sense, because you are trying to mix both a string (the header) with a decimal field.
So you have 2 options:
Remove the header columns from your query, and deal with header information outside your query.
Accept the fact that you'll need to convert the data type of every column to a string type. So when you have numeric data, you'll need to cast the column to varchar(n) explicitly.
In your case, it would mean adding the cast like this:
,'Active Energy kWh'
UNION ALL
,CAST(SUM(cast(invc.UNITS as Decimal (15,0))) AS VARCHAR(50)) -- Change 50 to appropriate value for your case
EDIT: Based on comment feedback, changed the cast to varchar to have an explicit length (varchar(n)) to avoid relying on the default length, which may or may not be long enough. OP knows the data, so OP needs to pick the right length.
We have SQL Server 2000 database with money data type columns and we have strange problem with numbers within money columns in which we store numbers with 2 decimal places. For o long time everything was OK. But now I see that in some rows where was number 47.22 is now number 47.2178. When i select CAST(COLUMN as CHAR) result is 47.22 but when i retrieve value from ADO recordset i have result 47.2178. I browse all application if there is any place where it can write number with 4 decimal places and find nothing(and in application history log there are records that application writes 47.22 to database). Can it be some SQL Server problem?
edit:application is written in VB6
Are you actually using the money data type or are you using a floating point type?
What happens when you use enterprise manager to select from that table? Does everything look ok?
My guess is that you are converting the data to a floating point type somewhere along the way. Probably in the ADO code.
UPDATE
Per MS: When casting money to a string type, the machine's locale comes into play. Which is why it is rounded to 2 decimal places.
You have three options.
First cast the money type to an equivalent decimal then cast that result to a char
Change the machines Regional Settings to default to the format you want.
Don't use the money data type to begin with, just use a decimal.
Don't use Enterprise Manager to draw any conclusions on what is really stored in your tables. EM has sometimes its own opinion on how to interpret data.
Looking at your CAST(....to CHAR) the reason is explained in the documentation (look for CAST & CONVERT)...
The following table shows the values
for style that can be used for
converting money or smallmoney to
character data.
Value Output
0 (default) No commas
every three digits to the left of the
decimal point, and two digits to the
right of the decimal point; for
example, 4235.98.
1 Commas every
three digits to the left of the
decimal point, and two digits to the
right of the decimal point; for
example, 3,510.92.
2 No commas
every three digits to the left of the
decimal point, and four digits to the
right of the decimal point; for
example, 4235.9819.
EDIT: Finally figured out how to use the BlockQuote feature. :-)
I'm working on a query which returns numeric values (currency). Some of the values are whole numbers and are being displayed as 3, 5, 2 etc whilst other numbers are coming up like 2.52, 4.50 etc.
How can I force oracle to always show the decimal places?
Thanks
TO_CHAR(pAmount, '9,999,999.99');
http://www.techonthenet.com/oracle/functions/to_char.php
http://www.ss64.com/orasyntax/to_char.html
To enhance the answers already given, you can use:
TO_CHAR(your_value,'fm999.99') to prevent leading spaces
____3.45 becomes 3.45 (_ indicates whitespace)
TO_CHAR(your_value,'fm990.99') to force values less than 1 to show a leading zero
.52 becomes 0.52
TO_CHAR(your_value,'fm990.00') to force 2 decimal places, even if 0
6.3 becomes 6.30
(TO_CHAR(your_value,'fm990.00')||'%') to add a percentage sign
18.6 becomes 18.60%
source: https://community.oracle.com/thread/968373?start=0&tstart=0
The display and formatting of the data should be handled at the presentation layer - not the data one.
Use the facilities provided by your front end to format the values as you see fit.
The to_char fixes the decimal issue but you have to be certain about the length. If it is longer than the format provided, it will show the number as ####. If the number is shorter, then it will leave spaces before the number. e.g
to_char(123.45),'99.00') will show ####
and
to_char(123.45),'999999.00') will show ' 123.45'.
So, if you have to export the results to CSV or Excel, these numbers will be treated as string.
So, I have not found any solution to it.
In SQL*Plus you can use the COLUMN directive to specify formatting on a per-column basis, separate from the query itself. That way you keep your query "clean" for possible other uses and still get your formatting. (In SQL*Plus at least...)
e.g
COLUMN SAL FORMAT 99,990.99
Google for "SQL*Plus User's Guide and Reference" and you should get links to the Oracle location for your Oracle version. 10.1 is here if that'll do. They'll probably all be about the same, mind you: I don't think SQL*Plus has changed much since I learned it in 1988 on Oracle 5.1.17...