Update MySQL new IPv6 column with existing IPv4 column data - mysql

I have the following two columns in a MySQL database table named "ip_test":
ipv4 as INT(11) (example value for 127.0.0.1: 2130706433).
ipv6 as VARBINARY (example value for 127.0.0.1: 0xFE800000000000000202B3FFFE1E8329).
What is the simplest manner to effectively convert the data (for a visual demonstration of the idea: UPDATE ip_test SET ipv6=ipv4;) though properly?

My goal was to avoid any server side scripting and to achieve this purely in MySQL. This seems correct from my initial tests:
UPDATE ip_test SET ipv6 = INET6_ATON(INET_NTOA(ipv4));

Related

Does MySQL server implicitly support encoding conversion?

I need to implement a sorted SELECT, on a specific encoding of a field, without CONVERT.
That is, normally I'd do it by
SELECT * FROM table ORDER BY CONVERT(field USING gbk) COLLATE gbk_chinese_ci
However for some reason CONVERT was not allowed. As a result, I tried to approach this by
ALTER TABLE table MODIFY field VARCHAR(xx) CHARACTER SET gbk COLLATE gbk_chinese_ci;
SELECT * FROM table ORDER BY field
It works. That's good. However I'm worried about encoding problems.
Connection to the MySQL server includes the parameters characterEncoding=utf8 and useUnicode=true. I couldn't yet find the explanation of these params in MySQL's official document, but I suppose these ensure that the communications between the client and the server should be in utf-8.
That brings the question. Does MySQL server implicitly convert data in utf-8 to gbk when it receives the data? Do the GET params only define the charset of communication rather than that of the final stored data?
Edit
Comments say that the server does convert them! Thanks guys!
My further confusion is that, only one of the fields is set to use gbk, while everything else has been left to use utf8. That means the server's charset should still be utf8 globally but gbk locally for that field only.
Suppose now I fire this line of script to the server
INSERT INTO table (field_gbk, field_utf8) VALUES ("a", "b");
Does the server:
Receive the whole statement in utf8;
Convert only "a" to gbk and stores it; and
Stores "b" as-is to the database?
Many thanks guys!
Yes.
You specify the encoding of in the client when you connect.
You specify the encoding ("Character set") of the column you are Inserting into.
MySQL converts from one encoding to the other as it INSERTs the rows. Similarly, it converts the other way when SELECTing.
The CONVERT function should not (normally) be used for anything.
You are using Java? characterEncoding=utf8 and useUnicode=true is what it uses for declaring the client side.
"gbk" for a single column? Find. That column will handled differently than other columns.

How to disable DB prefix name in mysql 6.3 Workbench

I want to disable database prefix name while executing queries in MySQL.
I am using MySQl Workbench 6.3 CE.
For Example : SELECT * FROM test_db.test_table;
I want to remove test_db prefix.
If you're using MySQL workbench, in the lefthand pane, there is a list of available databases. If you're only using one, you can right click on it and select "set as default schema", then any queries you run in that MySQL session will no longer need to be prefixed with the DB name. However, if you want to query another DB in the same session, you will have to append that DB's name as a prefix, or do the same process, and set that DB as the default schema.
See this link for pretty pictures and a full description: https://www.quackit.com/mysql/tutorial/mysql_default_database.cfm
You have to tell it what database to use .. So you do it the way you are describing. .. Or you tell MySQL which database to use BEFORE the SELECT IE
use test_db;
SELECT * FROM test_table;
They way MySQL works is that you either explicitly state which schema a specific DB object is in (e.g. a table) or it uses the current default schema. If you don't have a default schema set and don't use fully qualfied names, you will get an error from MySQL saying that you have to define a default schema first.
So what you want to accomplish is impossible. Either set a default schema (it's a per connection setting, so you can set it once and use with your other queries as long as you keep the connection open) or fully qualify your DB objects (which is the most flexible approach and also avoids certain ambiquities, like same named tables in different schemas).

Not able to add into mysql database using Talend Job

While adding data into mysql database using Job, I am getting following errors
*Starting job fillraw at 16:34 10/03/2016.
[statistics] connecting to socket on port 3955
[statistics] connected
Data truncation: Out of range value for column 'Net_Value' at row 2
Data truncation: Data too long for column 'Material_Description' at row 9
...
I'm new, but with some similar error, I debugged it with examining schemes and syncing. I suggest you do the same:
compare output scheme with DB scheme
check types both in Talend and database (my case I think was Talend String mapped to DB VARCHAR, but I forgot to put the exact size for VARCHAR on DB side)
check sizes and precisions of all types (expecially if you have double / float / decimal differences)

Mysql encryption/decryption without sending password in query

I need to encrypt some specific columns in mysql database. I researched and found few ways like AES_ENCRYPT functions, but these solutions requires sending the key value in the query.
I am looking for a solution where password can be stored in database some location and mysql can automatically use that value to encyrpt or decrypt that particular column?
Thank you.

Storing IPv6 Addresses in MySQL

As has been requested in "ipv6-capable inet_aton and inet_ntoa functions needed", there is currently no MySQL function for storing IPv6 addresses. What would be the recommended data type/function for storing/inserting? (I don't intend to store them as a string). I also don't want to separate the IPv6 address into 2 INT's.
How about:
BINARY(16)
That should be effective enough.
Currently there is no function to convert textual IPv6 addresses from/to binary in the MySQL server, as noted in that bug report. You either need to do it in your application or possibly make a UDF (User-Defined Function) in the MySQL server to do that.
UPDATE:
MySQL 5.6.3 has support for IPv6 addresses, see the following: "INET6_ATON(expr)".
The data type is VARBINARY(16) instead of BINARY(16) as I suggested earlier. The only reason for this is that the MySQL functions work for both IPv6 and IPv4 addresses. BINARY(16) is fine for storing only IPv6 addresses and saves one byte. VARBINARY(16) should be used when handling both IPv6 and IPv4 addresses.
An implementation for older versions of MySQL and MariaDB, see the following: "EXTENDING MYSQL 5 WITH IPV6 FUNCTIONS".
No one has posted a full working answer (and lots of examples use the Windows ::1 which can be very misleading for live (or "production") environments) any where (at least that I can find) so here is:
The format to store with.
Example INSERT query using a reasonably complex IPv6 IP address.
Example SELECT query that you will be able to echo the IPv6 IP address back to the client.
Troubleshooting to ensure you haven't missed any legacy code.
I changed all the column names to ipv6 to reflect that they properly support IPv6 (and that allows you to keep the old column ip intact). It is possible to store the ip column in the ipv6 column and then just DROP the ip column once you're certain the conversion has worked; when I actually have time I'll add that to this post.
IPv6 Data Type
As has been mentioned VARBINARY 16 is the desirable way to go until AMD blesses us with 128 bit CPUs and the databases are updated to support 128 bit integers (did I say that correctly?). IPv6 is 128 bit, not 64 bit.
CREATE TABLE `example`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`ipv6` VARBINARY(16) NOT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8mb4_unicode_520_ci'
ENGINE=InnoDB;
IPv6 INSERT Query
We obviously need to store an IPv6 IP address before we can SELECT it; here is the PHP / SQL code:
$ipv6 = mysqli_real_escape_string($db,'FE80:0000:0000:0000:0202:B3FF:FE1E:8329');
$query1 = "INSERT INTO example (ipv6) VALUES (INET6_ATON('$ipv6'));";
IPv6 SELECT Query
The PHP / SQL code:
$ipv6 = mysqli_real_escape_string($db,'FE80:0000:0000:0000:0202:B3FF:FE1E:8329');
$query2 = "SELECT INET6_NTOA(ipv6) AS ipv6 FROM example WHERE ipv6=INET6_ATON('$ipv6');";
This will return fe80::202:b3ff:fe1e:8329; no, not the full IPv6 (which is FE80:0000:0000:0000:0202:B3FF:FE1E:8329), it's a condensed / shorthand version. There is code to make it the formal full-length version but this is to save myself and others time because this Q/A is the one that keeps coming up.
Important: just because some IPv6 addresses look like they'd fit in to bigint does not imply two minutes later someone with a larger IPv6 address won't stop by and wreak havoc.
Hopefully this will save some folks from the insanity of opening another two dozen tabs. When I have time in the future I'll add the extra PHP code that extends the condensed IPv6 to the full formal format.
Troubleshooting
If for some reason storing and/or retrieving IPv6 addresses is not working for you then grab yourself a copy of Advanced Find and Replace (works faster in Wine than Linux's native grep); use this predominantly for finding, not replacing. Ensure that your code is consistent everywhere in your software.
All $ip variables must be converted to $ipv6 so you know you've got that bit covered.
Do not forget to remove the ending ) for the next four steps:
Search for all instances of PHP inet_pton( functions and remove them.
Search for all instances of PHP inet_ntop( functions and remove them.
Search for all instances of SQL INET_ATON( functions and remove them.
Search for all instances of SQL INET_NTOA( functions and remove them.
Search for all instances of $ipv6 and ensure that all IP-IN-TO-SQL instances use INET6_ATON('$ipv6') and that all instances where IP-FROM-SQL use INET6_NTOA(ipv6) AS ipv6.
Search for all instances of $row1['ip'] and replace them with $row1['ipv6'].
Ensure that all instances of $ipv6 = use the following code (with your database object reference changed): $ipv6 = (isset($_SERVER['REMOTE_ADDR']) && strlen($_SERVER['REMOTE_ADDR']) > 0) ? mysqli_real_escape_string($db,$_SERVER['REMOTE_ADDR']) : mysqli_real_escape_string($db,getenv('REMOTE_ADDR'));.
Ensure that your tests use freshly tested IP addresses instead of potentially botched versions if you are aware that there was something wrong before you started debugging.
Excellent example however I noted the following.
That only works if one's version of mysql has as function for INET6_ATON.
Otherwise the error message might be something like: That FUNCTION DOES NOT EXIST.