我进行了各种更新记录的尝试均未成功,其中 MySQL 数据库中的行名称包含变音符号(ä、ü、ö、ß)。最后我怀疑 Record Field Exchange 不能正确处理 Umlaute。以下是我尝试过的测试用例。
- 使用 MySQL ODBC 5.2a 驱动程序(ANSI 驱动程序)
- 使用 MySQL ODBC 5.2w 驱动程序(Unicode 驱动程序)
- 使用 MySQL ODBC 5.2a 驱动程序并在连接字符串中设置 charset=latin1
- 使用 MySQL ODBC 5.2w 驱动程序并在连接字符串中设置 charset=latin1
在每个测试用例中,都可以成功读取记录,但更新记录会导致以下错误:
- 'field_list' 中的未知列 'Eigentü'
- 服务器不支持 4 字节编码的 UTF8 字符
- 'field_list' 中的未知列 'Eigentü'
- 服务器不支持 4 字节编码的 UTF8 字符
为了获得更多信息,我打开了 ODBC 调试选项(在 MySQL 连接器/ODBC 数据源配置中找到),它将 SQL 字符串输出到 %TEMP%\myodbc.sql。对于测试用例,驱动程序编写如下名称(myodbc.sql 是一个 ANSI 文件):
- 选择语句:
Eigentümer
; 更新声明:Eigentümer
- 选择语句:
Eigentümer
; 更新声明:Eigentümer
- 选择语句:
Eigentümer
; 更新声明:Eigentümer
- 选择语句:
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
}