Convert Integers to Dollar Format in Oracle Database - sql

I'm using Oracle Database version 12.1.0.2.0. I'm running a query that returns integers that is actually a dollar amount:
SELECT value AS "Valuation" FROM estimates;
Result:
Instead, I would like to show:
$115,508
$38,150
$92,832
$116,222
How can I convert the integers into dollar $ format?

Use the TO_CHAR function:
TO_CHAR(SOME_NUMBER, '$999,999,999,999,999')
db<>fiddle here

Use to_char with extended parameters format and nlsparam: TO_CHAR (number)
and Number Format Models:
You can specify currency with NLS_CURRENCY and "Group symbol" (NLS_NUMERIC_CHARACTERS('dg'))
SELECT
to_char(
value
,'L999g999'
,q'[
NLS_NUMERIC_CHARACTERS = '.,'
NLS_CURRENCY = '$'
]') AS "Valuation"
FROM estimates;
DBFiddle
Results:
Valuation
$11,234
$104
$321,349
$2,837
NB: It's not necessary to specify extra NLS parameters if they correctly set on session level! So it will be much more agile and users will be able to use own session settings.

Can get rid of the left spaces if you really want that:
SQL> SELECT ltrim(to_char(value,'$999,999')) AS "Valuation" FROM estimates;
Valuation
---------
$115,508
$38,150
$92,832
$116,222
Bobby

Related

how to use substr function with to_date in sql?

query is :
select substr(to_date('01-02-2018','mm-dd-yyyy'),4,3) from dual;
output is :
JAN
can anyone explain how the output came ?
When you apply a text function directly to something that's of DATE datatype, you force an implicit conversion of the date into a string. This conversion uses the NLS_DATE_FORMAT parameter to decide the format of the output string.
In effect,
substr(to_date('01-02-2018','mm-dd-yyyy'),4,3)
is the same as
substr(to_char(to_date('01-02-2018','mm-dd-yyyy'), <NLS_DATE_FORMAT>),4,3)
The usual default value (for English-language versions of the database) of the NLS_DATE_FORMAT parameter is DD-MON-RR - which it sounds like the value of your NLS_DATE_FORMAT parameter is set to, which means your query is doing:
substr(to_char(to_date('01-02-2018','mm-dd-yyyy'), 'DD-MON-RR'),4,3)
Therefore, the substr is working on the string 02-JAN-18, and the 3 characters starting from the 4th character is JAN.
Rather than use substr on a date, you would do better to use to_char instead, e.g.:
to_char(to_date('01-02-2018', 'mm-dd-yyyy'), 'MON')

TO_Char number format model in Oracle

I don't understand fully how can I use the to_char function to convert a number to a string with the appropriate format model.
The actual number has this type of format:
Uses comma as decimal separator
Always 5 decimal numbers
The integer numbers can up to 6 (potentially can be infinite, but for now they were never more than 6)
The number can be positive or negative
The number can begin with a 0
I've tried to use the to_char but I am not able to achieve a result that works with all the conditions
Some examples of how the output should be are
0,00235 or 156,45623 or -0,0235 or -156,45623
Keep in mind that you are transforming a number into a string. The number does not have any sense of "," or "." or anything--it is a number.
The trick is to get the TO_CHAR function to convert the internal number to the string representation that you want.
There are a few problems to worry about: getting the radix point (decimal) correct and dealing with padding.
Here is a working example:
SELECT to_char(0.00235,'FM99999999999999990D99999', 'NLS_NUMERIC_CHARACTERS = '',.''') FROM DUAL;
0,00235
SELECT to_char(156.45823,'FM99999999999999990D99999', 'NLS_NUMERIC_CHARACTERS = '',.''') FROM DUAL;
156,45823
SELECT to_char(-0.0235,'FM99999999999999990D99999', 'NLS_NUMERIC_CHARACTERS = '',.''') FROM DUAL;
-0,0235
SELECT to_char(-156.45623,'FM99999999999999990D99999', 'NLS_NUMERIC_CHARACTERS = '',.''') FROM DUAL;
-156,45623
SELECT to_char(123456789.45623,'FM99999999999999990D99999', 'NLS_NUMERIC_CHARACTERS = '',.''') FROM DUAL;
123456789,45623
The relevant parts of the mask:
FMis used to trim leading and trailing blanks that Oracle normally uses to pad out numbers.
D is the radix point, depending on your NLS settings.
NLS_NUMERIC_CHARACTERS ... is an override of your local NLS settings--this might not be necessary if your locale uses a comma for the decimal, but it is a way you can force this behavior in a database with, say, North American settings.
Shamelessly stolen from this post from #Vadzim.
You should be able to get the format you're looking for by using this pattern:
rtrim(to_char(num, 'FM999999999999990.99'), '.')
https://rextester.com/QRSD48676
SELECT rtrim(to_char('0,00235', 'FM999999999999990.99999'), '.') FROM DUAL\\
SELECT rtrim(to_char('156,45623', 'FM999999999999990.99999'), '.') FROM DUAL\\
SELECT rtrim(to_char('-0,0235', 'FM999999999999990.99999'), '.') FROM DUAL\\
SELECT rtrim(to_char('-156,45623', 'FM999999999999990.99999'), '.') FROM DUAL\\
Results:
0.00235
156.45623
-0.0235
-156.45623

decimal separator oracle

I need to replace comma with point and then i need my value to be a number.
So i wrote this:
select replace('12345,6789', ',' , '.') from dual --it works fine
but then I want to convert to_number that value and I get the error:
"invalid number"
The to_number() function uses the session's NLS_NUMERIC_CHARACTERS setting to decide how to interpret commas and periods. If you know your string will always have a comma as decimal separator you can override that as part of the call, using the optional third argument; although that does mean you have to specify the format model:
select to_number('12345,6789', '9999999999D9999', 'NLS_NUMERIC_CHARACTERS='',.''')
from dual;
TO_NUMBER('12345,6789','9999999999D9999
---------------------------------------
12345.6789
You don't need a separate replace() step.
You can also change the session's setting with ALTER SESSION SET NLS_NUMERIC_CHARACTERS=',.';, but you may not be able to control the setting in every client that has to run your code.
The decimal separator is defined in your locale. Here it looks like it is ,. So you need not to do the replacement before converting your string:
select to_number('12345.6789') from dual --should work already
Or change your locale:
alter session set NLS_NUMERIC_CHARACTERS= '.,';
select to_number('123'||'.'||'456') from dual;
select to_number(replace('12345,6789', ',' , '.')) from dual

Number format in SQL

I have a number for example 39.46
and i want it to convert in ,format i.e it should look like 39,46 in SQL
is there any function to convert decimal amount in , separated format ?
There is a NLS setting NLS_NUMERIC_CHARACTERS, where you can set "," as decimal separator and "." to separate thousands. They are typically automatically set when you set your locale. You obviously use an English locale.
See here.
This assumes you have actual numbers in your DB and not strings which look like numbers. For strings you may want to use sting conversion operations as described by Thomas G.
Below I demonstrate how to use the number format and the nls_numeric_characters parameter, both for a numeric input and a string input. Notice the d (or D) in the format model, it says "use whatever the appropriate decimal separator is."
SQL> select to_char(93.23, '999d99', 'nls_numeric_characters='',.''') from dual;
TO_CHAR
-------
93,23
1 row selected.
Elapsed: 00:00:00.14
SQL> select to_char(to_number('93.23'), '999d99', 'nls_numeric_characters='',.''')
from dual;
TO_CHAR
-------
93,23
1 row selected.

ORA-01843 not a valid month- Comparing Dates

I have a problem when try to select data from a table filtering by date.
For example:
SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = '23/04/49';
The Oracle Error is:
Informe de error:
Error SQL: ORA-01843: mes no válido
01843. 00000 - "not a valid month"
*Cause:
*Action:
Probably the source data of table is corrupted, in this case:
How can i solve this problem?
Can I change this dates for null?
The results of this select, select * from nls_session_parameters; , is:
PARAMETER VALUE
------------------------------ ----------------------------------------
NLS_LANGUAGE SPANISH
NLS_TERRITORY SPAIN
NLS_CURRENCY ¿
NLS_ISO_CURRENCY SPAIN
NLS_NUMERIC_CHARACTERS ,.
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD/MM/RR
NLS_DATE_LANGUAGE SPANISH
NLS_SORT SPANISH
NLS_TIME_FORMAT HH24:MI:SSXFF
NLS_TIMESTAMP_FORMAT DD/MM/RR HH24:MI:SSXFF
NLS_TIME_TZ_FORMAT HH24:MI:SSXFF TZR
NLS_TIMESTAMP_TZ_FORMAT DD/MM/RR HH24:MI:SSXFF TZR
NLS_DUAL_CURRENCY ¿
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
You should use the to_date function (oracle/functions/to_date.php
)
SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = TO_DATE('23/04/49', 'DD/MM/YY');
You are comparing a date column to a string literal. In such a case, Oracle attempts to convert your literal to a date, using the default date format.
It's a bad practice to rely on such a behavior, as this default may change if the DBA changes some configuration, Oracle breaks something in a future revision, etc.
Instead, you should always explicitly convert your literal to a date and state the format you're using:
SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = TO_DATE('23/04/49','MM/DD/YY');
If you don't need to check exact timestamp, use
SELECT * FROM MYTABLE WHERE trunc(DATEIN) = TO_DATE('23-04-49','DD-MM-YY');
otherwise, you can use
SELECT * FROM MYTABLE WHERE DATEIN = TO_DATE('23-04-49 20:18:07','DD-MM-YY HH24:MI:SS');
Here, you use hard code date,if you directly compare then you must use DD-MM-YY HH24:MI:SS else you might get ORA-01849: hour must be between 1 and 12.
I know this is a bit late, but I'm having a similar issue. SQL*Plus executes the query successfully, but Oracle SQL Developer shows the ORA-01843: not a valid month error.
SQL*Plus seems to know that the date I'm using is in the valid format, whereas Oracle SQL Developer needs to be told explicitly what format my date is in.
SQL*Plus statement:
select count(*) from some_table where DATE_TIME_CREATED < '09-12-23';
VS
Oracle SQL Developer statement:
select count(*) from some_table where DATE_TIME_CREATED < TO_DATE('09-12-23','RR-MM-DD');
Just in case this helps, I solved this by checking the server date format:
SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';
then by using the following comparison (the left field is a date+time):
AND EV_DTTM >= ('01-DEC-16')
I was trying this with TO_DATE but kept getting an error. But when I matched my string with the NLS_DATE_FORMAT and removed TO_DATE, it worked...
In a comment to one of the answers you mention that to_date with a format doesn't help. In another comment you explain that the table is accessed via DBLINK.
So obviously the other system contains an invalid date that Oracle cannot accept. Fix this in the other dbms (or whatever you dblink to) and your query will work.
Having said this, I agree with the others: always use to_date with a format to convert a string literal to a date. Also never use only two digits for a year. For example '23/04/49' means 2049 in your system (format RR), but it confuses the reader (as you see from the answers suggesting a format with YY).
If the source date contains minutes and seconds part, your date comparison will fail.
you need to convert source date to the required format using to_char and the target date also.
If you are using command line tools, then you can also set it in the shell.
On linux, with a sh type shell, you can do for example:
export NLS_TIMESTAMP_FORMAT='DD/MON/RR HH24:MI:SSXFF'
Then you can use the command line tools and it will use the specified format:
/path/to/dbhome_1/bin/sqlldr user/pass#host:port/service control=table.ctl direct=true
Try using:
SELECT *
FROM MYTABLE
WHERE MYTABLE.DATEIN is not null
AND MYTABLE.DATEIN = '23/04/49';
Use the month as a string.
Example:
(12-Apr-2002) or (12-April-2002)
Although the answers using TO_DATE are correct, I prefer to use the ANSI SQL format for dates:
DATEIN = DATE '1949-04-23'
It works in Oracle and other DBMS ANSI SQL compliant. This is specially important if your application is DBMS agnostic.
Try alter session set NLS_DATE_FORMAT='DD/MM/YY'; -- or whatever format you want
I faced the same problem, on PROD, all the code were already in this format, but on preprod, it's not set,
So this means you change the default date format used by oracle
ALTER session set NLS_LANGUAGE=’AMERICAN’;