1

Visual Studio 2005 を使用して C++ MFC について学習しています。

Oracle MySQL データベースからデータを取得し、リスト コントロールに表示したいと考えています。何とかコードは動くのですが、表示がおかしくてひどいです。自分のコードに何かが欠けているように感じます。

コードを変更するにはどうすればよいですか? データベースには、表示したくない UserID というフィールドが 1 つあります。

以下は私が思いついたコードです:

void CPplCMain::OnBnClickedButton1()
{
    unsigned short Port = 3306;
    char *IPAddress = "127.0.0.1";
    char *UserName = "root";
    char *Password = "Root";
    char *DBName = "inomatic";

    MYSQL *ssock;
    MYSQL_RES   *res;
    MYSQL_ROW   row;
    //char execsql[500];
    ssock = (MYSQL *)malloc(sizeof(MYSQL));
    //在某些版本中,不需要该初始化工作,可观看mysql.H以及readme
    mysql_init(ssock);
    if(ssock == NULL)
    {
        MessageBox("EROR: MySQL ssock init error. \n");
        return;
    }
    //MessageBox("MySQL ssock init OK. \n");

    ssock = mysql_real_connect(ssock, IPAddress, UserName, Password, NULL, Port, NULL, 0);
    if(!ssock)
    {
        MessageBox("conn fail... \n");
        mysql_errno(ssock);
    }

    if(mysql_select_db(ssock, DBName) != 0)
    {
        MessageBox("select db error. \n");
        return;
    }

    //SQL查询语句
    if(mysql_query( ssock,"SELECT countryName FROM countries"))
    {
        MessageBox("Found", mysql_error(ssock));
    }
    if( !(res = mysql_store_result(ssock)) )
    {
        MessageBox("Disconnected!", mysql_error(ssock));
    }
    while( (row = mysql_fetch_row(res)) )
    {
        for(int i=0 ; i<mysql_num_fields(res); i++)
        {
           TRACE("%s ",row[i],"\n");
           m_CountryList.AddString(row[i]);
        }
        TRACE("\n");
    }

    if(mysql_query( ssock,"SELECT * FROM shop"))
    {
        MessageBox("Shop table Found", mysql_error(ssock));
    }
    if( !(res = mysql_store_result(ssock)) )
    {
        MessageBox("Disconnected!", mysql_error(ssock));
    }
    while( (row = mysql_fetch_row(res)) )
    {
        for(int i=0 ; i<mysql_num_fields(res); i++)
        {
            TRACE("%s ",row[i],"\n");
            //m_ShopList.AddString(row[i]);
            int nIndex = m_ShopListCtrl.InsertItem(i, row[i]);
            m_ShopListCtrl.SetItemText(nIndex, i,  row[i]);
        }
        TRACE("\n");
    }

    if(mysql_query( ssock,"SELECT * FROM peoplecounter"))
    {
        MessageBox("People Counter table Found", mysql_error(ssock));
    }
    if( !(res = mysql_store_result(ssock)) )
    {
        MessageBox("Disconnected!", mysql_error(ssock));
    }
    while( (row = mysql_fetch_row(res)) )
    {
        for(int i=0 ; i<mysql_num_fields(res); i++)
        {
            TRACE("%s ",row[i], "\n");
            //m_PplCounterList.AddString(row[i]);
            int nIndex = m_PplCounterCtrl.InsertItem(i, row[i]);
            m_PplCounterCtrl.SetItemText(nIndex, i,  row[i]);
        }
        TRACE("\n");
    }

    mysql_close(ssock);
    // TODO: Add your control notification handler code here
}

これは、データベースからのデータを入力した後のリスト コントロールのイメージです。

データベースからのデータを入力した後のリスト コントロールの画像

画像でわかるように、最初の行は正しく表示されますが、次の 6 行では重複データが行ごとに表示され、次のデータ セットが行 8 で正しく表示されます。

4

1 に答える 1

1

コードの問題は、データベース行の列エントリごとにリスト コントロールに行を挿入することです。forたとえば、次のように、ループの前に一度だけリスト コントロールに新しい行を挿入する必要があります。

while(row = mysql_fetch_row(res))
{
    // Insert a new row at the end of the list control.
    // Do this only once per database row.
    int nNewIndex = m_PplCounterCtrl.GetItemCount();
    int nCurIndex = m_PplCounterCtrl.InsertItem(nNewIndex, row[0]);

    // Insert all remaining database column entries.
    // Insert them into the current row of the list control.
    for(int i = 1; i < mysql_num_fields(res); i++)
    {            
        m_PplCounterCtrl.SetItemText(nCurIndex, i, row[i]);
    }
}
于 2014-09-10T17:25:45.647 に答える