MySQL データベースの行の名前にウムラウテ (ä,ü,ö,ß) が含まれているレコードを更新しようとしましたが、失敗しました。最後に、Record Field Exchange がウムラウテを適切に処理していないのではないかと思います。以下は、私が試したテストケースです。
- 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 文字をサポートしていません
詳細情報を取得するために、SQL 文字列を %TEMP%\myodbc.sql に出力する ODBC デバッグ オプション (MySQL Connector/ODBC Data Source Configuration にあります) をオンにしました。テスト ケースの場合、ドライバーは次のような名前を書き込みます (myodbc.sql は ANSI ファイルです)。
- SELECT ステートメント:
Eigentümer
; UPDATE ステートメント:Eigentümer
- SELECT ステートメント:
Eigentümer
; UPDATE ステートメント:Eigentümer
- SELECT ステートメント:
Eigentümer
; UPDATE ステートメント:Eigentümer
- SELECT ステートメント:
Eigentümer
; UPDATE ステートメント: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
}