2016-12-05 1 views
1

bug in MySQL ODBC 5.3.6을 찾은 후에도 MySQL ODBC 5.3.4를 사용하는 다른 문제가 발생합니다.MS Access (VBA)에서 ADODB를 사용하여 비 ASCII를 ASCII 데이터베이스에 삽입 할 때 재 시도가 가능하다면

ADODB를 MySQL ODBC (5.3.4 32 비트)와 함께 사용하여 로컬 MySQL 데이터베이스 서버 (5.7.16 64 비트)에 인터페이스하는 MS Access 응용 프로그램 (Office 2016 ProPlus 32 비트)을 Windows 10 Pro 64 비트 컴퓨터. MySQL 데이터베이스에 비 ASCII 문자를 삽입하면 "잘못된 문자열 값"오류로 실패하지만 동일한 명령문을 다시 시도하면 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 

테스트 결과이다 [MySQL의] [ODBC 5.3 (w) 드라이버 [mysqld를-5.7.16 로그] 잘못된 문자열 값 : "\ xE8gh '열의'

  1. 실행은 .Execute를 상기 오차 문 80004005 정차 행 1에 '이름';
  2. 디버깅을 계속하면 (F8) SQL 문이 올바르게 실행되고 올바른 값이 데이터베이스 테이블에 삽입됩니다.
  3. "유니 코드"드라이버 대신 "ANSI"ODBC 드라이버를 사용하면 처음에는이 테스트가 성공하지만 더 복잡한 (예 : 중국어) 비 ASCII 문자가 물음표로 대체됩니다.
  4. VBA가 내부적으로 유니 코드를 사용하지만 MySQL does not support UTF16 for clients을 사용하고 ODBC 연결 문자열에 "charset = utf8mb4"를 지정하거나 "SET CHARACTER SET utf8mb4"를 먼저 실행하면 "SET NAMES utf8mb4"가 지원되지 않습니다.
  5. INSERT 대신 IGNORE INSERT를 사용하면 첫 번째 실행은 성공한 것으로 보이지만 그 값은 실제로 "è"에서 잘립니다 (따라서 "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

하지만 두 번째 시도에서 성공한다는 것은 여전히 ​​이상합니다 (dbParams.Type의 값은 자동으로 수정되지 않습니다). –

답변

1

문 ...

dbParams.Type = adVarChar 

는 ... 그 값이 단일 바이트 문자의 문자열이 될 것이라는 ADODB.Parameter 객체를 말하고있다. 이러한 1 바이트 문자는 ODBC 드라이버로 전달되며, ODBC 드라이버는이를 MySQL 데이터베이스 엔진으로 전달합니다. 데이터베이스 엔진이 UTF-8 문자를 예상하면 0xE8 (Windows-1252와 같은 많은 "latin-1"형식 코드 페이지에서 è) 유효한 UTF-8 바이트 시퀀스가 ​​아니기 때문에 오류가 발생합니다. 위의 문을 변경

...

dbParams.Type = adVarWChar 

합니다 ... ADODB를 알려줍니다.그 값은 멀티 바이트 ("와이드") 문자열의 문자열이 될 매개 변수 객체입니다. 리터럴 VBA 문자열을 사용하여 값을 ... 할당 할 때

dbParams.Value = "dèf" 

... ADODB는 유니 코드 (현재 Windows 로케일 기준)의 단일 바이트 표현에서 문자열을 변환하고, ODBC에 그 전달합니다 운전사. ODBC 드라이버는 원시 유니 코드 (U+0064 U+00E8 U+0066)의 문자열을 UTF-8 인코딩 (0x64 0xC3 0xA8 0x66)으로 "다시 패키지"하여 데이터베이스 엔진에 전달할 수 있습니다.

관련 문제