1

次のコードを見てください。

protected void Button2_Click(object sender, EventArgs e)
{
    SqlConnection con = new SqlConnection(constring);

    SqlCommand cmd = new SqlCommand();

    if (DropDownList3.SelectedItem.Text == "Economy")
    {
        seats = Convert.ToInt32(DropDownList1.SelectedItem.Text);

        cmd.Connection = con;
        con.Open();
        cmd.CommandText = "select easeats from flight where fno='" + fn + "'";
       int eds = Convert.ToInt32(cmd.ExecuteScalar());

        if (eds > seats)
        {
            Panel2.Visible = true;                //seats available
            cl = DropDownList3.SelectedItem.Text;  
            seat = seats.ToString();
            seats = eds;
        }
        else
        {
            Panel3.Visible = true;         // seats not available 
        }
        con.Close();
    }
}

次の行でエラーが発生します。int eds = Convert.ToInt32(cmd.ExecuteScalar());

そして、エラーは

varchar 値をデータ型 int に変換する際のエラー

このコードの何が問題になっていますか?

4

2 に答える 2

4

まず、このようにクエリを作成しないでください。代わりにパラメーター化されたクエリを使用してください。

第二に、エラーメッセージは非常に明確です-数値だけでなく、おそらくいくつかのリテラル文字も含まれているvarchar列をintに変換しようとしています...

第三に、接続を明示的に閉じるよりも「using」ステートメントを優先します。その方が安全です。

于 2012-04-22T14:11:17.667 に答える
2

置き換えてみてください:

int eds = Convert.ToInt32(cmd.ExecuteScalar());

と:

int eds = 0;

int.TryParse(cmd.ExecuteScalar(), out eds);

このようにして、変換が失敗した場合、問題はなく、eds = 0 を続行します...

補足として、例外の処理と接続の有効期間は非常に貧弱です。次のようにブロック全体を置き換えることを検討してください。

protected void Button2_Click(object sender, EventArgs e)
{
    using(var con = new SqlConnection(constring))
    using(var cmd = con.CreateCommand())
    {
        if (DropDownList3.SelectedItem.Text == "Economy")
        {
            seats = Convert.ToInt32(DropDownList1.SelectedItem.Text);

            con.Open();
            cmd.CommandText = "select easeats from flight where fno='" + fn + "'";

            int eds = 0;
            object result = cmd.ExecuteScalar(); 
            int.TryParse(result, out eds);

            if (eds > seats)
            {
                Panel2.Visible = true;                //seats available
                cl = DropDownList3.SelectedItem.Text;  
                seat = seats.ToString();
                seats = eds;
            }
            else
            {
                Panel3.Visible = true;         // seats not available 
            }
        }
    }
}

もちろん、とにかく、全体をリファクタリングし、データベースとビジネス ロジックを UI ロジックから明確に分離することも検討する必要があります。一般に、UI 内の接続とクエリを直接処理することはありませんButtonClick。イベント ハンドラーではさらに少なくなります。

于 2012-04-22T14:13:13.970 に答える