How to convert blank to NULL in oracle query - sql

I have blanks in my name column in sql query. How can I replace to show as null.
SELECT Name from table

The TRIM function provides this feature.
It is used like this:
select TRIM(Name) from table
It will remove leading and trailing spaces from the results for field Name.

Maybe you are talking of spaces?
Here is how to remove any commonly known "blank" chars:
with regexp_replace (interestingly... just to notice the [[:space:]])
select '<'||
regexp_replace(
'a'||CHR(9)||' b'||CHR(10)||CHR(11)
||'c'||CHR(12)||CHR(13)||' d'
, '[[:space:]]','')
||'>'
from dual;
more efficient: avoid regexp_replace...: use TRANSLATE!
select '<'||
TRANSLATE(
'a'||CHR(9)||' b'||CHR(10)||CHR(11)
||'c'||CHR(12)||CHR(13)||' d' -- complicate string with blank
,'A'||CHR(9)||CHR(10)||CHR(11)||CHR(12)||CHR(13)||' '
,'A') -- this 'A' is a trick to replace by null ('')
||'>' -- to show where string stops
from dual;

TRIM removes the blank character from left and right, so if your string only consists of blanks then you get an empty string, which is NULL in Oracle.
select trim(name) from mytable;
This would also change ' Mary Smith ' to 'Mary Smith', but I guess you wouldn't mind :-)
If, however, you want to consider any whitespace, e.g. tabs, too, then TRIM doesn't suffice. You can use REGEXP_REPLACE then to replace all names that only consist of whitespace with null.
regexp_replace(name, '^[[:space:]]*$', null) from mytable;
If you also want to trim whitespace from any names (so ' Mary Smith ' becomes 'Mary Smith' again) then:
select regexp_replace(name, '^[[:space:]]*([^[:space:]]*)[[:space:]]*', '\1') from mytable;

Related

Oracle remove special characters

I have a column in a table ident_nums that contains different types of ids. I need to remove special characters(e.g. [.,/#&$-]) from that column and replace them with space; however, if the special characters are found at the beginning of the string, I need to remove it without placing a space. I tried to do it in steps; first, I removed the special characters and replaced them with space (I used
REGEXP_REPLACE) then found the records that contain spaces at the beginning of the string and tried to use the TRIM function to remove the white space, but for some reason is not working that.
Here is what I have done
Select regexp_replace(id_num, '[:(),./#*&-]', ' ') from ident_nums
This part works for me, I remove all the unwanted characters from the column, however, if the string in the column starts with a character I don't want to have space in there, I would like to remove just the character, so I tried to use the built-in function TRIM.
update ident_nums
set id_num = TRIM(id_num)
I'm getting an error ORA-01407: can't update ident_nums.id_num to NULL
Any ideas what I am doing wrong here?
It does work if I add a where clause,
update ident_nums
set id_num = TRIM(id_num) where id = 123;
but I need to update all the rows with the white space at the beginning of the string.
Any suggestions are welcome.
Or if it can be done better.
The table has millions of records.
Thank you
Regexp can be slow sometimes so if you can do it by using built-in functions - consider it.
As #Abra suggested TRIM and TRANSLATE is a good choice, but maybe you would prefer LTRIM - removes only leading spaces from string (TRIM removes both - leading and trailing character ). If you want to remove "space" you can ommit defining the trim character parameter, space is default.
select
ltrim(translate('#kdjdj:', '[:(),./#*&-]', ' '))
from dual;
select
ltrim(translate(orginal_string, 'special_characters_to_remove', ' '))
from dual;
Combination of Oracle built-in functions TRANSLATE and TRIM worked for me.
select trim(' ' from translate('#$one,$2-zero...', '#$,-.',' ')) as RESULT
from DUAL
Refer to this dbfiddle
I think trim() is the key, but if you want to keep only alpha numerics, digits, and spaces, then:
select trim(' ' from regexp_replace(col, '[^a-zA-Z0-9 ]', ' ', 1, 0))
regexp_replace() makes it possible to specify only the characters you want to keep, which could be convenient.
Thanks, everyone, It this query worked for me
update update ident_nums
set id_num = LTRIM(REGEXP_REPLACE(id_num, '[:space:]+', ' ')
where REGEXP_LIKE(id_num, '^[ ?]')
this should work for you.
SELECT id_num, length(id_num) length_old, NEW_ID_NUM, length(NEW_ID_NUM) len_NEW_ID_NUM, ltrim(NEW_ID_NUM), length(ltrim(NEW_ID_NUM)) length_after_ltrim
FROM (
SELECT id_num, regexp_replace(id_num, '[:(),./#*&-#]', ' ') NEW_ID_NUM FROM
(
SELECT '1234$%45' as id_num from dual UNION
SELECT '#SHARMA' as id_num from dual UNION
SELECT 'JACK TEST' as id_num from dual UNION
SELECT 'XYZ#$' as id_num from dual UNION
SELECT '#ABCDE()' as id_num from dual -- THe 1st character is space
)
)

How to remove all hyphens and spaces from a string?

I've got the following code:
INSERT INTO DWCUST (DWCUSTID, DWSOURCEIDBRIS, DWSOURCEIDMELB, FIRSTNAME, SURNAME, GENDER, PHONE, POSTCODE, CITY, STATE, CUSTCATNAME)
SELECT dwcustSeq.nextval, cb.custid, Null, cb.fname, cb.sname, UPPER(cb.gender), cb.phone, cb.postcode, cb.city, cb.state, cc.custcatname
FROM a2custbris cb
NATURAL JOIN a2custcategory cc
WHERE cb.rowid IN (SELECT source_rowid FROM A2ERROREVENT where filterid = 5);
I want to adjust it so that before cb.phone (varchar2) values are added to dwcust, all hyphens and spaces are removed from the strings so that they are just numeric.
For instance I want 04-1234 5254 to become 0412345254
Translate can be useful:
translate(cb.phone, 'X- ', 'X')
For example,
select translate(' 04-1234 5254', 'X- ', 'X')
from dual
gives:
TRANSLATE('04-12345254','X-','X')
---------------------------------
0412345254
1 row selected.
About this usage, Oracle docs says:
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.
I would use regexp_replace()
select regexp_replace('04-1234 5254', '[- ]', '')
from dual;
This would still return something that is not a number if it e.g. contains a /
To make sure or to remove everything that is not a number use the following:
select regexp_replace('04-1234 5254', '[^0-9]', '')
from dual;
Just replace cb.phone with regexp_replace(cb.phone, , '[^0-9]', '') in your SELECT list.
SELECT ...., regexp_replace(cb.phone, , '[^0-9]', ''), ....
FROM a2custbris cb
....

why output is null at select translate(' #',' ','') from dual; and why resulit is # at select replace(' #',' ','') from dual;

Basically translate will change character to character and Replace string to string , and here i have tried to remove spaces using translate to count the number words .
select translate(' #',' ','') from dual;
select replace(' #',' ','') from dual;
select ename , nvl(length(replace(TRANSLATE(upper(trim(ename)),'ABCDEFGHIJKLMNOPQRSTUVWXYZ'' ',' # '),' ',''))+1,1) NOOFWORDs
from emp;
Unfortunately Oracle has made many bizarre choices around null vs. empty string.
One of those has to do with TRANSLATE. TRANSLATE will return NULL if any of its arguments (including the last one) is NULL, no matter what the logical behavior should be.
So, to remove spaces (say) with TRANSLATE, you must add a character you do NOT want to be removed to both the second and the third argument. I added the lower-case letter z, but you could add anything (a dot, the digit 0, whatever - just make sure you add the same character at the beginning of both arguments)
... translate (input_string, 'z ', 'z') ....
For example:
select translate(' #','z ','z') from dual;
TRANSLATE('#','Z','Z')
------------------------
#
select translate(' #',' ','') from dual;
Returns NULL because in Oracle empty strings unfortunately yield NULLs. Therefore it's equivalent to
SELECT translate(' #', ' ', NULL)
FROM dual;
and translate() returns NULL when an argument is null. Actually this is well documented in "TRANSLATE":
(...)
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.
If you want to replace one character, use replace() as you already did. For a few but more than one characters you can nest the replace()s.
This however gets unhandy, when you want to replace quite a lot of characters. In such a situation, if the replacement character is only one character or the empty string regexp_replace() using a character class or alternates may come in handy.
For example
SELECT regexp_replace('a12b478c01', '[0-9]', '')
FROM dual;
replaces all the digits so just 'abc' remains and
SELECT regexp_replace('ABcc1233', 'c|3', '')
FROM dual;
removes any '3' or 'c' and results in 'AB12'. In your very example
SELECT regexp_replace(' #', ' ', '')
FROM dual;
would also work and give you '#'. Though in the simple case of your example a simple replace() is enough.

Changing LastName,FirstName to LastName,FirstInitial

I'm sure this is super easy, but how would I go about converting LastName,FirstName to LastName,FirstInitial?
For example changing Smith,John to Smith,J or Johnson,John to Johnson,J etc.
Thank You!
In case of LastName and FirstName columns:
select LastName,substr(FirstName,1,1)
from mytable
;
In case of a fullname saved in a single column:
select substr(fullname,1,instr(fullname || ',',',')-1) || substr(fullname,instr(fullname || ',',','),2)
from mytable
;
or
select regexp_replace (fullname,'([^,]*,?)(.).*','\1\2')
from mytable
;
Here is one way, using just "standard" instr and substr. Assuming your input is a single string in the format 'Smith,John':
select substr(fullname, 1, instr(fullname, ',')+1) from yourtable;
yourtable is the name of the table, and fullname is the name of the column.
instr(fullname, ',') finds the position of the comma within the input string (it would be 6 in 'Smith,John'); thensubstrtakes the substring that begins at the first position (the1in the function call) and ends at the position calculated byinstr`, PLUS 1 (to get the first initial as well).

Delete certain character based on the preceding or succeeding character - ORACLE

I have used REPLACE function in order to delete email addresses from hundreds of records. However, as it is known, the semicolon is the separator, usually between each email address and anther. The problem is, there are a lot of semicolons left randomly.
For example: the field:
123#hotmail.com;456#yahoo.com;789#gmail.com;xyz#msn.com
Let's say that after I deleted two email addresses, the field content became like:
;456#yahoo.com;789#gmail.com;
I need to clean these fields from these extra undesired semicolons to be like
456#yahoo.com;789#gmail.com
For double semicolons I have used REPLACE as well by replacing each ;; with ;
Is there anyway to delete any semicolon that is not preceded or following by any character?
If you only need to replace semicolons at the start or end of the string, using a regular expression with the anchor '^' (beginning of string) / '$' (end of string) should achieve what you want:
with v_data as (
select '123#hotmail.com;456#yahoo.com;789#gmail.com;xyz#msn.com' value
from dual union all
select ';456#yahoo.com;789#gmail.com;' value from dual
)
select
value,
regexp_replace(regexp_replace(value, '^;', ''), ';$', '') as normalized_value
from v_data
If you also need to replace stray semicolons from the middle of the string, you'll probably need regexes with lookahead/lookbehind.
You remove leading and trailing characters with TRIM:
select trim(both ';' from ';456#yahoo.com;;;789#gmail.com;') from dual;
To replace multiple characters with only one occurrence use REGEXP_REPLACE:
select regexp_replace(';456#yahoo.com;;;789#gmail.com;', ';+', ';') from dual;
Both methods combined:
select regexp_replace( trim(both ';' from ';456#yahoo.com;;;789#gmail.com;'), ';+', ';' ) from dual;
regular expression replace can help
select regexp_replace('123#hotmail.com;456#yahoo.com;;456#yahoo.com;;789#gmail.com',
'456#yahoo.com(;)+') as result from dual;
Output:
| RESULT |
|-------------------------------|
| 123#hotmail.com;789#gmail.com |