I want to add special character after 3rd character. Below is the example
Current Phone Number:- 123234567
Expected output :- (123)234-567
How can I do this ?
Concatenation, as you said, along with the substr function:
SQL> with test (col) as
2 (select 123234567 from dual)
3 select '(' || substr(col, 1, 3) || ')' ||substr(col, 4, 3) ||'-'|| substr(col, 7) result
4 from test;
RESULT
------------
(123)234-567
SQL>
Or, using regular expressions:
SQL> with test (col) as
2 (select 123234567 from dual)
3 select regexp_replace(col, '([0-9]{3})([0-9]{3})', '(\1)\2-') result_2
4 from test;
RESULT_2
------------
(123)234-567
SQL>
Related
I have a string, like:
'one,two,three'
and I want to convert it in rows and use it into IN clause in an SQL:
one
two
three
I tried something like :
SELECT column_value
FROM XMLTable('"one","two","three"');
and it worked fine but in a join condition it fails.
SELECT 1
FROM dual
WHERE 'one' IN (SELECT column_value
FROM XMLTable('"one","two","three"'));
it gaves me the error:
ORA-00932: inconsistent datatypes: expected - got CHAR
00932. 00000 - "inconsistent datatypes: expected %s got %s"
Can anyone help me on this, please?
NOTE: I would like not use PLSQL
What you need is nothing but just casting a CLOB value to a [VAR]CHAR[2] data type such as
SELECT 1
FROM dual
WHERE 'one' IN (SELECT CAST(column_value AS VARCHAR2(20))
FROM XMLTable('"one","two","three"'))
1
---
1
in order to make it comparable with a literal(such as 'one').
Moreover, CAST might be replaceable with XMLCast as well.
You do not need XML to split the string and can use simple (fast) string functions:
WITH data (value) AS (
SELECT 'one,two,three' FROM DUAL
),
bounds (value, spos, epos) AS (
SELECT value, 1, INSTR(value, ',', 1)
FROM data
UNION ALL
SELECT value, epos + 1, INSTR(value, ',', epos + 1)
FROM bounds
WHERE epos > 0
)
SEARCH DEPTH FIRST BY value SET order_id
SELECT CASE epos
WHEN 0
THEN SUBSTR(value, spos)
ELSE SUBSTR(value, spos, epos-spos)
END as item
FROM bounds;
Which outputs:
ITEM
one
two
three
However
In your case you have an XY-problem and you DO NOT NEED to split the string as you can use LIKE to match the search string against a sub-string of your list:
SELECT 1
FROM dual
WHERE ',' || :your_list || ',' LIKE '%,' || :search_value || ',%';
or with hardcoded strings:
SELECT 1
FROM dual
WHERE ',' || 'one,two,three' || ',' LIKE '%,' || 'one' || ',%';
db<>fiddle here
Query that raised an error - if rewritten to this - works:
SQL> select 1
2 from dual
3 where 'one' in (select regexp_substr('one,two,three', '[^,]+', 1, level)
4 from dual
5 connect by level <= regexp_count('one,two,three', ',') + 1
6 );
1
----------
1
SQL>
Subquery (that uses regexp_substr) splits a comma-separated list of values ('one,two,three') into rows.
Alternatively, if you use Oracle Apex (or have it installed in your database), you can simplify it by utilizing apex_string.split:
SQL> select 1
2 from dual
3 where 'one' in (select * from apex_string.split('one,two,three', ','));
1
----------
1
SQL>
You could use REGEXP_COUNT to find your word in the list.
This would be faster than converting
But read this canonical thread Is storing a delimited list in a database column really that bad?
SELECT
CASE WHEN REGEXP_COUNT('one,two,three', '^([^,]+,)*one(,[^,]+)*$', 1, 'i') > 0
THEN 1 ELSE 0
END as cnt
FROM DUAL;
| CNT |
| --: |
| 1 |
db<>fiddle here
I'm trying the following query from DBeaver (backend is oracle):
SELECT * FROM mytable where mycolumn in (REPLACE( :req_id_list, CHR(13), ','))
when it prompts for the value of req_id_list I want to paste the values from Excel, which will be one value per line. the query is failing with ORA-00907: missing right parenthesis. is there a way to convert the multiline value to a CSV one ?
I don't use DBeaver so this is a SQL*Plus example. Basically, you'll have to "split" that multi-line input value into separate rows (that's what subquery in lines #8 - 10 does):
Declaring a bind variable:
SQL> var req_id_list varchar2(20)
Storing A + carriage return + C into it:
SQL> exec :req_id_list := 'A' || chr(13) || 'C';
PL/SQL procedure successfully completed.
Query itself (lines #1 - 5 represent sample data; I expect A and C to be returned as that's what I passed to req_id_list):
SQL> with mytable (mycolumn) as
2 (select 'A' from dual union all
3 select 'B' from dual union all
4 select 'C' from dual
5 )
6 select *
7 from mytable
8 where mycolumn in (select regexp_substr(replace(:req_id_list, chr(13), '#'), '[^#]+', 1, level)
9 from dual
10 connect by level <= regexp_count(:req_id_list, chr(13)) + 1
11 );
M
-
A
C
SQL>
In my database, special characters have got inserted with these ASCII values
ASCII(' ') ASCII('')
49828 32
There is ASCII Value 49828 shown in the column description that is showing as special character ¤
How do I find all the values that have this special character? and how to replace it with a regular space (ASCII 32)
I'd say you'd use REPLACE (as you said).
Sample table:
SQL> create table test (col) as
2 select 'x' || chr(67) || 'y' from dual union all
3 select 'x' || chr(49828) || 'y' from dual;
Table created.
Contents (disregard Ą displayed in my SQL*Plus & my database):
SQL> select * from test;
COL
----
xCy
xĄy
Update only rows that contain that value:
SQL> update test set
2 col = replace(col, chr(49828), chr(32))
3 where instr(col, chr(49828)) > 0;
1 row updated.
Result:
SQL> select * from test;
COL
----
xCy
x y
SQL>
I have some problem here. I got to SELECT a column which the result i.e. '01201698765'. How to split this number to becoming like this : '01.2016.98765'.
I've used TO_CHAR, but the '0' (zero) number at the front was gone.
You could use:
SUBSTR
concatenation operator ||
For example,
SQL> WITH sample_data AS(
2 SELECT '01201698765' num FROM dual
3 )
4 --end of sample_data mimicking real table
5 SELECT num,
6 substr(num, 1, 2)||'.'||substr(num, 3, 4)||'.'||substr(num, 7) num_formatted
7 FROM sample_data;
NUM NUM_FORMATTED
----------- -------------
01201698765 01.2016.98765
SQL>
Assuming the column is a string, just use string operations:
select substr(col, 1, 2) || '.' + substr(col, 3, 4) + '.' + substr(col, 5, 5)
The original format:
123-456-7890
My goal format:
(123)456-7890
I wanted to go the route of concatenating between substrings but I continually get flagged for errors. I am unsure of a better method to go about implementing a way to format.
My query:
select || '(' || substr(telephone,0, 3)|| ')' ||
substr(telephone,4, 3)|| ' '||
substr(telephone,7, 4)) as telephone,
from book;
My current error:
"missing expression"
You have an extra dangling parenthesis at the end of your SELECT, and you also have a dangling concatenation operator || in the front. Try this:
SELECT '(' || SUBSTR(telephone, 0, 3) || ')' ||
SUBSTR(telephone, 4, 3) || ' ' || SUBSTR(telephone, 7, 4) AS telephone
FROM book
Update:
You should really use this query, because it turns out you also had a problem with forming your desired output as well:
SELECT '(' || SUBSTR(telephone, 1, 3) || ')' || SUBSTR(telephone, 5, 8) AS telephone
FROM book
You can use regular expressions to do.
select regexp_replace
(phoneNo,
'([[:digit:]]{3})\-([[:digit:]]{3})\-([[:digit:]]{4})',
'(\1)\2-\3'
)
from(
select '123-456-7890' as phoneNo from dual)
Output
(123)456-7890
SELECT '123-456-7890','('||SUBSTR('123-456-7890',1,3)||')'||SUBSTR('123-456-7890',5,8) FROM dual;
Using SUBSTR:
SQL> WITH sample_data AS(
2 SELECT '123-456-7890' num FROM dual
3 )
4 -- end of sample_data mimicking real table
5 SELECT num,
6 '('
7 || SUBSTR(num, 1, 3)
8 ||
9 ')'
10 || SUBSTR(num, 5, 8) AS my_num
11 FROM sample_data;
NUM MY_NUM
------------ ---------------
123-456-7890 (123)456-7890
SQL>
Remember, the index for SUBSTR starts from 1. It is bad practice to use 0 as starting index.
You could also do it using REGEXP_REPLACE.
Pattern: (\d{3})(-)(\d{3})(-)(\d{4})
Expression: regexp_replace(num, '(\d{3})(-)(\d{3})(-)(\d{4})', '(\1)\3\4\5')
For example,
SQL> WITH sample_data AS(
2 SELECT '123-456-7890' num FROM dual
3 )
4 -- end of sample_data mimicking real table
5 SELECT num,
6 regexp_replace(num, '(\d{3})(-)(\d{3})(-)(\d{4})', '(\1)\3\4\5') my_num
7 FROM sample_data;
NUM MY_NUM
------------ ---------------
123-456-7890 (123)456-7890
SQL>