2016-12-05 1 views
1

bug in MySQL ODBC 5.3.6を見つけた後も、MySQL ODBC 5.3.4を使用して別の問題が発生します。MS Access(VBA)でADODBを使用してASCII以外の文字列をMySQLデータベースに挿入すると再試行されますが、

私は、MySQL ODBC(5.3.4 32ビット)でADODBを使用してローカルMySQLデータベースサーバー(5.7.16 64ビット)とインターフェイスするMS Accessアプリケーション(Office 2016 ProPlus 32ビット)をWindows 10 Pro 64ビットコンピュータ。 MySQLデータベースに非ASCII文字を挿入すると "Incorrect string value"というエラーが表示されますが、同じ文を再度実行すると、SQL文が正しく実行され、正しい値がデータベーステーブルに挿入されます。

問題を特定するために、私は次の表を作成しました:

CREATE TABLE test2 (
    id INT NOT NULL AUTO_INCREMENT, 
    name VARCHAR(100) CHARACTER SET utf8mb4, 
    PRIMARY KEY (id)); 

、次のVBAコードを含むテストMS Accessデータベース(およびMicrosoft ActiveXデータ6.1オブジェクトライブラリへの参照):

my.iniで
Public Function dbTestIt2() as Long 

    Dim dbConn As New ADODB.Connection 
    Dim dbCmd As New ADODB.Command 
    Dim dbParams As New ADODB.Parameter 
    Dim l As Long 

     dbConn.ConnectionString = "Driver={MySQL ODBC 5.3 Unicode Driver};option=3;database=xxx;user=yyy;password=zzz;" 
     dbConn.Open 
     With dbCmd 
      .ActiveConnection = dbConn 
      .CommandType = adCmdText 
      .CommandText = " INSERT INTO test2 (name) VALUES (?);" 
      dbParams.Type = adVarChar 
      dbParams.Size = 100 
      dbParams.Value = "abcdèfgh" 
      dbParams.Direction = adParamInput 
      .Parameters.Append dbParams 
      .Execute l, , adExecuteNoRecords 
     End With 
     dbConn.Close 

     dbTestIt2 = l 

    End Function 

関連する行:ここ

[client] 
    default-character-set=utf8mb4 
    [mysql] 
    default-character-set=utf8mb4 
    [mysqld] 
    character-set-server=utf8mb4 
    collation-server=utf8mb4_unicode_ci 

試験結果であります:「列に '\ xE8gh':[MySQLの] [ODBC 5.3(W)ドライバー] [mysqldを-5.7.16-ログ]不正な文字列値:

  1. 実行がエラー80004005で.Executeのステートメントで停止し行1の「名前」。
  2. デバッグを続けると(F8)、SQL文が正しく実行され、正しい値がデータベーステーブルに挿入されます。
  3. "Unicode"ドライバの代わりに "ANSI" ODBCドライバを使用すると、このテストは初めて成功しますが、より複雑な(たとえば中国語の)非ASCII文字が疑問符に置き換えられます。
  4. 私はVBAが内部的にUnicodeを使用していますが、MySQL does not support UTF16 for clientsを使用し、ODBC接続文字列で "charset = utf8mb4"を指定するか、 "SET CHARACTER SET utf8mb4"を実行すると最初は助けず、 "SET NAMES utf8mb4"
  5. INSERTの代わりにINSERT IGNOREを使用すると、最初の実行は成功したようですが、値は実際には "è"で切り捨てられます(したがって、 "abcd"のみが挿入されます)。
  6. はまた、私が間違って何をやっているMySQLのODBC 5.3.6

で起こるか、これはMySQLのODBCドライバーで別のバグですか?

+0

'dbParams.Type = adVarChar'の代わりに' dbParams.Type = adVarWChar'を試してください。 –

+0

@GordThompson:本当ですか?ただ一つの手紙?あなたは私の日/週/月を救った!私はcharacter-set-client-handshake = FALSEのようなものは、初期のハンドシェイクが失敗したと思っていたので、何かを試していました。あなたが答えとしてあなたのコメントを追加するなら、私はそれを最良の答えとして選ぶことができ、私のような何週間も苦労している貧しい子どもたちを助けることができます。 #ifeelstupid –

+0

しかし、それは2回目の試行で成功するのはまだ変です(dbParams.Typeの値は自動的に変更されませんが、チェックしました)。 –

答えて

1

声明...

dbParams.Type = adVarChar 

は...その値がシングルバイト文字の文字列になることADODB.Parameterオブジェクトを語っています。これらのシングルバイト文字はODBCドライバに渡され、ODBCドライバはMySQLデータベースエンジンに渡します。データベースエンジンがUTF-8文字を予期している場合、0xE8(Windows-1252のような多くの "latin-1"型コードページのè)が有効なUTF-8バイトシーケンスではないため、エラーが発生します。上記のステートメントを変更する

...

dbParams.Type = adVarWChar 

は... ADODBを伝えます。その値はマルチバイト(「ワイド」)文字列になります。リテラルVBA文字列を使用して値を割り当てるとき...

dbParams.Value = "dèf" 

... ADODBは、(現在のWindowsロケールに基づいて)その単一バイト表現からUnicodeに文字列を変換し、ODBCにそれを通過しますドライバ。 ODBCドライバは、生のUnicode(U+0064 U+00E8 U+0066)からUTF-8エンコーディング(0x64 0xC3 0xA8 0x66)に文字列を「再パッケージ化」し、それをデータベースエンジンに渡すことができます。

関連する問題