mysql - convertir - sql utf8
ยฟCรณmo conectarse a MySQL usando UTF8 dentro de un script perl? (1)
En una palabra:
Dentro de Perl-Script: ¿Cómo me conecto a MySQL de una manera que permita transmitir el carácter unicode de cuatro bytes U + 1F61C ("๐") desde el script de Perl a una MySQL-Table donde este carácter debe ser almacenado?
El uso de {mysql_enable_utf8 => 1}
no resuelve el problema.
En detalle:
Tengo exactamente el mismo problema que el descrito en la pregunta ERROR 1366 (HY000): Valor de cadena incorrecto: ''/ xF0 / x9F / x98 / x9C'' para la columna ''comment'' en la fila 1 e incluso con el mismo carácter Unicode (๐ = U + 1F61C = CARA CON LENGUA TUERCADA Y OJO GANADOR ) que produce el mensaje de error
DBD::mysql::st execute failed: Incorrect string value: ''/xF0/x9F/x98/x9C'' for column ...
Pero no uso PHP, utilizo Perl.
La respuesta aceptada en la otra pregunta dice:
Ejecute MySQL 5.5 o posterior.
Reviso la versión:mysql> select version(); +-------------------------+ | version() | +-------------------------+ | 5.7.13-0ubuntu0.16.04.2 | +-------------------------+
Entonces es 5.7 que es posterior a 5.5.
โ revisadoEstablecer el carácter de la tabla a
utf8mb4
.
Compruebo el conjunto de caracteres de mi base de datos, mi tabla e incluso de la columna informada:mysql> SELECT default_character_set_name FROM information_schema.SCHEMATA -> WHERE schema_name = "myDatabase"; +----------------------------+ | default_character_set_name | +----------------------------+ | utf8mb4 | +----------------------------+ mysql> SELECT CCSA.character_set_name FROM information_schema.`TABLES` T, -> information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA -> WHERE CCSA.collation_name = T.table_collation -> AND T.table_schema = "myDatabase" -> AND T.table_name = "myTable"; +--------------------+ | character_set_name | +--------------------+ | utf8mb4 | +--------------------+ mysql> SELECT character_set_name FROM information_schema.`COLUMNS` -> WHERE table_schema = "myDatabase" -> AND table_name = "myTable" -> AND column_name = "myColumn"; +--------------------+ | character_set_name | +--------------------+ | utf8mb4 | +--------------------+
Entonces mi base de datos, mi tabla y la columna informada usan el conjunto de caracteres
utf8mb4
.
โ revisado- Habilite UTF8 en su conexión MySQL.
Este parece ser el problema. La respuesta a la otra pregunta dice:SET NAMES utf8
, o utilizar una opción cuando se conecta que de manera similar lo habilita.
No sé cómo SET NAMES utf8
dentro de un script de perl, así que lo hice como lo hice en los últimos años. Creo que esta es " una opción cuando se conecta que de manera similar lo habilita ".
Está al final de la línea larga que comienza con my $dbh = DBI->connect
:
#!/usr/bin/perl -w
use strict;
use warnings;
use utf8;
use Encode;
use DBI;
binmode STDOUT, ":utf8";
#Here I connect using the parameter mysql_enable_utf8 (create database handle):
my $dbh = DBI->connect(''DBI:mysql:database=myDatabase;host=localhost'',''aUser'',''aPassword'',{mysql_enable_utf8 => 1});
#Prepare the statement (create statement handle):
my $sth = $dbh->prepare(''INSERT INTO `myTable` (`myColumn`) VALUES(?);'');
#This doesn''t work:
$sth->execute(''๐๏'');
#This doesn''t work either:
$sth->execute(encode_utf8(''๐๏''));
#end processing:
$dbh->disconnect();
exit(0);
Ambos ejecutan lanzan el mismo error (solo cambia el número de línea al final):
DBD::mysql::st execute failed: Incorrect string value: ''/xF0/x9F/x98/x9C'' for column ''myColumn'' at row 1 at myTestScript.pl line 16.
¿Qué estoy haciendo mal?
¿Cómo puedo hacerlo mejor?
El problema es con el comando SET NAMES utf8
. En MySQL, el conjunto de caracteres utf8 no es realmente utf8, admite caracteres de hasta 3 bytes solamente y el carácter en cuestión tiene 4 bytes:
El conjunto de caracteres utf8 en MySQL tiene estas características:
• No admite caracteres suplementarios (solo caracteres BMP).
• Un máximo de tres bytes por carácter multibyte.
El verdadero utf8 es el utf8mb4 que utilizas como juego de caracteres en el campo mismo. Por lo tanto, use SET NAMES utf8mb4
Entonces, desde Perl deberías usar {mysql_enable_utf8mb4 => 1}
lugar de {mysql_enable_utf8 => 1}
.