Strip dots from IP addresses in Mysql - mysql

I need to strip dots from a columns of IP addresses in MySQL table 'visits', I used the following query, what's wrong with it?
UPDATE 'visits' SET 'IP' = REPLACE('IP', '.', '');
Thanks

Use backticks ` instead of single quotes ' for table and column name
UPDATE `visits` SET `IP` = REPLACE(`IP`, '.', '');
That said, this method may create issues.
For e.g. you have two IPs: 10.1.1.11 and 10.1.11.1
After your update, both will become - 101111 and there is no way to tell which is which.
As #Alex said in the comments, if you want to represent the IP as numeric value, consider INET_ATON() instead, which returns an integer that represents the numeric value of the address in network byte order (big endian).
UPDATE `visits` SET `IP` = INET_ATON(`IP`);
It'll return unique number for an IP.
10.1.1.11 - 167837963
10.1.11.1 - 167840513

Related

Updating column with Replace

Using MySQL (MariaDB 10.4.12)
I am trying to update a column using the replace function. I need to replace an ip address with a URL. The value in the column is very long.
I am using:
UPDATE myTable
SET myColumn = REPLACE(myColumn, '192.168.9.1', 'www.mydomain.com/content')
WHERE ID = 1234;
When I run this, the value it updates to is very wrong.
However, if I remove the"/content" from the replace function, it updates correctly.
The data type of the column is longtext:
# Field, Type, Null, Key, Default, Extra
'myColumn', 'longtext', 'NO', '', NULL, ''
The value in this column is metadata, that is a very long string of characters/code. In the middle is my url that I need to update.
Example: a:4:{s:5:"child";a:1:{s:0:"";a:1:{s:3:"rss";a:1:{i:0;a:6:{s:4:"data";s:3:" and on and on and on.
Additionally, if I just select with the REPLACE() function, it returns the correct value.
Is there an issue with having a forward-slash ("/") in the replace function or update statement?
Thanks
-M

Trim leading and update in mysql

I wanted to create a query in MYSQL that would trim the leading '# ' from all of the fields in a column.
update values set value = TRIM(LEADING '# ' from value)
However, doing this gives me an error
Duplicate entry '3002' for key value
The value column has a unique constraint and the error probably occurs because the query is trying to set the same value to all of value column after trimming.
Is there a way to do trim leading and update in mysql?
This query looks fine.
The issue might be here. Let me give you an example.
Case 1:
At row-x, you have value '#info' and at row-y you have info.
You removed the # from row-x in your query. Now you have already info value at row-y. You can not update the new value to info as it is there already.
I would suggest either to remove the UNIQUE constraint or you do not update the database itself. You can trim with your backend programming.
This is not setting all values to the same value, this is where once trimmed you now have two different rows with the same value for that column.
To find this:
SELECT id, value, TRIM(LEADING '# ' from value) AS trimmed_value ORDER BY trimmed_value
Presuming you have some kind of id column you'll be able to find any rows where trimmed_value is identical.

MYSQL, Insert the numeric characters of a string in a column to another column

I am trying to clean the telephone numbers of a database so we can easily search for them. In the column TEL we have rows like:
654-598-5487
654.254.2456
(458)-5458789 e.3
I want to copy all those values to a new column where only the numeric characters are transferred:
6545985487
6542542456
45854587893
The new column (TEL_NO_FORMAT) is a big int and it only allows numbers, but if I execute something like this:
UPDATE CLIENTS set `TEL_NO_FORMAT` = `TEL`
It will only transfer the first numeric characters found and ignore the rest:
654
654
NULL
Easiest way is the REGEXP_REPLACE(MySQL 8.0+):
SELECT *, REGEXP_REPLACE(tel_no_format, '[^0-9]','') AS result
FROM clients
Answering the question in an update query
UPDATE CLIENTS SET TEL_NO_FORMAT = REGEXP_REPLACE(TEL, '[^0-9]','');
You should replace the undesired char before
UPDATE CLIENTS set `TEL_NO_FORMAT` = replace(replace(replace(`TEL`, '.',''),'-',''),')','')
because some char (eg '-') are create problem during conversion ..
anyway rember that a big int can't manage properly eventual tel number 0 prefixed eg:
00453778988

SELECT LIKE with binary column returns no results when hex is too long for a specific uuid

I have a table with a UUID column (code below, shortened for demo sake). When I was demoing my application yesterday, I had an issue where the an item I had created in the table with a uuid4 value would not pull up when searching for the full uuid; but eventually pulled up when I tried shortening the UUID I was searching for. When I created a second item with a new uuid4, I was able to search for that one just fine.
I'm not sure what the issue might be nor how to even debug it on the MySQL side. 'HEX'ing the column and doing a string comparison is not an option as I need to be able to use the index on the uuid column.
Since using UUID's is the primary and only method of looking items up (business requirements dictate not using the integer PK), I need to determine a solution that works 100% of the time.
CREATE TABLE `ItemTable` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uuid` binary(16) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uuid` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `ItemTable` (`uuid`)
VALUES (UNHEX('0BFADD4EEFC14C05A7CA83245C37EEB7'));
INSERT INTO `ItemTable` (`uuid`)
VALUES (UNHEX('6C52ACF3864E49BCBC4E7A7B2CBB90C5'));
SELECT * FROM `ItemTable` where uuid LIKE CONCAT(UNHEX('0BFADD4EEFC14C05A7CA83245C37EEB7'), '%'); -- No Results
SELECT * FROM `ItemTable` where uuid LIKE CONCAT(UNHEX('0BFADD4EEFC14C05A7CA83245C37EE'), '%'); -- No Results
SELECT * FROM `ItemTable` where uuid LIKE CONCAT(UNHEX('0BFADD4EEFC14C05A7CA83245C37'), '%'); -- No Results
SELECT * FROM `ItemTable` where uuid LIKE CONCAT(UNHEX('0BFADD4EEFC14C05A7CA83245C'), '%'); -- No Results
SELECT * FROM `ItemTable` where uuid LIKE CONCAT(UNHEX('0BFADD4EEFC14C05A7CA8324'), '%'); -- Theres the first one!!
SELECT * FROM `ItemTable` where uuid LIKE CONCAT(UNHEX('6C52ACF3864E49BCBC4E7A7B2CBB90C5'), '%'); -- Works right off the bat with the full UUID.
Here's a few notes to aid you in debugging this. Somewhere below may be an "answer" to a "question" you might have had, but didn't ask. (I'm assuming that you meant to ask a question, and weren't just giving a status report.)
x'5C' evaluates to a backslash character '\'. And the backslash is the standard character that MySQL uses for escape sequences.
As an example, '\n' is not interpreted as two separate characters (a backslash and an n). It's evaluated as a single newline character. To get a backslash character returned, we normally have to escape the backslash itself with another backslash. As a demonstration, consider:
SELECT HEX('\n') --> '0A'
SELECT HEX('\\n') --> '5C6E'
The UNHEX function returns a binary string. Before MySQL 5.5, the CONCAT function returned a binary string, but with later versions, it produces a nonbinary string. I'd expect the LIKE comparison would work with BINARY datatype (that's my expectation, but I haven't tested that.)
But consider this: the effect of "doubling up" the backslash characters...
SELECT v
, v LIKE UNHEX('335C37')
, v LIKE UNHEX('335C5C37')
, v LIKE REPLACE(UNHEX('335C37'),'\\','\\\\')
FROM (
SELECT CAST(UNHEX('335C37') AS BINARY) AS v
) t
Returns:
v v LIKE UNHEX('335C37') v LIKE UNHEX('335C5C37') v LIKE REPLACE(UNHEX('335C37'),'\\','\\\\')
---- ---------------------- ------------------------ -------------------------------------------
3\7 0 1 1
NOTE: you would perform the REPLACE function after the UNHEX operation, a sequence of 5C could actually be from '35C4'. Doing the replacement on the hex digits (without assuring the byte boundary) would introduce a spurious C5 character
DON'T DO THIS:
UNHEX(REPLACE('35C4','5C','5C5C')) --> x'35C5C4' (wrong!)
DO THIS:
REPLACE(UNHEX('35C4'),'\\','\\\\') --> x'35C4' (right!)
Are there characters other than the backslash that present potential issues?
Consider x'5F', and x'25', which are the underscore and percent characters, respectively. Those have special meanings in a string on the right side of a LIKE operator. (Likely, you'll want to escape those as well.
Escape the backslashes first, then the other characters. I'm thinking you are going to need an expression like this:
REPLACE(REPLACE(REPLACE( x ,'\\','\\\\'),'_','\\_'),'%','\\%')
And do that before you concatenate on the final '%' character.

Strict matching of strings and integers

I am writing a flexible search mechanism for a customer's website. I am utilizing union clauses to query a number of different fields in the database in search of a string value entered by the user. This works fine except for one issue.
When comparing a string of a text to an integer that is currently set to zero, the match always returns true. In other words, according to MySQL, "email#example.com" is equal to 0.
I have tried utilizing the CAST and CONVERT function to turn this into a standard string to string comparison, but I can't seem to get the syntax right. My attempts either repeat the above issue or return no rows at all when some should match. I am also concerned that doing this would have an effect on performance since I am combining lots of unions.
What I really need is a strict comparison between an entered string and the value in the database, be it an integer or string.
EDIT:
Here is an example.
CREATE TABLE `test_table` (
`id` INT NOT NULL AUTO_INCREMENT ,
`email` VARCHAR(255) NOT NULL ,
`phone` BIGINT(19) NOT NULL DEFAULT '0' ,
PRIMARY KEY (`id`) )
ENGINE = MyISAM;
INSERT INTO `test_table` (`id`, `email`, `phone`) VALUES (1, 'email#example.com', 0);
SELECT * FROM test_table WHERE phone = 'email#example.com';
Execute this and the one row that has been inserted will return. My issue is that it shouldn't!
This query should fail:
SELECT * FROM test_table WHERE cast(phone as char) = 'email#example.com';
The cause of the original problem is that when comparing strings and numbers, it converts the string to a number (so you can write where phone = '123'). You need to use an explicit cast of the field to make it a string-to-string comparison, to prevent this default conversion.
Unfortunately, casting like this is likely to prevent it from using indexes. Even if the field is already char, the cast apparently prevents it from indexing.
You could also solve it during input validation: if phone is an integer, don't allow the user to provide a non-integer value in the search field.
How about replacing:
SELECT * FROM test_table WHERE phone = 'email#example.com'
with:
SELECT * FROM test_table WHERE phone = 'email#example.com' and phone <> 0
<> means different from.
This will work for you because you are using 0 in the phone column to mean there isn't a phone number (although it would be better style to use NULL for no phone number).