how to fetch the after certain special character - oracle

I have a string 1234567789#9010.I want to fetch the value after #.In this case I want 9010.so I have written below function
res:=substr(str,charindex(str'#',1),length(str));
then the result is coming correctly but if string is having only 1234567789 then result is coming 12345677891234567789 .if the string does not have '#' then it should fetch 1234567789.

Using REGEXP_REPLACE comes to mind:
SELECT REGEXP_REPLACE(val, '^.*#', '')
FROM yourTable;
We could also use REGEXP_SUBSTR with a capture group:
SELECT REGEXP_SUBSTR(val, '#(.*)$', 1, 1, NULL, 1)
FROM yourTable;

Related

Oracle string operation to exclude specific characters based on delimiter

From the String ES-123456-PSA Spain-101, I need to extract only ES-123456-101 Delimiter position is fixed.
Tried REGEXP_SUBSTR('ES-123456-PSA Spain-101','[^-]+',2,3 ) which gives PSA Spain.
Is there a way to ignore those specific characters and returns rest of them.
If you want ES-123456-101 then use this:
SELECT REGEXP_REPLACE('ES-123456-PSA Spain-101', '[^-]+-', '', 1, 3 )
FROM dual;
If you want ES-12345-101 then could you explain the logic for 12345 not 123456? Typo or omit the last character?
you can also use subtr and instr
with t as
(
select 'ES-123456-PSA Spain-101' as text from dual
)
select substr(text,1,instr(text,'-',1,2)) -- ES-123456-
||substr(text,instr(text,'-',1,3)+1) -- 101
from t

pl/sql save hierarchical query to variable

I am trying to save result set of hierarchical query to variable
CREATE OR REPLACE FUNCTION test12
RETURN number IS
result number(4):=0;
clli_array dbms_sql.varchar2_table;
BEGIN
with tmp as (select 'strforregexp' str from dual)
select regexp_substr(str, '\/([A-Z0-9]{11}|[A-Z0-9]{8})', 1, level) STR into :clli_array from tmp
connect by regexp_substr(str, '\/([A-Z0-9]{11}|[A-Z0-9]{8})', 1, level) is not null;
END test12;
But getting an error
Error(9,9): PLS-00049: bad bind variable 'CLLI_ARRAY'
So, i have 2 questions
1) can i get all matches of regexp witohout hierarchical query
2) why i am getting an error
As #APC pointed out, the first problem is that you've got a colon in front of CLLI_ARRAY. This causes the PL/SQL compiler to believe that CLLI_ARRAY is going to be a SQL*Plus substitution variable, and when it finds that such a variable is not defined it throws the error you got.
However, even if you remove the colon you're not out of the woods yet. Once you remove the colon you'll get
PLS-00597: expression 'CLLI_ARRAY' in the INTO list is of wrong type
That's because CLLI_ARRAY is a PL/SQL-type collection, but your statement returns a single string.
What you probably want to do is to use BULK COLLECT to have the system retrieve all the results of the query into your VARCHAR2_TABLE:
with tmp as (select 'strforregexp' str from dual)
select regexp_substr(str, '\/([A-Z0-9]{11}|[A-Z0-9]{8})', 1, level) STR
BULK COLLECT into clli_array
from tmp
connect by regexp_substr(str, '\/([A-Z0-9]{11}|[A-Z0-9]{8})', 1, level) is not null
Best of luck.

Extract sub-string after match in oracle

I have string like Order#Confirm####2791 i wanted to fetch 2791 after #### delimiter. I tried below one not getting exact sub-string what i am expecting to return.
SELECT regexp_substr('Order # Confirm ####2791','[^####]+',1,2) regexp_substr
FROM dual;
I would like to return 2791 from above query.
SELECT regexp_substr('Order # Confirm ####2791','####(.*)$',1,1, null, 1) regexp_substr
FROM dual;
If you want to restrict the match to digits:
SELECT regexp_substr('Order # Confirm ####2791','####(\d+)$',1,1, null, 1) regexp_substr
FROM dual;
regexp_replace works too:
SELECT regexp_replace('Order # Confirm ####2791','.*?####(\d+)$', '\1') regexp_replace
FROM dual;
Note with regexp_substr() if a match is not found NULL is returned and with regexp_replace() if a match is not found the original string is returned.
You don't need regular expressions for this.
SELECT substr('Order # Confirm ####2791',
instr('Order # Confirm ####2791', '####') + 4) as your_substr
FROM dual;

Using REGEXP_SUBSTR to get certain string

I have trouble of getting the following Numbers only from the given string:
Taid-HP- VSAT -100021258856985847585 - BMN
I want the result to be
100021258856985847585
I used teh REGEXP in all ways but i could not
If you want string between 3rd and 4th -, use this
select trim(regexp_substr(str, '(.*?-){3}(.*?)-', 1, 1, '', 2)) from
(select 'Taid-HP- VSAT -100021258856985847585 - BMN' as str from dual)
Referred this answer
Get value between 2nd and 3rd comma

Oracle invalid number in clause

I'm struggling with getting a query to work, and I could really use some help. We have an in house app that we use for building small web apps where I work. It's basically a drag and drop GUI. There's functionality built in to access query string values using the key.
I'm passing a comma separated list of values into a page through the query string. I'm then trying to use the list of values as part of an in clause in a query.
I can see that the value is correct in the query string.
orders=1,2,3
Here's the specific part of the query
"AND OrderNumber IN (this is where it maps from the query string)
I've tried running similar queries in Toad, and I think I've found the issue. It's giving an invalid number error, and I think it's wrapping the query string value in single quotes. I can replicate the error when I do "AND OrderNumber IN ('1,2,3')" in Toad.
Here's where I get really confused. The following works in Toad.
"AND OrderNumber IN ('1','2','3')"
So I tried recreating that by doing
select replace('1,2,3', ',', chr(39)||','||chr(39)) from dual;
I have confirmed that returns '1','2','3' in Toad.
However, I still get an Invalid Number error when I run the following in Toad.
AND OrderNumber IN (replace('1,2,3', ',', chr(39)||','||chr(39))
I've been racking my brain over this, and I can't figure it out. It seems to me that if "AND OrderNumber IN ('1','2','3')" works, and replace('1,2,3', ',', chr(39)||','||chr(39)) returns '1','2','3', that "AND OrderNumber IN (replace('1,2,3', ',', chr(39)||','||chr(39))" should work.
Any help you might be able to offer on this would be greatly appreciated. I know the rest of the query works. That's why I didn't post it. I'm just stuck on trying to get this IN clause working.
A change to phonetic_man's answer that will allow for NULL elements in the list. The regex format of '[^,]+' for parsing delimited lists does not handle NULL list elements and will return an incorrect value if one exists and thus its use should be avoided. Change the original by deleting the number 2 for instance and see the results. You will get a '3' in the 2nd element's position! Here's a way that handles the NULL and returns the correct value for the element:
SELECT TRIM(REGEXP_SUBSTR(str, '(.*?)(,|$)', 1, LEVEL, NULL, 1)) str
FROM ( SELECT '1,,3,4' str FROM dual )
connect by level <= regexp_count(str, ',') + 1;
See here for more info and proof: https://stackoverflow.com/a/31464699/2543416
Can you try the following query.
SELECT * FROM orders
WHERE orderno IN
(
SELECT TRIM(REGEXP_SUBSTR(str, '[^,]+', 1, LEVEL)) str
FROM ( SELECT '1,2,3,4' str FROM dual )
CONNECT BY INSTR(str, ',', 1, LEVEL - 1) > 0
)
The inline query splitting the string in different rows. So, on executing it you will get the following result.
SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL)) str
FROM ( SELECT '1,2,3,4' str FROM dual )
CONNECT BY instr(str, ',', 1, LEVEL - 1) > 0
1
2
3
4
Now, passing this result to the main query IN clause should work.
I think the desired clause to be built is:
AND OrderNumber IN (1,2,3)
A numeric list. The example you tested:
AND OrderNumber IN ('1','2','3')
works because an implicit conversion from a VARCHAR2 to a NUMBER is occurring for each element in the list.
The following clause will not work because no implicit conversion of the string '1,2,3' can be made (note the clause has a single string element):
AND OrderNumber IN ('1,2,3')
When doing a replace, you are converting the single string: 1,2,3 with the single string: 1','2','3 and this single string cannot be implicitly converted to a number.

Resources