Supress leading zeros from oracle table extract to a file - oracle

I am extracting data from oracle table to a text file and I have below number columns. When I select the below columns to a file it gives me all leading zeros which I wanted to suppress.
Select ltrim(col_1,'0'),ltrim(col_2,'0'),ltrim(col_3,'0') from table1
Datatype:
Col_1 ---NUMBER(10,2),
Col_2 ---NUMBER(38,0),
Col_3 ---NUMBER(15,1)
Current Output:
00000303.44|0| 00000000000008.2
00000000.00|26| 00000000000030.2
00000473.40|0| 00000000000010.0
Expected Output:
303.44|0|8.2
0|26|30.2
473.4|0|10
Please let me know if i need to change the datatype to get the Expected output. I even tried TO_CHAR(TRIM(LEADING 0 FROM col_name) i did not get the expected output.

This is caused by the datatypes set in the last output stage of your datastage job. When a column is set a decimal, datastage will fill the remaining positions with leading zeros up to the size if your decimal field.
The easiest way to get around this is to place a transform prior to the file output stage and convert all the columns to a varchar at the last stage trimming all the leading zeros.

Since the data is not in number and possibly in varchar/varchar2;
conversion is required; you can use to_number to address this;
Using one of your sample data in below case
select
to_number(00000000000008.2) as num1,
to_number('00000000000008.2') as chr1,
trim(00000000000008.2) as num2,
trim('00000000000008.2') as chr2,
ltrim(00000000000008.2,'0') as num3,
ltrim('00000000000008.2','0') as char3
from dual

Related

I have column with value (200ML) and I need to separate the (ML) from the column

I have column with value (200ML) and I need to separate the (ML) from the column !
I assume you mean that you want the leading numeric portion and the trailing alpha portion of the string '200ML' to be returned as separate columns. If that's correct you can use REGEXP_SUBSTR to do this:
SELECT REGEXP_SUBSTR(TEXT_STRING, '^[0-9]+', 1, 1) AS LEAD_NUMERIC,
REGEXP_SUBSTR(TEXT_STRING, '[A-Za-z]+$', 1, 1) AS TRAILING_ALPHA
FROM TABLE_A
db<>fiddle here

Oracle LPAD() function

Question: For every part description that begins with the letter β€œb”, list the part description, and then pad each part description with a β€œ+”on the left side so that all these part descriptions are 15 characters in length.
And I wrote like
SELECT
LENGTH(PART_PART_DESCRIPTION), LPAD(PART_PART_DESCRIPTION,15,'+'),
PART_PART_DESCRIPTION, CONCAT('+', PART_PART_DESCRIPTION) FROM PART
WHERE SUBSTR(PART_PART_DESCRIPTION,1,1)='B'
but the output doesn't show 15 of '+' on left side.
Here is the output table
Your column PART_PART_DESCRIPTION is of CHAR data type with 285 data length. so BLENDER in your column has a total 285 (7 + 278 trailing spaces) length. that is why you are facing the problem.
See this:
SQL> select LPAD(CAST('BLENDER' AS CHAR(285)),15,'+') FROM DUAL;
LPAD(CAST('BLENDER'ASCHAR(285)),15,'+')
------------------------------------------------------------
BLENDER
SQL> select LPAD('BLENDER',15,'+') FROM DUAL;
LPAD('BLENDER',
---------------
++++++++BLENDER
SQL>
You need to use TRIM to properly use the LPAD on CHAR datatype column Something like the following:
LPAD(trim(PART_PART_DESCRIPTION),15,'+')
Most probably your data is padded with spaces. Try this
SELECT
LENGTH(PART_PART_DESCRIPTION), LPAD(TRIM(PART_PART_DESCRIPTION),15,'+'),
PART_PART_DESCRIPTION, CONCAT('+', PART_PART_DESCRIPTION) FROM PART
WHERE SUBSTR(PART_PART_DESCRIPTION,1,1)='B'

Oracle 01481. 00000 - "invalid number format model"

This is my query i have used to get the value as money. Nut when concat value getting above exception. The query is
select to_char(b.balance,'9999.'||d.number_of_decimal_places) from balance b, decimal d
Am stuck with this problem.
If you have numeric number_of_decimal_places values like 1, 2, 3 etc. then you are constructing a format model like, for example, '9999.2' instead of '9999.99'.
You can convert that integer value to the format model with rpad or lpad:
select to_char(b.balance,'9999.'||rpad('9', d.number_of_decimal_places, '9'))
from balance b, decimal d
Or for trailing zeros:
select to_char(b.balance,'9999.'||rpad('0', d.number_of_decimal_places, '0'))
from balance b, decimal d
If you have string number_of_decimal_places values like '9', '99', '999' etc. then the concatenation you have will work unless you have an invalid value in one of the rows, which would be any character other than a 9 or a 0.
That includes spaces, which you could have in a varchar2 or char field. Either way you could remove those with trim:
select to_char(b.balance,'9999.'||trim(d.number_of_decimal_places))
from balance b, decimal d
But if you have any other characters then you will need to identify and correct the data in those rows; and even with spaces it would be better to fix the data if it's a varchar2 column.
It would be better to use new-style joins; I haven't changed these examples because it isn't clear if you are doing a cartesian product or have just omitted the join conditions.
If number_of_decimals returns a value like 2 then:
SELECT TO_CHAR( b.balance, RPAD( '9999.', 5 + d.number_of_decimals, '9' ) )
FROM balance b
CROSS JOIN
decimal d
For whatever reason, the concatenation of '9999.'||d.number_of_decimal_places is generating an invalid mask. We can only guess at the actual table values, presence of spaces, or whatever else may be causing issues with what it is doing.
So your solution is to run:
select '9999.'||d.number_of_decimal_places from decimal d
See what the actual format mask is that you are generating, and adjust as necessary.

Decimal place require in Oracle

case 1: SELECT TO_CHAR(12345.6789, '99999D99') FROM dual;
Output: 12345.67
case 2: SELECT TO_CHAR(12345.6789, '999D99') FROM dual;
Output: ######
case 3: SELECT TO_CHAR(12345, '99999D99') FROM dual;
Output: 12345.00
case 4: SELECT TO_CHAR(12345.1, '99999D99') FROM dual;
Output: 12345.10
Here Problem is if we don't know how many digits before decimal then how to manage for correct answer.[only case 1,3,4 can resolved using by TO_CHAR but how to solve for case 2.]
In this case the simplest answer might be to not supply a format model at all, but truncate or round the value to two decimal places:
SELECT TO_CHAR(ROUND(12345.6789, 2)) as rounded,
TO_CHAR(TRUNC(12345.6789, 2)) as truncated
FROM dual;
ROUNDED TRUNCATED
-------- ---------
12345.68 12345.67
From the documentation:
If you omit fmt, then n is converted to a VARCHAR2 value exactly long enough to hold its significant digits.
Otherwise you'd need to supply a format model that allowed for the maximum size of your number; if it's unrestricted you'd need 36 nines, the decimal separator, and two more nines. The result would be padded with spaces so you might also want to trim it, depending on how you'll use the string value.
SELECT TO_CHAR(12345.6789, '999999999999999999999999999999999999D99') as val
FROM dual;
VAL
----------------------------------------
12345.68
You could also do that flexibly by using the length of the truncated value (i.e. once the decimal places have been removed):
SELECT TO_CHAR(12345.6789,
lpad('9', length(trunc(12345.6789)), '9') || 'D99') as val
FROM dual;
VAL
---------
12345.68
But that seems unnecessarily complicated when you can let Oracle work it out for you.
However, if you want the decimals to show trailing zeros then you might need to use that method; but with zeros after the decimal separator:
SELECT TO_CHAR(12345.6, lpad('0', length(trunc(12345.6)), '9') || 'D00') as val
FROM dual;
VAL
---------
12345.60
... which addresses the 3rd and 4th cases you added. I've made it show a leading zero for values less than 1 as well; the generated format model in this case is '99990D00'. The number of nines will still vary depending on the size of your number.
By default Oracle still leaves a space at the start for a potential minus sign. You can avoid that with the FM format modifier:
SELECT TO_CHAR(12345.6, 'FM'
|| lpad('0', length(trunc(12345.6)), '9') || 'D00') as val
FROM dual;
VAL
--------
12345.60
You could always go with the maximum number of digits you expect to be present in the input. If there are fewer digits in the input than your format specifier, it wouldn't affect the outcome in anyway. For instance,
select to_char(12323.5553,'99999D99') from dual
would produce,
123.56
As you said, the length of the input is unknwon. So why would you use a fixed length formater for somthing that is unknown? Does not work. Read your input as String from the beginning and manipulate it as String or even better - BLOB.
Well, to do the rounding correct might be tricky.
So, best check your data if the numbers will realy get so big, because that would mean a lot of work and trouble.
If not more than 38 Digits are needed, you can go with decimal or numeric datatype and (if you insist on a formatter) use the TM formatter for example.
SELECT to_char(cast(1234.456 as decimal( *,2)), 'TM') as a FROM dual
or take the advice that was given above by the other posters.

oracle truncates the value after saving an id with precisions?

I have a table. it has a column with datatype NUMBER(38,20). it is an id column. out application generates the id. i am trying to insert record with an id value of 105.00010. but it inserts only 105.0001. May i know the reason why it is truncating one value(0). it porperly inserts records from 105.00001 to 105.00009. while inserting 105.00010 it is truncating. Please help me.
column size is **NUMBER(38,20)**
Thanks!
See the following test case:
WITH data_values
AS (SELECT 105.0001 AS test_val FROM dual
UNION ALL
SELECT 105.00010 AS test_val FROM dual)
SELECT test_val,
TO_NUMBER(test_val, '999.99999') AS NUM,
TO_CHAR(test_val, '999.99999') AS STR
FROM data_values;
Results in:
TEST_VAL NUM STR
105.0001 105.0001 105.00010
105.0001 105.0001 105.00010
The value after the final non zero digit is irrelevent to Oracle. Both your numbers are equivalent.
The rightmost zeros after the decimal are insignificant, so the value is not truncated, it is still the same value.
If you need it to stay the same you may need to treat the value as a varchar2.

Resources