I have a requirement to pull the Oracle db values to csv using SQL Plus to compare a numeric values which has a decimal point of 10 digits.
But the the numbers are rounding automatically to 8 decimal point. Is there any way we can disable the rounding of numbers in SQLPlus. Below find the details.
Here is my SQL Set commands.
SET UNDERLINE OFF
SET PAGESIZE 50000
SET NEWPAGE NONE
SET WRAP OFF
SET COLSEP , -- SEPARATE COLUMNS WITH A COMMA
SET FEEDBACK OFF
SET TRIMS ON
SET TRIMSPOOL ON
SET DEFINE ON
SET termout ON
SET verify ON
SET linesize 600
Can somebody help me on this.
Numeric values don't have any intrinsic format, so your client is deciding how to display them. I'm not sure which client is producing the 'DB' values, but the SQL*Plus ones are just using its defaults:
SQL*Plus normally displays numbers with as many digits as are required for accuracy, up to a standard display width determined by the value of the NUMWIDTH variable of the SET command (normally 10). If a number is larger than the value of SET NUMWIDTH, SQL*Plus rounds the number up or down to the maximum number of characters allowed if possible, or displays hashes if the number is too large.
So you see:
with your_table (x, y) as (
select -0.0224231886, -0.021470109 from dual
union all select -0.037164512, -0.0238026527 from dual
union all select 0.021786217, 0.044550243 from dual
union all select 0.0772262609, 0.0724136521 from dual
union all select 0.968632046, 0.0866250777 from dual
)
select x, y from your_table;
X, Y
-.02242319,-.02147011
-.03716451,-.02380265
.021786217,.044550243
.077226261,.072413652
.968632046,.086625078
You can change the default for your session with `set numf[ormat]', using a format model with enough digits before and after the decimal point to represent any number you might have stored, e.g.:
set numformat 990.99999999999
then the same query gets
X, Y
-0.0224231886, -0.0214701090
-0.0371645120, -0.0238026527
0.0217862170, 0.0445502430
0.0772262609, 0.0724136521
0.9686320460, 0.0866250777
Or you could implicitly modify it using set numw[idth]:
set numf ""
set numwidth 20
X, Y
-.0224231886, -.021470109
-.037164512, -.0238026527
.021786217, .044550243
.0772262609, .0724136521
.968632046, .0866250777
which gives you the precision you need, but doesn't show the leading zero. If that doesn't matter then this approach is simpler.
Perhaps you seek for column formating option to enforce column formating
COLUMN column_name FORMAT 999999.0000000000
Related
I can't convert char symbols with dot to number. I get exception
ORA-01481 invalid format mask
Which mask would work for me? I need unlimited number of characters before the dot.
The star or n symbol doesn't work
select to_number('840.11', '*.99') from dual
The behaviour of to_number depends on database or even session settings, so in order to be sure to convert it the way you need, you need to supply the numeric characters, like this:
select to_number('840.11', '999.99', ' NLS_NUMERIC_CHARACTERS = ''. ''') from dual
Now if you have a higher number of digits before the dot, you can simply enlarge the format mask, like this:
select to_number('234234840.11', '99999999999999.99', ' NLS_NUMERIC_CHARACTERS = ''. ''')
from dual
There is no direct way to specify a dynamic amount of digits before the dot, but there is some kind of workaround described here:
Dynamic length on number format in to_number Oracle SQL
You can build a fitting formatmask using TRANSLATE and then ROUND (or TRUNC) the solution of the transformation to your needed accuracy:
SELECT ROUND(TO_NUMBER('840.1155',TRANSLATE('840.1155', '123456789', '000000000')),2) FROM dual
=> 840.12
I have the following in Unix under my shell script:
SET linesize 2000
SET pagesize 50000
SET ECHO OFF
SET FEEDBACK OFF
SET VERIFY OFF
SET MARKUP HTML OFF
set numwidth 17
set colsep ","
select accountnum, cardnum, name, address, number from employee;
Once it generates the output in .csv, cardnum and accountnum becomes scientific like:
5.30706E+15
I want it to be:
501889176278289
I know how to change it in Excel but since I am sending these reports to a client. I want it to go to them in the correct format so they don't have to change anything.
I would suggest this:
SELECT TO_CHAR(accountnum,'9999999999999999999') accountnum
, TO_CHAR(cardnum,'9999999999999999999') cardnum
, name, address, number
FROM employee;
Except of TO_CHAR suggested in other answer you can try:
set numformat 9999999999999999999 that should solve your problem.
Another way is COLUMN accountnum FORMAT 9999999999999999999
when I execute the next SQL:
select 1/3 from dual;
the result is ,333333333
but the result that I expected was 0,333333333
Why doesn't oracle show the zero ? is there any parameter that can affect it?
Thanks
Edit: I checked this behaviour from an aplication that uses the oo4o (oracle object for ole), and confirmed with the sqlDeveloper (when I execute the sql with F5, not with ctrl+intro). The real problem is with the oo4o Dynaset object: when I try to sum the value of two fields, what I get is a concatenation, not a sum: ,3 + ,2 = ,3,2.
What I want to know is if there is some parameter or configuration that makes the oracle engine return the number without the zero, so I can turn on|off in order to return de zero as integer part.
SQL*Plus will show that by default (using your territory's decimal separator):
SQL> select 1/3 from dual;
1/3
----------
.333333333
You could use set numformat to change the behaviour:
SQL> set numformat "0D9999"
SQL> select 1/3 from dual;
1/3
-------
0.3333
... where the D represents the decimal separator. Or you could use column formatting, with a column alias:
SQL> set numformat ""
SQL> column answer format 0.000
SQL> select 1/3 as answer from dual;
ANSWER
------
0.333
Other clients have different ways of controlling the default output; SQL Developer behaves much the same, but PL/SQL Developer, Toad etc. might not.
Or you can format the number as part of the query, which isn't client-dpendent:
SQL> select to_char(1/3, '9990D99999') from dual;
TO_CHAR(1/3
-----------
0.33333
You need to provide enough digits for the integer part of whatever you're calculating though. Anything less than zero is simple, but if there are too many digits before the decimal separator then it won't display at all:
SQL> select to_char(100000/3, '9990D99999') from dual;
TO_CHAR(100
-----------
###########
My NLS settings:
NLS_SORT POLISH
NLS_COMP BINARY
Simple test query:
select * from (
select '11117' as x from dual
union
select '12988' as x from dual
union
select '14659' as x from dual
union
select '1532' as x from dual
union
select '18017' as x from dual
) order by x;
Actual result:
x
-----
11117
12988
14659
1532
18017
Desired result:
x
-----
1532
11117
12988
14659
18017
Question:
Is there a NLS setting that will help me achive desired result? I know I can do order by to_number(x) or, even better, order by lpad(x, 5), but it's not good in this case - I need a system-wide solution that won't require query change.
What I tried:
order by nlssort(x, 'nls_sort=binary');
alter session set nls_sort='binary';
Maybe a somewhat odd solution, but ...
Rename your TABLE_SOMETHING to TABLE_OTHER.
Create a view TABLE_SOMETHING on top of the TABLE_OTHER which will TO_NUMBER() the troubled string column of yours to the same column name.
If the table is, application-wide, being modified, then create INSTEAD OF triggers over the view TABLE_SOMETHING.
Recompile possibly invalidated packages.
Won't be particularly performant when it comes to modifying large quantities of records, won't allow for truncating the table, but it might solve the ordering problem.
I have a cursor which selects date from column with NUMBER type containg floating point numbers. Numbers like 4,3433 are returned properly while numbers smaller then 1 have removed leading zero.
For example number 0,4513 is returned as ,4513.
When I execute select used in the cursor on the database, numbers are formatted properly, with leading zeros.
This is how I loop over the recors returned by the cursor:
FOR c_data IN cursor_name(p_date) LOOP
...
END LOOP;
Any ideas why it works that way?
Thank you in advance.
You're confusing number format and number value.
The two strings 0.123 and .123, when read as a number, are mathematically equals. They represent the same number. In Oracle the true number representation is never displayed directly, we always convert a number to a character to display it, either implicitly or explicitly with a function.
You assume that a number between 0 and 1 should be represented with a leading 0, but this is not true by default, it depends on how you ask this number to be displayed. If you don't want unexpected outcome, you have to be explicit when displaying numbers/dates, for example:
to_char(your_number, '9990.99');
It's the default number formatting that Oracle provides.
If you want to specify something custom, you shall use TO_CHAR function (either in SQL query or PL/SQL code inside the loop).
Here is how it works:
SQL>
SQL> WITH aa AS (
2 select 1.3232 NUM from dual UNION ALL
3 select 1.3232 NUM from dual UNION ALL
4 select 332.323 NUM from dual UNION ALL
5 select 0.3232 NUM from dual
6 )
7 select NUM, to_char(NUM, 'FM999990D9999999') FORMATTED from aa
8 /
NUM FORMATTED
---------- ---------------
1.3232 1.3232
1.3232 1.3232
332.323 332.323
.3232 0.3232
SQL>
In this example, 'FM' - suppresses extra blanks, '0' indicates number digit including leading/trailing zeros, and '9' indicates digit suppressing leading/trailing zeros.
You can find many examples here:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34570