Oracle REGEXP_SUBSTR extracts strings by blank when there are multiple blanks - oracle

Hi I'm new to Oracle SQL, I want to extract LiIon Polymer from 6Cell LiIon Polymer.
I use REGEXP_SUBSTR('6Cell LiIon Polymer', '\S+', 7) but it only returns LiIon

You want substring that follows the first space? Use good, old substr + instr combination. Sample data first, query you might be interested in begins at line #4.
SQL> with test (col) as
2 (select '6Cell LiIon Polymer' from dual)
3 --
4 select substr(col, instr(col, ' ') + 1) result
5 from test;
RESULT
-------------
LiIon Polymer
SQL>

Using Regular expression and without hardcoding
select REGEXP_SUBSTR('6Cell LiIon Polymer', '[^\S]+', instr('6Cell LiIon Polymer', ' '), 1) from dual;

Related

How to evaluate an expression in one table field into another?

I have a table, inside there is a field called x, the x field contain value of '1+2', '1+3' etc, how to get these value and calculate it and save into another field?
For simple arithmetic expressions - and depending on your Oracle version - you could use xmlquery to evaluate. Note that / has special meaning in xml, the operator for division is the keyword div - so you need a replace in case you may have forward slashes in the arithmetic expression. (If you don't have any divisions, you can simplify the query by removing the call to replace.)
Here is an example - including the test data at the top, in a with clause (not part of the solution!)
with
test_data (str) as (
select '1 + 3' from dual union all
select '3 * 5 - 2' from dual union all
select '2/4*6' from dual union all
select '3 * (1 - 3)' from dual
)
select str, xmlquery(replace(str, '/', ' div ') returning content).getNumberVal()
as evaluated_expression
from test_data;
STR EVALUATED_EXPRESSION
----------- --------------------
1 + 3 4
3 * 5 - 2 13
2/4*6 3
3 * (1 - 3) -6
If you only have valid PL/SQL arithmetic expressions in your formulas, then you can use EXECUTE IMMEDIATE to evaluate them.
For this, you'll need to create a function:
create or replace function eval_expression(p_expression in varchar2)
return number is
query varchar2(100);
result number;
begin
query := 'select ' || p_expression || ' from dual';
execute immediate query
into result;
return result;
end eval_expression;
Then you can use this function in UPDATE query:
update t
--val is another field
set t.val = eval_expression(t.x)
Naturally, with EXECUTE IMMEDIATE this query won't be extremely efficient, but it'll work. Also, with dynamic queries we're going into unsafe territory, so make sure that you don't have malicious code among your formulas.
Also, see "Evaluate Expression" on Ask TOM. Tom Kyte used a slightly more civilized approach (dbms_sql package) and created a package with a single variable support.
If the case you have mentioned needs to be considered then I will suggest you use the following query:
select
xmlquery('3+4'
returning content
).getNumberVal()
from
dual;
If More operators are involved except division then the aforementioned query will work but if the division operator is also involved then you must have to replace "/" with " div " keyword. Something like the following:
select
xmlquery(
replace( '20/5', '/', ' div ')
returning content
).getNumberVal()
from
dual;
Now, you can use it in your update statement or anywhere else.
update tab
set tab.result_column_name = xmlquery(t.your_expr_column_name
returning content
).getNumberVal()
update tab
set tab.result_column_name = xmlquery(
replace( t.your_expr_column_name, '/', ' div ')
returning content
).getNumberVal()
Demo
Cheers!!

How substr works on dates

I am trying to understand a query in my application where it uses substr function.
I have gone through the documentation for substr, which looks simple and clear.
Now below is my query without using substr:
select last_day(to_date(to_char(add_months(TO_DATE('2004/10/25', 'yyyy/mm/dd'),1),'YYYY')||'0201','YYYYMMDD')) from dual;
This gives me result as 2/29/2004. The above query just returns last day of Feb in simple words.
Now I am using substr as below:
select substr(last_day(to_date(to_char(add_months(TO_DATE('2004/10/25', 'yyyy/mm/dd'),1),'YYYY')||'0201','YYYYMMDD')),5,1) from dual;
So here the start value is 5 & length is 1, so I am expecting output as 2 looking at 2/29/2004. but the actual output is E, I am not clear from where this E is coming as result.
You cannot use SUBSTR() on DATE values. SUBSTR() works only on strings!
When you run SUBSTR({DATE_VALUE}, ...) then Oracle actually does following:
SELECT
SUBSTR(
TO_CHAR(
{DATE_VALUE}, (SELECT VALUE FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT')
), ...
)
FROM dual;
What is the purpose of this query? Do you like to find out whether input year is a leap-year?
Try this instead -
select substr(to_char(last_day(to_date(to_char(add_months(TO_DATE('2004/10/25', 'yyyy/mm/dd'),1),'YYYY')||'0201','YYYYMMDD')),'dd/mm/yyyy'),5,1)
from dual;

How to replace positions in a number by special characters in oracle?

My table contain column name accountnumber;
acctnum
-------
1234556777
2335678000
i want an output using oracle using sql query
acctnum
---------
123xxx6777
233xxx8000
i tried replace function ,but i did not get the output.pls help.
If I did not understand wrong, This maybe help you?
with a as
(select '1234567' as acctnum from dual)
select '###' || substr(acctnum,4) from a;
If you're trying to replace characters 4, 5 and 6 with an x you can do it with the SUBSTR function like this:
SELECT SUBSTR(acctnum, 1, 3) || 'xxx' || SUBSTR(acctnum, 7) AS acctnum
FROM mytable;

How to add new line separator into data for oracle

I'm working on displaying data from oracle.
is there a way to make the following data inside the table:
example :
'1.somedata, 2.somedata, 3.somedata, 4.somedata, 5.somedata'
to display like:
example:
'1. somedata
2. somedata
3. somedata
4. somedata
5. somedata'
on the interface?
do i add new line separator directly into the data?
or do i separator them into new line when i query it?
or is there any other simple way?
Thanks.
There are so many ways to do this, here is one if you are selecting from a column:
SELECT REPLACE ('1.somedata, 2.somedata, 3.somedata, 4.somedata, 5.somedata', ',', CHR (13) || CHR (10)) AS split
FROM DUAL;
1.somedata
2.somedata
3.somedata
4.somedata
5.somedata
I personally would use the listagg function and use '' as the delimiter.
SELECT LISTAGG(last_name, ' ')
WITHIN GROUP (ORDER BY hire_date, last_name) "Emp_list",
MIN(hire_date) "Earliest"
FROM employees
WHERE department_id = 30;
Remember that Apex is generating a web page, which means the end result is HTML. Apex, however, will also sometimes escape special HTML characters for you, like < and &. Since you're viewing a table, I assume the source of your data is a query and your "somedata" field is a single column. Try this:
SELECT REPLACE( somedata_column, ',', '<br />' )
FROM mytable
You don't say what version of Apex. In Apex 4.x, the column would need to be set to a Standard Report Column, which would stop Apex from the <br> elements. I forget what the column type is in Apex 5.x.
Check below sample query which converts coma separated list data into rows
SELECT substr( '1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,',
( case when rownum = 1 then 1
else instr( '1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,', ',', 1, rownum - 1 ) + 1
end ),
instr( substr( '1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,',
( case when rownum = 1 then 1
else instr( '1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,', ',', 1, rownum - 1 ) + 1
end )
), ',' ) - 1
) as data
FROM dual
CONNECT BY LEVEL <= length( '1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,' ) - length ( replace('1.AL,2.AL,3.AL,4.AL,5.AL,6.AL,', ',') )
Hope this will help you!

Oracle statement

Tables records as below
D:\HOME\DOC\FILE\2001\12\TT-12S2Q99-EE-EE1.pdf
D:\HOME\DOC\FILE\2002\02\TT-12S2Q94-EE-EE1.xml
D:\HOME\DOC\FILE\2005\05\TT-12S2Q98-EE-EE1.pdf
D:\HOME\DOCS\TEMPFILE\TT-12S2Q88-EE-EE1.pdf
I want to extract those file names only. The result should be
TT-12S2Q99-EE-EE1
TT-12S2Q94-EE-EE1
TT-12S2Q98-EE-EE1
TT-12S2Q88-EE-EE1
Anyone can give me a hand ?
You can use INSTR with the third parameter negative to search backwards in the string from the end (something I didn't know you could do until a few minutes ago). Combine that with a SUBSTR and you should have what you want:
SQL> select filename from mytable;
FILENAME
--------------------------------------------------------------------------------
C:\path\to\some\file.txt
SQL> select substr(filename, instr(filename, '\', -1) + 1) from mytable;
SUBSTR(FILENAME,INSTR(FILENAME,'\',-1)+1)
--------------------------------------------------------------------------------
file.txt
Take a look at the SUBSTR and INSTR functions.
If you're still stuck after that, post your best attempt at what you've done.

Resources