REGEXP_SUBSTR return all matches (mariaDB) - mariadb

I need to get all the matches of a regular expression in a text field in a MariaDB table. As far as I know REGEXP_SUBSTR is the way to go to get the value of the match of a regular expression in a text field, but it always returns after the first match and I would like to get all matches.
Is there any way to do this in MariaDB?
An example of the content of the text field would be:
#Generation {
// 1
True =>
`CP?:24658` <= `CPV?:24658=57186`;
//`CP?23432:24658` <= `CPV?:24658=57186`
// 2
`CP?:24658` <> `CPV?:24658=57178` =>
`CP?:24656` <> `CPV?:24656=57169`;
And the select expression that I'm using right now is:
select REGEXP_SUBSTR(textfield,'CP\\?(?:\\d*:)*24658') as my_match
from table
where id = 1243;
Which at the moment returns just the first match:
CP?:24658
And I would like it to return all matches:
CP?:24658
CP?23432:24658
CP?:24658

Use just REGEXP to find the interesting rows. Put those into a temp table
Repeatedly process the temp table -- but remove the SUBSTR as you use it.
What will you be doing with each substr? Maybe that will help us devise a better approach.

Related

how to search for a particular string in the given string in oracle

I have a string with value as '12A,12B,12C,13,14'.
I want to check whether '2A' is available in the above string.
while trying my value '2A' checks in 12A and returns as matched.
Please give me a solution for this.
You can do something like this:
select * from table where ',' || col || ',' like '%,2A,%';
Commas are concatenated to the column to cover the cases where the element is present at the start or end of the string.

Neo4j Cypher extracting data from collection using 'and/or' logical operators

I have a collection and I need to extract a name and id from each node and return them together to avoid post processing. I am trying:
extract(c IN nodes(c)| c.name +\': \'+ c.id) as results
The problem is that when a node without a name value is encountered it doesn't return anything.
Is there a way like 'and/or' to make the c.name optional allowing it to still return the c.id and a NULL for c.name?
Thanks
I would have thought at first that you could use toString to turn nulls into an empty string, but that doesn't seem to work. coalesce should help, though:
extract(c IN nodes(c)| coalesce(c.name, '') +\': \'+ c.id) as results

extract some characters with instr

in pl/sql
I have these text:
${cat};${dog};
I would like to extract these:
${dog}
I'm trying with instr but allways shows me the last semicolon with these:
SELECT substr(field,instr(field,'$',1,2),instr(field,';',1,2)-1),...
Any help please
the function is defined as substr(str, pos, len), so you have to subtract the positions in the 3rd argument as substr(str, pos1, pos2 - pos1)
Not sure if it's what you need, but I would code this:
select substr('${cat};${dog};'
,instr('${cat};${dog};',';',1,1)+1
,instr('${cat};${dog};',';',1,2)-instr('${cat};${dog};',';',1,1)-1
)
from dual;
If looking for the second item in the list, here's a way using REGEXP_SUBSTR() to return the 2nd occurrence of a set of zero or more characters that are not a semi-colon, where they are followed by a semi-colon or the end of the line. This allows for a NULL value in the list:
select REGEXP_SUBSTR('${cat};${dog};', '([^;]*)(;|$)', 1, 2, NULL, 1) from dual;
Even better, make the call to REGEXP_SUBSTR generic and put it into a stored function that you pass a string, the element you want and the delimiter and have it return the string.
Benefits:
- Logic and code is encapsulated in a reusable function all can use without having to understand the regular expression syntax (but still get the power from it)
- There is a consistent, simple way to call it
- Code becomes MUCH easier to follow/debug
- If it needs to change there is only one place to change it
- A particular element of a list can be SELECTed
- An element of a list can be used in a WHERE clause
Here is the function definition itself:
FUNCTION GET_LIST_ELEMENT(string_in VARCHAR2, element_in NUMBER, delimiter_in VARCHAR2 DEFAULT ',') RETURN VARCHAR2 IS
BEGIN
RETURN REGEXP_SUBSTR(string_in, '([^\'||delimiter_in || ']*)(\'||delimiter_in||'|$)', 1, element_in, NULL, 1);
END GET_LIST_ELEMENT;

MS Access IIF Field Exists

I am creating a report from a query where a field ABC is displayed as CAT if yes and as MOUSE if no. But unfortunately, when there are instances where the table inside the query does not contain field ABC, the report generates a error pop-up. Is there any way to by-pass this and run the report with other fields excluding the missing field?
I heard that IIF Exist function could help, but I am really blank here. I wrote the access query like below:
Iif (fieldExists(iif([ABC]=5, 'CAT', 'MOUSE'),iif([ABC]=5, 'CAT', 'MOUSE'), '')) AS TOMnJERRY
This function is maybe the shortest one to test if a field exists in Access:
Function FieldExists(ByVal Table As String, ByVal Field As String) As Boolean
On Error Resume Next
FieldExists = (DCount(Field, Table) >= 0)
End Function
How it works:
If the field exists, the expression (DCount(Field, Table) >= 0) is obviously always true, because DCount never returns a negative value. If the field doesn't exist, an error will occur and the program will jump to the next line without setting the return variable FieldExist, so this one will keep at default and this is false.
So the solution for your problem should look like this:
Iif (FieldExists('YourTable','ABC'), iif([ABC]=5, 'CAT', 'MOUSE'), '')

Using prepared statements and full-text-search in SQLite

I'm using the SQLite C interface to write an application. Since I like security, I'm using prepared statements to query the database. In one such query, I'm selecting rows from a virtual database using the MATCH keyword for full-text-searching. Here's an example:
SELECT * FROM Emails
WHERE ( Subject LIKE ?001 OR ?001 IS NULL )
AND ( Author LIKE ?002 OR ?002 IS NULL )
AND ( Body MATCH ?003 OR ?003 IS NULL )
This allows the user to enter any terms (Subject, Author, or Body) individually or in any combination to do a search. Any term that isn't entered, I'll bind NULL to that parameter. The problem with that statement is that you can't use the OR keyword with the MATCH keyword. I'm looking for a statement I can use with the MATCH keyword to return all rows if not searching in the Body column. Is there such a statement?
I suggest the following:
SELECT * FROM emails
WHERE ...
AND ( CASE (SELECT COUNT(*) FROM emails WHERE body MATCH ?003)
WHEN 0 THEN 1
ELSE body MATCH ?003
END )
I ended up modifying the SQL statement at runtime to replace MATCH with LIKE '%'. Not very elegant, but it works for now.

Resources