What's wrong with this query? Paths - mysql

I'm trying to get info from a table using a browser path column in the table. This is what the query looks like:
select * from selwowscheduler sc
join browser b on sc.scheduledbrowser = b.browserid
where b.browserpath like '*iexplore C:\Program Files\Internet Explorer\iexplore.exe'
Thing is, this returns nothing. I can put %iexplore.exe instead of *iexplore C:\Program Files\Internet Explorer\iexplore.exe and that returns something (though more than I want).
I thought maybe it was the literals \ so I replaced the \ with \\, but that didn't work either (Still returns nothing).
Does anyone know why this isn't working?
Thanks.
EDIT: I know * is not a wild card, it is part of what is on the path. We use it to initiate different browsers on different PCs.

You have to escape a backslash like that \\\\. Try:
where b.browserpath like '%iexplore C:\\\\Program Files\\\\Internet Explorer\\\\iexplore.exe'

The problem is with the the Like syntax what is the * supposed to be matching against because * is not a special character % means match any character 0 or more and _ means match any one character.
Also if you cannot use like to accomplish what you need I would look into Regexp which uses regular expressions to match against and are usually more adaptable then simple Like comparisons

Well first off * is not a valid wildcard for mysql as near as I can tell which is why the query returns nothing (it is looking for a path with '*' in it). My guess without knowing exactly what you are looking for is that some variant of the % wildcard would work. It can be in the middle of the string such as:
where b.browserpath like 'C:%iexplore'
This would return all paths on "C" that end in iexplore. This:
where b.browserpath like 'C:\Program Files%.exe'
returns the paths to anything on "C:\Program Files" that has an ending of ".exe" and so on.

Related

How to use regex flags in Mariadb's regexp_replace?

I have a table with records. A record has a field content that contains some html like <p><img src=\"/pictures/image.jpg\" vspace=\"6\" hspace=\"6\" align=\"left\" alt=\"Alt text\" title=\"Title Text\" width=\"260\"> Some text content...
I need to remove <a></a> tags that are now placed around <img>. There can be multiple <a><img></a> occurrences in the string. I kinda made a corresponding regexp and learnt about REGEXP_REPLACE function. Ideally I expect something like
UPDATE table_name SET content = REGEXP_REPLACE(content, '/<a\shref=\\?"\/pictures\/.+">(<img.+">)<\/a>/gmU', '\\1') WHERE id=1
to work out, but it doesn't. I don't understand where to put flags gmU. Also in the articles/docs I found on the internet I don't see flags like g (global) and U (ungreedy). Is it global and ungreedy by default? How to make it all work?
10.3.15-MariaDB.
In MariaDB you pass flags to REGEXP_REPLACE by in-lining them in the regex using (?x) notation, where x is the flag. REGEXP_REPLACE by default replaces all occurrences of pattern in the string, so you don't need the g flag; nor in your case do you need the multi-line flag m as you are not attempting to use beginning/end of line anchors. You can use U though in place of the ? modifier to make + non-greedy.
There's a couple of issues with your regex:
MariaDB does not require regexes to be contained with /
\s represents a literal s and needs to be \\s
To match a literal \ you need to use \\\\, not \\
This regex should give you the results you want:
(?U)<a\\s.*href=\\\\?"/pictures.+(<img.+>)</a>
In a query:
SELECT REGEXP_REPLACE(content, '(?U)<a\\s.*href=\\\\?"/pictures.+(<img.+>)</a>', '\\1')
FROM test
Demo on dbfiddle

MySQL REGEXP_SUBSTR() escaping issue?

Please take the following example regex:
https://regexr.com/4ek7r
As you can see, the regex works great and matches the sizes (e.g. 3/16" etc) from the product descriptions.
I'm trying to implement this in MySQL 8.0.15 using REGEXP_SUBSTR()
As per the documentation I have doubled up the escape characters but the regex is not working.
Please see the following SQL fiddle:
https://www.db-fiddle.com/f/e6Ez3XCdU5Ahs91z6TQA8P/0
As you can see, REGEXP_SUBSTR() returns NULL
I'm presuming this is an escape issue - but i'm not 100% sure.
How can I ensure MySQL returns the 1st match per product (row) akin to the regexr.com example?
Cheers
Edit: 28/05/2019 - root cause
Wiktor's answer below solved my problem and his regex was much cleaner & well worth the upvote. That said, i didn't understand why my original version was not working after the port from SQL Server to MySQL. I finally noticed the problem this morning - it had nothing to do with the regex, it was a rookie error in string concatenation! Specifically, I was using UPPER(Description + ' ') (i.e. using +) - which works fine in SQL Server but obviously; MySQL forces numeric! So i was essentially running my regex against a 0! Replacing the + with CONCAT actually fixed my original query with original regex - just thought i'd share this in case it helps anyone else!
In MySQL v8.x that supports ICU regex, you may use
SELECT Description, REGEXP_SUBSTR(Description, '(?im)(?=\\b(?:[0-9/]+(?:\\.[0-9/]+)?\\s*(?:[X-]|$)|[0-9/\\s]+(?:\\.[0-9/]+)?(?:[CM]?M|["”TH])))[0-9/\\s.]+(?:[CM]?M|["”TH])?(?:\\s*[/X-]\\s*[0-9/\\s.]+(?:[CM]?M|["”TH])?)?(?=[.\\s()]|$)') AS Size FROM tbl_Example
The main points:
The flags can be used as inline options, (?mi), m will enable multiline mode when ^ and $ match start/end of a line and i will enable case insensitive mode
[$] matches a $ char, to match end of a line position, you need to move $ out of a character class, use alternations in this case ((?=[\.\s\(\)$]) -> (?=[.\s()]|$), yes, do not escape what does not have to be escaped, too)
Matching fractional number part, it is better to use a (?:\.[0-9/]+)? like pattern (it matches an optional sequence of . and then 1 or more digits or /s)
(C|M)? is better written as [CM]? (a character class is more efficient)

What is the purpose of using WHERE COLUMN like '%[_][01][7812]' in SQL statements?

What is the purpose of using WHERE COLUMN like '%[_][01][7812]' in SQL statements?
I get some result, but don't know how to use properly.
I see that it is searching through the base, but I don't understand the pattern.
Like selects strings similar to a pattern. The pattern you're looking at uses several wildcards, which you can review here: https://www.w3schools.com/SQL/sql_wildcards.asp
Briefly, the query seems to ba matching any row where COLUMN ends in an _ then a 0 or a 1, then a 7,8,1, or 2. (So it would match 'blah_07' but not 'blah_81', 'blah_0172', or 'blah18')
First thing as you might be aware that where clause is used for filtering rows.
In your case (Where column Like %[_][01][7812]) Means find the column ending with [_][01][7812] and there could be anything place of %
declare
#searchString varchar(50) = '[_][01][7812]',
#testString varchar(50) = 'BeginningOfString' + '[_][01][7812]' + 'EndofString'
select CHARINDEX(#searchString, #testString), #testString, LEN(#testString) as [totalLength]
set #testString = '[_][01][7812]' + 'EndofString'
select CHARINDEX(#searchString, #testString), #testString, LEN(#testString) as [totalLength]
set #testString = 'BeginningOfString' + '[_][01][7812]'
select CHARINDEX(#searchString, #testString), #testString, LEN(#testString) as [totalLength]
Although you've tagged your post MySQL, that code seems unlikely to have been written for it. That LIKE pattern, to me, resembles Microsoft SQL Server's variation on the syntax, where it would match anything ending with an underscore followed by a zero or a one, followed by a 7, an 8 a 1 or a 2.
So your example 'TA01_55_77' would not match, but 'TA01_55_18' would, as would 'GZ01_55_07'
(In SQL Server, enclosing a wildcard character like '_' in square brackets escapes it, turning it into a literal underscore.)
Of course, there may be other RDBMSes with similar syntax, but what you've presented doesn't seem like it would work on the data you've got if running in MySQL.

MySQLAdmin replace text in a field with percent in text

Using MySQLAdmin. Moved data from Windows server and trying to replace case in urls but not finding the matches. Need slashes as I don't want to replace text in anything but the urls (in post table). I think the %20 are the problem somwhow?
UPDATE table_name SET field = replace(field, '/user%20name/', '/User%20Name/')
The actual string is more like:
https://www.example.com/forum/uploads/user%20name/GFCI%20Stds%20Rev%202006%20.pdf
In a case you are using MariaDB you have REGEXP_REPLACE() function.
But best approach is to dump the table into the file. Open it in a Notepad ++
and run regex replace like specified on a pic:
Pattern is: (https:[\/\w\s\.]+uploads/)(\w+)\%20(\w+)((\/.*)+)
Replace with: $1\u$2\%20\u$3$4
Then import the table again
Hope this help
If its MariaDB, you can do the following:
UPDATE table_name SET field = REGEXP_REPLACE(field, '\/user%20name\/', '\/User%20Name\/');
First, please check, what is actually stored in the database: %20 is a html-entity which represents a whitespace. Usually, when you are storing this inside the database, it will be represented as an actual whitespace (converted before you store it) -> Hence your replace doesn't match the actual data.
The second option that might be possible - depending on what you want to do: You are seeing the URL containing %20, therefore you created your database records (which you would like to fetch) with that additional %20 - And when you now try to query your results based on the actual url, the %20 is replaced with an "actual" whitespace (before your query) and hence it doesn't match your stored data.

using regex in sqlite or mysql

I'm using sqlite3 to try and find users who have an e-mail address that is either with Gmail, Yahoo or Hotmail. It needs to do this just on the basis of the first part of the domain, so I want any address that had the #yahoo to be accepted.
It appears from documentation that it is not possible to use a regular expression when querying an sqlite database. Is there any elegant way of doing something similar? It doesn't seem to be possible to use a "like/in" with multiple options (eg: LIKE (%#yahoo%, %#gmail%, %#hotmail%)?
Failing that, I may switch over to MySQL for a reg exp as I want to keep the solution simple and elegant and DB isn't a major factor. How would said regexp query be written in MySQL?
You can't use multiple "LIKE" in that way but you can use:
(email LIKE "%#yahoo%" OR email LIKE "%#gmail%" OR ....)
you can use the way Nemoden is using or something like this (not tested)
WHERE email REGEXP '[\w\.]+#(yahoo|gmail|ymail|hotmail)\.(com|ru|co\.uk)'
This would be much faster because LIKE %string% OR ... is very slow and doesnt use any indexes(dont know if REGEXP uses indexes tho).
I think you might want something like this (RLIKE function):
WHERE email RLIKE '^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.([A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum|travel)$'
If you use whatever_cs (case sensitive collation), use a-zA-Z instead of A-Z.
You can also get rid of ^ and $ in the regex. ^ means "starts with" and $ means "ends with"
UPDATE:
'.*#(gmail|hotmail|yahoo)\.[A-Z]{2,4}'