MFC Unicode应用程序如何使用MySQL ODBC Connector连接到latin1 MySQL数据库?

时间:2013-04-24 08:33:41

标签: mysql unicode mfc odbc mysql-connector

我不知不觉地尝试更新记录,其中MySQL数据库中行的名称包含Umlaute(ä,ü,ö,ß)。最后我怀疑Record Field Exchange没有正确处理Umlaute。以下是我尝试过的测试用例。

  1. 使用MySQL ODBC 5.2a驱动程序(ANSI驱动程序)
  2. 使用MySQL ODBC 5.2w驱动程序(Unicode驱动程序)
  3. 使用MySQL ODBC 5.2a驱动程序并在连接字符串中设置charset = latin1
  4. 使用MySQL ODBC 5.2w驱动程序并在连接字符串中设置charset = latin1
  5. 在每个测试用例中,可以成功读取记录,但更新记录会导致以下错误:

    1. 'field_list'
    2. 中的未知栏'Eigentü'
    3. 服务器不支持4字节编码的UTF8字符
    4. 'field_list'
    5. 中的未知栏'Eigentü'
    6. 服务器不支持4字节编码的UTF8字符
    7. 为了获得更多信息,我打开了ODBC调试选项(在MySQL Connector / ODBC数据源配置中找到),它将SQL字符串输出到%TEMP%\ myodbc.sql。对于测试用例,驱动程序写入如下名称(myodbc.sql是ANSI文件):

      1. SELECT语句:Eigentümer;更新声明:Eigentümer
      2. SELECT语句:Eigentümer;更新声明:Eigentümer
      3. SELECT语句:Eigentümer;更新声明:Eigentümer
      4. SELECT语句:Eigentümer;更新声明:Eigentümer
      5. 我很惊讶SELECT在任何情况下都有效。你知道如何正确设置驱动程序或我能做些什么来使它工作吗?

        服务器信息:

        mysql> SHOW VARIABLES LIKE 'character_set%';
        +--------------------------+----------------------------+
        | Variable_name            | Value                      |
        +--------------------------+----------------------------+
        | character_set_client     | latin1                     |
        | character_set_connection | latin1                     |
        | character_set_database   | latin1                     |
        | character_set_filesystem | binary                     |
        | character_set_results    | latin1                     |
        | character_set_server     | latin1                     |
        | character_set_system     | utf8                       |
        | character_sets_dir       | /usr/share/mysql/charsets/ |
        +--------------------------+----------------------------+
        8 rows in set (0,00 sec)
        

        负责构建SQL语句的代码:

        void invdb::CWDBArtikelRecordset::DoFieldExchange(CFieldExchange* pFX)
        {
            pFX->SetFieldType(CFieldExchange::outputColumn);
            RFX_Int(pFX, L"[LNGer]", mWDBArtikel.id);
            RFX_Int(pFX, L"[Gerätetyp]", mWDBArtikel.geraetetyp);
            RFX_Text(pFX, L"[Seriennr]", mWDBArtikel.seriennr);
            RFX_Text(pFX, L"[Inventarnummer]", mWDBArtikel.inventarnummer);
            RFX_Text(pFX, L"[Eigentümer]", mWDBArtikel.eigentuemer);
            RFX_Text(pFX, L"[Meßbereich]", mWDBArtikel.messbereich);
            RFX_Long(pFX, L"[Baujahr]", mBaujahr);
            RFX_Text(pFX, L"[Inbetriebnahme]", mWDBArtikel.inbetriebnahme);
            RFX_Date(pFX, L"[Ende der Garantiezeit]", mWDBArtikel.endeDerGarantiezeit);
            RFX_Text(pFX, L"[Firma]", mWDBArtikel.firma);
            RFX_Text(pFX, L"[Pumpentyp]", mWDBArtikel.pumpentyp);
            RFX_Text(pFX, L"[PumpeSerNr]", mWDBArtikel.pumpesernr);
            RFX_Long(pFX, L"[AktStation]", mAktStation);
            RFX_Long(pFX, L"[DefaultStation]", mDefaultStation);
            RFX_Int(pFX, L"[IZS]", mWDBArtikel.izs);
            RFX_Date(pFX, L"[daten_vom]", mWDBArtikel.daten_vom);
            RFX_Text(pFX, L"[Schnittstellen]", mWDBArtikel.Schnittstellen);
        }    
        

        应更新记录的代码:

        void invdb::updateWDBArtikel(const WDBArtikel& wdbartikel) {
            // CWDBArtikelRecordset is derived from CRecordset
            // GetConnectedDB returns a succesfully connected CDatabase reference
            CWDBArtikelRecordset rs(&conWS.GetConnectedDB());
            rs.m_strFilter.Format(L"LNGer = '%d'", wdbartikel.id);
            rs.Open();
            if (rs.IsEOF())
                throw std::runtime_error("updateWDBArtikel: Not found");
            rs.Edit();
            rs.Set(wdbartikel);
            if (rs.mWDBArtikel.aktStation == AFX_RFX_LONG_PSEUDO_NULL)
                rs.SetFieldNull(&rs.mAktStation);
            if (rs.mWDBArtikel.defaultStation == AFX_RFX_LONG_PSEUDO_NULL)
                rs.SetFieldNull(&rs.mDefaultStation);
            if (rs.mWDBArtikel.endeDerGarantiezeit.GetStatus() != COleDateTime::valid)
                rs.SetFieldNull(&rs.mWDBArtikel.endeDerGarantiezeit);
            rs.Update(); // Results in a CDBException
        }
        

0 个答案:

没有答案