Oracle SQL My input should be the format mask in to_char(:n,'fm000') - sql

If my string has more length than 4 digits then my output is displayed as #######
For that the query is:
select to_char(:n,'fm0000') from dual;
It should take the number of zeros based on the input bind variables length after fm.
INPUT : 123
OUTPUT: 0123
INPUT : 123456789
OUTPUT: 0123456789
Zero should come before the number of input.
Any Suggestions!!

Edit - the OP changed the requirement completely.
The solution to the edited problem is trivial:
... '0' || to_char(:n)
End of edit - Original answer (to the question as originally posted) below.
It seems what you are trying to do is best achieved like this. Never mind the with clause, that is only for testing. Adapt as needed, and use enough nines in the format model to cover your longest inputs.
with
test_data ( n ) as (
select 3 from dual union all
select 19923 from dual
)
select n, to_char(n, 'fm99990000') as n_str
from test_data
;
N N_STR
------ --------
3 0003
19923 19923
2 rows selected.

According to documentation
If you omit fmt, then n is converted to a VARCHAR2 value exactly long
enough to hold its significant digits
so perhaps all you need is to_char(:n)

Based on your updated requirement, you can do this with a slight modification of #mathguy's original format mask manipulation; or with default conversion to a string and left-padding, or even more simly just prepending a single zero:
with t (n) as (
select 1 from dual
union all select 123 from dual
union all select 123456789 from dual
)
select n,
to_char(n, 'fm' || rpad('0', length(n) + 1, '0')) as n_str_1,
lpad(to_char(n), length(n) + 1, '0') as n_str_2,
'0' || to_char(n) as n_str_3
from t;
N N_STR_1 N_STR_2 N_STR_3
---------- ---------- ---------- ----------
1 01 01 01
123 0123 0123 0123
123456789 0123456789 0123456789 0123456789

If the field you are checking is a string:
case when substring(field, 1, 1)!=0 then '0'||field else field end
If it's a number you can always add a 0 as proposed by others:
'0'||to_char(field)

Related

Issues with SUBSTR function Oracle_SQL

I used the SUBSTR function for the similar purposes, but I encountered the following issue:
I am extracting 6 characters from the right, but the data in column is inconsistent and for some rows it has characters less than 6, i.e. 5 or 4. So for such rows, the function returns blanks. How can I fix this?
Example Scenario 1:
SUBSTR('0000123456',-6,6)
Output: 123456
Scenario 2 (how do I fix this?, I need it to return '23456'):
SUBSTR('23456',-6,6)
Output: ""
You can use a case expression: if the string length is strictly greater than 6 then return just the last 6 characters; otherwise return the string itself. This way you don't need to call substr unless it is really needed.
Alternatively, if speed is not the biggest issue and you are allowed to use regular expressions, you can write this more compactly - select between 0 and 6 characters - as many as possible - at the end of the string.
Finally, if you don't mind using undocumented functions, you can use reverse and standard substr (starting from character 1 and extracting the first 6 characters; that will work as expected even if the string has length less than 6). So: reverse the string, extract first (up to) 6 characters, and then reverse again to restore the order. WARNING: This is shown only for fun; DO NOT USE THIS METHOD!
with
test_data (str) as (
select '0123449389' from dual union all
select '00000000' from dual union all
select null from dual union all
select 'abcd' from dual
)
select str,
case when length(str) > 6 then substr(str, -6) else str end as case_substr,
regexp_substr(str, '.{0,6}$') as regexp_substr,
reverse(substr(reverse(str), 1, 6)) as rev_substr
from test_data
;
STR CASE_SUBSTR REGEXP_SUBSTR REV_SUBSTR
---------- ------------- ------------- --------------
0123449389 449389 449389 449389
00000000 000000 000000 000000
abcd abcd abcd abcd
One method uses coalesce():
select coalesce(substr('23456', -6, 6), '23456')
Another tweaks the length:
select substr('23456', greatest(- length('23456'), -6), 6)

SQL to shorten long integer to 4 or 5 character number with two decimal places

I'm trying to write SQL code to convert this 00004000000000000000000000000000 to this 40.00. And convert this 00025000000000000000000000000000 to this 250.00 Any help?
Here is what I have so far:
to_number(to_char(substr(trim(to_char(nvl(pre_tax,0),'00000000000000000000000000000000')),1,8),'9999999.99'))/100 as pre_tax,
trim(to_char(substr(to_char(nvl(pre_tax,0),'00000000000000000000000000000000'),9,8),'99999999'))/100000 as pre_tax_pct,
to_number(to_char(substr(trim(to_char(nvl(roth,0),'00000000000000000000000000000000')),1,8),'9999999.99'))/100 as roth_amt,
trim(to_char(substr(to_char(nvl(roth,0),'00000000000000000000000000000000'),9,8),'99999999'))/100000 as roth_pct
How about
SQL> WITH vals AS ( /* Test input */
2 SELECT '00004000000000000000000000000000' AS input_value FROM dual
3 UNION
4 SELECT '00025000000000000000000000000000' FROM dual
5 )
6 select to_char(input_value / 10E25, '999G990D00') result
7 from vals;
RESULT
-----------
40,00
250,00
SQL>
From your query attempt, it appears you have two fixed-format 32-character strings, called pre_tax and roth; and you want to extract the first 8-character and second 8-character chunks out from each, convert them to numbers, and present them as formatted text. The first chunk is supposed to represent six significant digits before the decimal point and two after; while the second has three digits before and five after the decimal. Probably...
So you could do that with:
-- CTE for sample data, including a second row with more digits
with your_table (pre_tax, roth) as (
select '00004000000000000000000000000000', '00025000000000000000000000000000' from dual
union all
select '12345678901234567890000000000000', null from dual
)
-- actual query
select to_char(nvl(to_number(substr(pre_tax, 1, 8)), 0) / 100, '999990D99') as pre_tax_amt,
to_char(nvl(to_number(substr(pre_tax, 9, 8)), 0) / 100000, '990D99999') as pre_tax_pct,
to_char(nvl(to_number(substr(roth, 1, 8)), 0) / 100, '9999990D99') as roth_amt,
to_char(nvl(to_number(substr(roth, 9, 8)), 0) / 100000, '990D99999') as roth_pct
from your_table;
PRE_TAX_AM PRE_TAX_PC ROTH_AMT ROTH_PCT
---------- ---------- ----------- ----------
40.00 0.00000 250.00 0.00000
123456.78 901.23456 0.00 0.00000
It's tough to see what your code's currently doing, but this will do what you're looking for (the last 'final_outp' column, the other columns just show how to build up to it).
WITH vals AS ( /* Test input */
SELECT '00004000000000000000000000000000' AS input_value FROM dual
UNION
SELECT '00025000000000000000000000000000' FROM dual
)
SELECT v.input_value,
/* Get the part of string that appears before decimal (first 6 characters) */
SUBSTR(v.input_value,0,6) AS part_before_decimal,
/* Get the part of string that appears after decimal (all characters after first 6) */
SUBSTR(v.input_value,6) AS part_after_decimal,
/* Add decimal character in between */
SUBSTR(v.input_value,0,6) || '.' || SUBSTR(v.input_value,6) AS char_string_with_decimal,
/* Convert string with decimal to numeric value */
to_number(
SUBSTR(v.input_value,0,6) || '.' || SUBSTR(v.input_value,6),
'999999.999999999999999999999999999'
) AS numeric_value,
/* Convert numeric value back to string in desired format, and trim leading spaces */
trim(
to_char(
to_number(
SUBSTR(v.input_value,0,6) || '.' || SUBSTR(v.input_value,6),
'999999.999999999999999999999999999'
),
'999999.99'
)
) AS final_outp
FROM vals v

Number check in oracle sql

How to check in 10 digit number whether it contain 999 or 000 in the 4-6th bytes ?
I have a n idea with using INSTR but i don't know how to execute it
This is strange. If the "number" is really a string, then you can use like or substr():
where col like '___999%' or col like '___000%'
or:
where substr(col, 4, 3) in ('999', '000')
or even regular expressions.
Given the nature of your question, you can turn a number into a string and use these methods. However, if you are looking at particular digits, then the "number" should be stored as a string.
If they are actually numbers rather than strings then you could use numeric manipulation:
with t (n) as (
select 1234567890 from dual
union all select 1239997890 from dual
union all select 1230007890 from dual
union all select 1299967890 from dual
union all select 1234000890 from dual
)
select n,
mod(n, 10000000) as stage1,
mod(n, 10000000)/10000 as stage2,
trunc(mod(n, 10000000)/10000) as stage3,
case when trunc(mod(n, 10000000)/10000) in (0, 999) then 'Yes' else 'No' end as matches
from t;
N STAGE1 STAGE2 STAGE3 MATCHES
---------- ---------- ---------- ---------- -------
1234567890 4567890 456.789 456 No
1239997890 9997890 999.789 999 Yes
1230007890 7890 .789 0 Yes
1299967890 9967890 996.789 996 No
1234000890 4000890 400.089 400 No
Stage 1 effectively strips off the first three digits. Stage two almost strips off the last four digits, but leaves fractions, so stage 3 adds trunc() (you could also use floor()) to ignore those fractional parts.
The result of that is the numeric value of the 4-6th digits, and you can then test if that is 0, 999 or something else.
This is really looking at the 4th to 6th most significant digits, which is the same if the number is always 10 digits; if it might actually have different numbers of digits then you'd need to clarify what you want to see.
select
1 from dual where instr(98800054542,000,4,3)in (6) or instr(98800054542,999,4,3)in (6); let me know if this helped.

SQL How to extract numbers from a string?

I am working on a query in SQL that should be able to extract numbers on different/random lenght from the beginning of the text string.
Text string: 666 devils number is not 8888.
Text string: 12345 devils number is my PIN, that is 6666.
I want to get in a column
666
12345
Use a combination of Substr & instr
SELECT Substr (textstring, 1,instr(textstring,' ') - 1) AS Output
FROM yourtable
Result:
OUTPUT
666
12345
Use this if you have text at the beginning e.g. aa12345 devils number is my PIN, that is 6666. as it utilises the REGEXP_REPLACE function.
SELECT REGEXP_REPLACE(Substr (textstring, 1,instr(textstring,' ') - 1), '[[:alpha:]]','') AS Output
FROM yourtable
SQL Fiddle: http://sqlfiddle.com/#!4/8edc9/1/0
This version utilizes a regular expression which gives you the first number whether or not it's preceded by text and does not use the ghastly nested instr/substr calls:
SQL> with tbl(data) as (
select '666 devils number is not 8888' from dual
union
select '12345 devils number is my PIN, that is 6666' from dual
union
select 'aa12345 devils number is my PIN, that is 6666' from dual
)
select regexp_substr(data, '^\D*(\d+) ', 1, 1, null, 1) first_nbr
from tbl;
FIRST_NBR
---------------------------------------------
12345
666
12345
SQL>

how to add zeros after decimal in Oracle

I want to add zeroes after the number .
for eg a= 6895
then a= 6895.00
datatype of a is number(12);
I am using the below code .
select to_char(6895,'0000.00') from dual .
I m getting the desired result from above code but
'6895' can be any number.so due to that i need to add '0' in above code manually.
for eg.
select to_char(68955698,'00000000.00') from dual .
Can any one suggest me the better method .
The number format models are the place to start when converting numbers to characters. 0 prepends 0s, which means you'd have to get rid of them somehow. However, 9 means:
Returns value with the specified number of digits with a leading space if positive or with a leading minus if negative. Leading zeros are blank, except for a zero value, which returns a zero for the integer part of the fixed-point number.
So, the following gets you almost there, save for the leading space:
SQL> select to_char(987, '9999.00') from dual;
TO_CHAR(
--------
987.00
You then need to use a format model modifier, FM, which is described thusly:
FM Fill mode. Oracle uses trailing blank characters and leading zeroes
to fill format elements to a constant width. The width is equal to the
display width of the largest element for the relevant format model
...
The FM modifier suppresses the above padding in the return value of
the TO_CHAR function.
This gives you a format model of fm9999.00, which'll work:
SQL> select to_char(987, 'fm9999.00') from dual;
TO_CHAR(
--------
987.00
If you want a lot of digits before the decimal then simply add a lot of 9s.
datatype of a is number(12);
Then use 12 9s in the format model. And, keep the decimal to just 2. So, since the column datatype is NUMBER(12), you cannot have any number more than the given size.
SQL> WITH DATA AS(
2 SELECT 12 num FROM dual union ALL
3 SELECT 234 num FROM dual UNION ALL
4 SELECT 9999 num FROM dual UNION ALL
5 SELECT 123456789 num FROM dual)
6 SELECT to_char(num,'999999999999D99') FROM DATA
7 /
TO_CHAR(NUM,'999
----------------
12.00
234.00
9999.00
123456789.00
SQL>
Update Regarding leading spaces
SQL> select ltrim(to_char(549,'999999999999.00')) from dual;
LTRIM(TO_CHAR(54
----------------
549.00
SQL>
With using CASE and SUBSTR it is very simple.
CASE WHEN SUBSTR(COLUMN_NAME,1,1) = '.' THEN '0'||COLUMN_NAME ELSE COLUMN_NAME END