Wie füge ich das Sonderzeichen in DB ein?

Ich arbeite an Ubuntu und ich benutze DBeaver für DB-Zugriff. Ich versuche, das lateinische character in eine database (MSSQL) einzufügen, und es wirft einen Fehler. Aber wenn ich das gleiche Sonderzeichen mit DBeaver , ist es kein Fehler zu casting und es funktioniert. Ich habe diese Frage schon gesehen. Aber ich habe keine Ahnung.

Es ist der folgende Fehler:

 DBD::ODBC::st execute failed: [unixODBC][FreeTDS][SQL server]Error converting characters into server's character set. Some character(s) could not be converted (SQL-HY000) at expert.fi_review.pl line 243. 

Und data in db ist J rjest myyr . Aber die aktuellen data sind Järjestömyyrä .

Beispielcode:

 my ($dsn,$dbh); &DB_Connect; $insert_query = "INSERT INTO table_name (name) values(N'$name')"; my $sth = $dbh->prepare($insert_query); $sth->execute() or $DB_Error=$DBI::errstr; sub DB_Connect { $dsn = "dbi:ODBC:driver={SQL server};server=$server_name,$port;database=$Database_name;driver=FreeTDS;tds_version=8.0;"; reconnect: $dbh = DBI->connect($dsn, $db_user_id, $db_pwd ,{AutoCommit => 1}) or goto reconnect; $dbh-> {'LongTruncOk'} = 1; $dbh-> {'LongReadLen'} = 90000; } 

Hmm Ich habe iconv Unterstützung für FreeTDS und in irgendeinem Sinne verantwortlich für diese Fehlermeldung. Ich habe drei Fragen und einen Vorschlag.

  1. Was ist die Codierung der table_name.name , table_name.name ? Unterstützt diese encoding die Charaktere, die du insert willst? Ich wette nicht

  2. Ist der Client-charactersatz in der freetds.conf mit dem im Gebietsschema (1) reflektierten freetds.conf übereinstimmen?

  3. Bist du sicher, dass du das alte TDS-Protokoll nicht benutzt hast 4.1?

FreeTDS konvertiert SQL-Text in UTF-16. Wenn Sie die data in die SQL- insert statement interpolieren, konvertiert FreeTDS die gesamte statement, data und alle. Wenn die Client-Codierung nicht korrekt beschrieben ist, können die data nicht konvertiert werden. Wenn die server-Codierung das character nicht darstellen kann, können die data nicht konvertiert werden. Und wenn das Protokoll alt ist, gibt es keine Unterstützung für Unicode in Sicht.

Es ist schwer zu sagen, aus Ihrer Fehlermeldung, aber es sieht mir wie die Client-Seite gelungen und die server-Seite fehlgeschlagen. Das heißt, FreeTDS hat die data korrekt in UTF-16 umgewandelt, aber der server konnte die data nicht in die Spalte name insert, da es varchar , nicht nvarchar und die " nvarchar " für die database (oder Spalte, falls angegeben) ist nicht einer, der diese character darstellen kann.

Mein Vorschlag ist, TDS_DUMP zu verwenden und der FreeTDS Mailingliste beizutreten. Das TDS_DUMP-Protokoll beantwortet alle Fragen, die ich gestellt habe. Und du wirst eine bessere Unterstützung auf der Mailingliste bekommen, weil es spezialisiert ist.

Nun können Sie fragen, warum DBeaver zu funktionieren scheint. Ich weiß es nicht; Bis dahin habe ich noch nie davon gehört. Ich kann Ihnen sagen, dass es Möglichkeiten gibt, data einzufügen (z. B. mit parametrisierten Abfragen in ODBC), wo der server einfach die data wörtlich einfügt. Merkwürdigerweise versteht es nicht, dass sie für die deklarierte Codierung gültig sind.

Ich habe vielen Leuten mit solchen Problemen geholfen. Die database ist für CP-1252 eingerichtet, aber die data sind nicht korrekt codiert. Die Anwendung kann fehlcodierte data insert und sie später wieder abrufen und korrekt machen, sozusagen unter dem Radar rutschen. Aber lassen Sie die DBA versuchen, die data abzufragen oder sie mit normalen Admin-Tools zu überprüfen, und sie sehen komisch aus . Der server nimmt an, dass die data in ihrer database pro databasedefinition codiert sind. Wenn das nicht der Fall ist, kommt Heiterkeit!

Wenn das dein Fall ist, kannst du es leicht testing. Verwenden Sie DBeaver, um die data einzufügen. Verwenden Sie die SQL server-Admin-Anwendung oder eine gute alte isql, um sie auf Windows abzurufen. Quoten sind Sie nicht amüsiert

Konvertiere das utf-8 in utf-16, bevor es in eine nvarchar-Spalte eingefügt wird.

Und zurück zu utf-8 beim Lesen.

Oder verwenden Sie eine Varbinary Spalte und speichern Sie die Ebene utf-8 Bytes dort. Das memoryn von utf-8 codierten data in einer nvarchar-Spalte ist falsch.

Können Sie versuchen, Ihren Code so zu ändern?

 $insert_query = "INSERT INTO table_name (name) values(?)"; my $sth = $dbh->prepare($insert_query); $sth->bind_param(1, $name, DBI::SQL_WVARCHAR); $sth->execute() or $DB_Error=$DBI::errstr; 

Konvertiere das Feld in utf8_unicode_ci

Beispiel: ALTER TABLE t CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Oder wenn es eine Abfrage ist:

 SELECT * FROM `INFORMATION_SCHEMA.COLUMNS` WHERE TABLE_SCHEMA = 'dbname' AND CHARACTER_SET_NAME = 'latin1' 

Aus deiner Frage ist es nicht klar, wann das Problem kommt.

Wenn es von Perl ist, kannst du es einfach mit der url escape function kodieren

 use URI::Escape; my $string = "Järjestömyyrä"; my $encode = uri_escape($string); my $decode = uri_unescape($encode); 

Eine JavaScript-Alternative zur Vorschau ist hier

 var a="Järjestömyyrä"; var b=encodeURIComponent(a); console.log("Encode : "+b); console.log("Decode : "+decodeURIComponent(b)); 

Ihr Fehler ist als SQL server falsch, da der Fehler auf Ihrer Client-Seite mit Perl ist, wo der Fehler auftritt.

Darüber hinaus nutzen Sie Drittanbieter-Bibliotheken und Management-Tools, wenn es keine Notwendigkeit, dies zu tun, funktionell oder Dollar weise, und viel weniger Unterstützung.

Als Kommentatoren haben Sie hier gesagt, Umlaut-Text sind Unicode-character, so dass die Spalten entweder nvarchar oder nText sein müssen. https://msdn.microsoft.com/en-us/library/ms186939.aspx

Wenn Sie SSMS und SSDT verwenden , bin ich sicher, dass die SQL server-Community eine bessere Unterstützung für Sie bietet. Es besteht keine Notwendigkeit, Perl zu verwenden, um diese einfache dataübertragung zu erreichen.

SQLSTATE [HY000]: Allgemeiner Fehler: 1366 Falscher Stringwert für ein Feld mit Akzente –

Eine sehr ähnliche Frage erscheint auch hier