3

我进行了各种更新记录的尝试均未成功,其中 MySQL 数据库中的行名称包含变音符号(ä、ü、ö、ß)。最后我怀疑 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

在每个测试用例中,都可以成功读取记录,但更新记录会导致以下错误:

  1. 'field_list' 中的未知列 'Eigentü'
  2. 服务器不支持 4 字节编码的 UTF8 字符
  3. 'field_list' 中的未知列 'Eigentü'
  4. 服务器不支持 4 字节编码的 UTF8 字符

为了获得更多信息,我打开了 ODBC 调试选项(在 MySQL 连接器/ODBC 数据源配置中找到),它将 SQL 字符串输出到 %TEMP%\myodbc.sql。对于测试用例,驱动程序编写如下名称(myodbc.sql 是一个 ANSI 文件):

  1. 选择语句:Eigentümer; 更新声明:Eigentümer
  2. 选择语句:Eigentümer; 更新声明:Eigentümer
  3. 选择语句:Eigentümer; 更新声明:Eigentümer
  4. 选择语句:Eigentümer; 更新声明:Eigentümer

我很惊讶 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
}
4

0 回答 0