SQL fulltext-search with CONTAINS raises geometry error - mysql

My php code generate a sql query as follow:
SELECT id, title, files, rating, DATE_FORMAT(date, '%d %M %Y') AS fancydate
FROM ArtArchive
WHERE CONTAINS (tags, 'Pepper')
ORDER BY date DESC
And it returns the error:
HY000 - 3055 - Geometry byte string must be little endian.
tags is a VARCHAR(255) indexed as FULLTEXT
I got the query to work by using : tags LIKE '%Pepper%', so I'm certain the CONTAINS is in cause.
I couldn't figure out what this error mean, nor what I have to do with geometry of all things: I'm simply trying to find words in a text.
After checking multiple examples, I'm pretty sure that I've been using the correct syntax. I also tried things such as : CONTAINS (tags, '"Pepper"'), CONTAINS (tags, 'Pepper'), CONTAINS (tags, "'Pepper'"), with no different result.
I'm trying not to use IN or LIKE because I intent to search multiple values at once in the tags field. I've toned it down to one value in the example until I get get it to work at all.

MySQL does NOT support CONTAINS() for text searches, as you would expect:
MySQL only recognizes the CONTAINS SQL function when dealing with
spatial data. It requires two graphics objects as arguments, and
returns a 1 or 0 depending on if the first object completely contains
the second. Designed as an implementation of the OpenGIS framework,
the MySQL CONTAINS function does not work on ordinary strings, and
will produce an error if you try it. MySQL only recognizes the LIKE
and STRCMP functions when dealing with string of information.
Found that info here.

Related

MySQL throwing error "Error Code: 3685. Illegal argument to a regular expression" when calculating accurate occurrence of phrase(s) inside column

As I mentioned in the Q-title, as now the MySQL has been heavily upgraded to version 8, which expectedly provides much new features including shortened characters for Word Boundary matching, calculating exact occurrence of phrase(s) inside column where one row-column(cell) may contain multiple occurrences of searched term/phrase must become easier to achieve.
Yet when I am using this proper looking query to count the exact occurrence of string it throws the below given error:
SELECT
ROUND((LENGTH(`column_name`) - LENGTH(REGEXP_REPLACE(`column_name`,
"^[[:<:]]Home Depot[[:>:]]$",
''))) / LENGTH('Home Depot')) AS `found`
FROM
<DB>.<TableName>;
Where if there are 2 rows as below:
Home Depot is a good one but Home Depot
Home Depot is a bad one
Then it must return found(count of total occurrence) as 3 instead of just no. of rows 2.
But on the contrary it throws error: Error Code: 3685. Illegal argument to a regular expression.
And if I use \\b instead of the [[:<:]], then it gives too many rows of the order of 1000000 which is ofcourse the wrong count as there aren't that much rows in the entire table, so it's just the Regex engine messing up.
Anyone care to help out achieve what I want ?
You need to change the word boundaries to \\b. And to match Home Depot anywhere in the string, you must remove the ^ and $ anchors. Finally, to get the total number of replacements, you have to use SUM() to add up the values from each row.
I don't think you need to use ROUND() since the numerator should always be an exact multiple of the denominator.
Putting it all together:
SELECT SUM((LENGTH(`column_name`) -
LENGTH(REGEXP_REPLACE(`column_name`, "\\bHome Depot\\b", '')))
/ LENGTH('Home Depot')) AS found
FROM db.tablename

Having troubles creating a wildcard sql code with multiple inputs

I'm currently working on creating a query that will pull data from a table that is linked on a certain part #. The challenge with this is the part #'s in the table have leading zeros. For example the part number I have is 8456790 but is stored in our table as 00000008456790. I'm able to get the desired results for one value using the following code:
select ZMATNR, ZLPN
FROM tblZMMGPNXREF
WHERE ZMATNR like ('%8456790%')
I have roughly 8,000 part #'s I want to run this code for but I know the syntax doesn't allow for me to paste all 8,000 parts at once.
Is there a quick way to run this code including all 8,000 part #s?
In most databases casting '00000008456790' to an integer should be enough:
select ZMATNR, ZLPN
FROM tblZMMGPNXREF
WHERE cast(ZMATNR as int) = 8456790
In Mysql it's even easier because of implicit conversion of '00000008456790' to the integer 8456790 when they are compared:
select ZMATNR, ZLPN
FROM tblZMMGPNXREF
WHERE ZMATNR = 8456790

Syntax error in date in query expression for non-date fields

I'm having trouble building a query in Access 2013. The database isn't mine and the only thing I really have control over is this query. There is a table, I'm pulling 7 fields from it and eventually adding an 8th field to the query to do some string manipulation.
However, I keep getting getting "Syntax error in date in query expression 'fieldname'." error whenever I click on the arrow to sort the fields. The odd thing is these errors pop up when sorting non-date fields. When sorting the date field I get "Syntax error (missing operator) in query expression 'Release Date'."
This happens after a fresh build. I have no WHERE conditions, just SELECT and FROM. Ideas?
Here's the sql query, though I'm mainly working in the query design view:
SELECT Transmissions.[Job#], Transmissions.[Part#], Transmissions.TransmissionSN, Transmissions.Status, Transmissions.[Release Date], Transmissions.[Build Book Printed], Transmissions.[ID Tags Required]
FROM Transmissions;
Well... it seems you are the lucky inheritor of a poorly designed database.
Using special characters in a field name is just asking for trouble. And you've found what that trouble is.
Access uses the # sign to designate a Date type for query comparisons. Such as:
dtSomeDate = #2/20/2017#
You surround the date with the # signs.
In your case, the query thinks [Job#] and [Part#] are trying to wrap dates. But of course, that's not the case and thus it fails.
You can try a couple of work arounds. (I leave it to you to experiment.)
1) You can try to rename the problem fields within your query. So that:
Transmissions.[Job#] becomes Transmissions.[Job#] as JobNum
and
Transmissions.[Part#] becomes Transmissions.[Part#] as PartNum
2) You can try to copy the [Transmissions] table to a new table that you create
that does not have the naming problems.
3) Export the [Transmissions] table to a CSV file and re-import it to a new
table (or possibly new database) without the naming problems.
Here is a link to a microsoft article that tells you why to avoid special characters in Access:
Big Bad Special Chars.
Hope that puts you on the right track. :)
Typically, this means that the field names are missing or misspelled.
Try running this to see:
SELECT * FROM Transmissions;

MYSQL REGEXP with JSON array

I have an JSON string stored in the database and I need to SQL COUNT based on the WHERE condition that is in the JSON string. I need it to work on the MYSQL 5.5.
The only solution that I found and could work is to use the REGEXP function in the SQL query.
Here is my JSON string stored in the custom_data column:
{"language_display":["1","2","3"],"quantity":1500,"meta_display:":["1","2","3"]}
https://regex101.com/r/G8gfzj/1
I now need to create a SQL sentence:
SELECT COUNT(..) WHERE custom_data REGEXP '[HELP_HERE]'
The condition that I look for is that the language_display has to be either 1, 2 or 3... or whatever value I will define when I create the SQL sentence.
So far I came here with the REGEX expression, but it does not work:
(?:\"language_display\":\[(?:"1")\])
Where 1 is replaced with the value that I look for. I could in general look also for "1" (with quotes), but it will also be found in the meta_display array, that will have different values.
I am not good with REGEX! Any suggestions?
I used the following regex to get matches on your test string
\"language_display\":\[(:?\"[0-9]\"\,)*?\"3\"(:?\,\"[0-9]\")*?\]
https://regex101.com/ is a free online regex tester, it seems to work great. Start small and work big.
Sorry it doesn't work for you. It must be failing on the non greedy '*?' perhaps try without the '?'
Have a look at how to serialize this data, with an eye to serializing the language display fields.
How to store a list in a column of a database table
Even if you were to get your idea working it will be slow as fvck. Better off to process through each row once and generate something more easily searched via sql. Even a field containing the comma separated list would be better.

MySQL find/replace with a unique string inside

not sure how far I'm going to get with this, but I'm going through a database removing certain bits and pieces in preparation for a conversion to different software.
I'm struggling with the image tags as on the site they currently look like
[img:<string>]<image url>[/img:<string>]
those strings are in another field called bbcode_uid
The query I'm running to make the changes so far is
UPDATE phpbb_posts SET post_text = REPLACE(post_text, '[img:]', '');
So my actual question, is there any way of pulling in each string from bbcode_uid inside of that SQL query so that I don't have to run the same command 10,000+ times, changing the unique string every time.
Alternatively could I include something inside [img:] to also include the next 8 characters, whatever they may be, as that is the length of the string that is used.
Hoping to save time with this, otherwise I might have to think of another way of doing it.
As requested.
The text I wish to replace would be
[img:1nynnywx]http://i.imgur.com/Tgfrd3x.jpg[/img:1nynnywx]
I want to end up with just
http://i.imgur.com/Tgfrd3x.jpg
Just removing the code around the URL, however each post_text has a different string which is contained inside bbcode_uid.
Method 1
LIB_MYSQLUDF_PREG
If you want more regular expression power in your database, you can consider using LIB_MYSQLUDF_PREG. This is an open source library of MySQL user functions that imports the PCRE library. LIB_MYSQLUDF_PREG is delivered in source code form only. To use it, you'll need to be able to compile it and install it into your MySQL server. Installing this library does not change MySQL's built-in regex support in any way. It merely makes the following additional functions available:
PREG_CAPTURE extracts a regex match from a string. PREG_POSITION returns the position at which a regular expression matches a string. PREG_REPLACE performs a search-and-replace on a string. PREG_RLIKE tests whether a regex matches a string.
All these functions take a regular expression as their first parameter. This regular expression must be formatted like a Perl regular expression operator. E.g. to test if regex matches the subject case insensitively, you'd use the MySQL code PREG_RLIKE('/regex/i', subject). This is similar to PHP's preg functions, which also require the extra // delimiters for regular expressions inside the PHP string
you can refer this link :github.com/hholzgra/mysql-udf-regexp
Method 2
Use php program, fetch records one by one , use php preg_replace
refer : www.php.net/preg_replace
reference:http://www.online-ebooks.info/article/MySql_Regular_Expression_Replace.html
You might be able to do this with substring_index().
The following will work on your example:
select substring_index(substring_index(post_text, '[/img:', 1), ']', -1)