PL/SQL How do i remove characters from data - oracle

I have rows that contain certain data such as:
EUR-40E
CP1-40E
CP1-36E
CP1FP-48E
My question is, how do i remove all characters leaving only the numbers after the hyphen.
I have tried to do it using this:
REGEXP_REPLACE (po.config_id, '\D')
But end up with this output:
140
140
136
It takes all characters but unfortunately the 1 before the hyphen remains?
Thanks

You could do it like that:
select substr(regexp_substr('EUR-40E','-[[:digit:]]+'),2) from dual;

Try :
select regexp_replace(substr(text,instr(text,'-'),length(text)), '[^0-9]', '') from dual;
replace text with the actual value e.g. CP1FP-48E56T
Example ( I created a dummy table foo with your values ) :
SQL> select * from foo;
TEXT
------------
EUR-40E
CP1-40E
CP1-36E
CP1FP-48E
CP1FP-48E54R
SQL> select regexp_replace(substr(text,instr(text,'-'),length(text)), '[^0-9]', '') output from foo;
OUTPUT
--------------------------------------------------------------------------------
40
40
36
48
4854

Related

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'

ORA-12899: value too large for column - on export/import, both BYTE semantics, not CHAR

I have an Oracle DB on one Windows machine and perform an export of all tables + contents using SQL developer 4.0.2.15. File format is plain text SQL, ANSI ISO-8859-1. The line endings are done in UNIX style (1 byte).
The table / column definitions are like:
"PRODUCTNAME" VARCHAR2(120 BYTE),
When I execute this .sql file on the target Windows machine, tables are created and inserts are done. But some items that have exactly 120 bytes in the PRODUCTNAME (including 1 line feed character) fail to insert on the target machine.
I get:
ORA-12899: value too large for column "DBNAME"."TABLENAME"."PRODUCTNAME" (actual: 121, maximum: 120)
I don't understand why. I have no 2-byte characters in this particular string, and the export is definitely done using 0x0A as line break character (checked via Notepad++ status line and its HexView Plugin). I use drag&drop to open the .sql file in the target machine's SQL developer (same version). When I copy the productname with its line break into Notepad++ via clipboard, it count's 120 bytes of length.
I do not understand, why in Oracle developer the script counts this 1 extra character.
I have searched for this in google and found topics here on SO among others, but they don't help me or I don't fully understand them.
What do I miss? Please help!
Create a temporary table (say, TEST) having PRODUCTNAME VARCHAR2(200). Import data into it. Check rows that exceed length of 120 characters.
You might need to use the DUMP function, such as
select dump(productname) from test
It'll show you actual length of data stored in that column. Just for example:
SQL> select ename, dump(ename) dump_e from emp where rownum = 1;
ENAME DUMP_E
---------- ----------------------------------------
KING Typ=1 Len=4: 75,73,78,71
-----
this!
SQL>
[EDIT: TRIM example]
SQL> with test (id, col) as
2 (select 1, 'abc' from dual union
3 select 2, 'def ' from dual union
4 select 3, ' ghi ' from dual
5 )
6 select '#' || col || '#' col,
7 '#' || trim(col) || '#' new_col
8 from test
9 order by id;
COL NEW_COL
-------- --------
#abc# #abc#
#def # #def#
# ghi # #ghi#
SQL>

what will translate function do if I want to change some chars to nothing?

I have a sql statement:
select translate('abcdefg', 'abc', '') from dual;
Why the result is nothing?
I think it should be 'defg'.
From the documentation:
You cannot use an empty string for to_string to remove all characters in from_string from the return value. Oracle Database interprets the empty string as null, and if this function has a null argument, then it returns null. To remove all characters in from_string, concatenate another character to the beginning of from_string and specify this character as the to_string. For example, TRANSLATE(expr, 'x0123456789', 'x') removes all digits from expr.
So you can do something like:
select translate('abcdefg', '#abc', '#') from dual;
TRANSLATE('ABCDEFG','#ABC','#')
-------------------------------
defg
... using any character that isn't going to be in your from_string.
select translate('abcdefg', 'abc', '') from dual;
To add to Alex's answer, you could use any character(allowed in SQL) for that matter to concatenate to remove all the characters. So, you could even use a space instead of empty string. An empty string in Oracle is considered as NULL value.
So, you could also do -
SQL> SELECT TRANSLATE('abcdefg', ' abc', ' ') FROM dual;
TRAN
----
defg
SQL>
Which is the same as -
SQL> SELECT TRANSLATE('abcdefg', chr(32)||'abc', chr(32)) FROM dual;
TRAN
----
defg
SQL>
Since the ascii value of space is 32.
It was just a demo, it is better to use any other character than space for better understanding and code readability.

how to paste numbers with thousand separator from excel to sqldeveloper table editor

There's data exported to excel:
MS_ID STARTDATETIME
3 704 285 09.11.2014 11:29:25
3 704 285 09.11.2014 11:29:25
I want to paste it back to Oracle using sqldeveloper table data editor.
For date column I do
alter session set NLS_DATE_FORMAT = 'mm.dd.yyyy HH24:mi:ss';
But I'm also getting:
INSERT INTO "PPB"."CDRGPRS" (MS_ID, STARTDATETIME) VALUES ('3 704 285', TO_DATE('09.11.2014 11:29:25', 'mm.dd.yyyy HH24:mi:ss'))
ORA-01722: invalid number
ORA-06512: at line 1
The SQL above is generated by sqldeveloper.
There's no NLS_NUMBER_FORMAT. How to make Oracle format and parse numbers with spaces as thousand separator?
TO_NUMBER() allows you to specify whatever separators you want using nls_numeric_characters.
SQL> select to_number( '100 123,23'
2 , '999G999G999D99'
3 , 'nls_numeric_characters = '', '''
4 ) as no
5 from dual;
NO
----------
100123.23
G is the number format model corresponding to the separator, which is the second option of your nls_numeric_characters.
If you want to convert it into a number improperly you can REPLACE() the spaces:
SQL> select to_number(replace( '100 12323', ' ')) as no
2 from dual;
NO
--------
10012323
Wrote this macro and put it to Personal.xlsb
Sub nospace()
Application.FindFormat.NumberFormat = "#,##0"
Application.ReplaceFormat.NumberFormat = "0"
Cells.Replace What:="", Replacement:="", _
SearchFormat:=True, ReplaceFormat:=True
End Sub

Oracle 11.2 to_number multiple commas

In Oracle 11.2, is there some number format, nf, that will work with to_number to parse arbitrary length varchar2s containing digits and commas?
I can achieve this without a number format, by using regexp_replace, but I'd prefer to achieve the same thing using just a number format.
e.g., the following 2 statements work:
select to_number(regexp_replace('12,345', ',', '')) from dual;
select to_number(regexp_replace('1,234,567', ',', '')) from dual;
but I'd prefer:
select to_number('12,345', nf) from dual;
select to_number('1,234,567', nf) from dual;
where nf is one number format string that works for both statements.
If I try nf = '99,999', the first statement works, but the second fails.
Thanks.
Oracle won't complain if the number format is too long, so you can use a model that has enough digits to cope with the biggest number you can receive:
SQL> select to_number('12,345',
2 '999G999G999G999G999G999G999G999G999G999G999G999G999') from dual;
TO_NUMBER('12,345','999G999G999G999G999G999G999G999G999G999G999G999G999')
-------------------------------------------------------------------------
12345
SQL> select to_number('1,234,567',
2 '999G999G999G999G999G999G999G999G999G999G999G999G999') from dual;
TO_NUMBER('1,234,567','999G999G999G999G999G999G999G999G999G999G999G999G999')
----------------------------------------------------------------------------
1234567
SQL> select to_number('999,999,999,999,999,999,999,999,999,999,999,999,999',
2 '999G999G999G999G999G999G999G999G999G999G999G999G999') from dual;
TO_NUMBER('999,999,999,999,999,999,999,999,999,999,999,999,999','999G999G999G999
--------------------------------------------------------------------------------
1.0000E+39
I've used the G group separator instead of a fixed comma to support globalisation, but the effect is the same.
The only caveat is that the source number has to have the right grouping so it matches the formatting exactly for the digits it does have:
SQL> select to_number('1,2345',
2 '999G999G999G999G999G999G999G999G999G999G999G999G999') from dual;
select to_number('1,2345',
*
ERROR at line 1:
ORA-01722: invalid number
Although I support Alex Poole's answer, here's another crude but effective way of solving the problem that should perform better than doing a regex.
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE table_of_numbers (
example_num VARCHAR2(50)
)
/
INSERT INTO table_of_numbers (example_num)
VALUES ('12,345')
/
INSERT INTO table_of_numbers (example_num)
VALUES ('1,234,567')
/
Query 1:
SELECT TO_NUMBER(example_num, RPAD('9', LENGTH(example_num) - 1, '9')) fudge
FROM table_of_numbers
Results:
| FUDGE |
-----------
| 12345 |
| 1234567 |
If you need to match the commas, then you could do something slightly more sophisticated with INSTR and LPAD to make sure you generate the right mask.
For this :
select to_number('1,234,567', nf) from dual;
Use nf = 9,999,999 will work.

Resources