3

MySQL データベースの行の名前にウムラウテ (ä,ü,ö,ß) が含まれているレコードを更新しようとしましたが、失敗しました。最後に、Record Field Exchange がウムラウテを適切に処理していないのではないかと思います。以下は、私が試したテストケースです。

  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 文字をサポートしていません

詳細情報を取得するために、SQL 文字列を %TEMP%\myodbc.sql に出力する ODBC デバッグ オプション (MySQL Connector/ODBC Data Source Configuration にあります) をオンにしました。テスト ケースの場合、ドライバーは次のような名前を書き込みます (myodbc.sql は ANSI ファイルです)。

  1. SELECT ステートメント: Eigentümer; UPDATE ステートメント:Eigentümer
  2. SELECT ステートメント: Eigentümer; UPDATE ステートメント:Eigentümer
  3. SELECT ステートメント: Eigentümer; UPDATE ステートメント:Eigentümer
  4. 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
}
4

0 に答える 0