0

関数を呼び出してデータベースからデータを選択しようとしていますが、より効率的であり、毎回接続を開いてリーダーを実行するのは好きではありません。そのようなことができるソリューションはありますか?

これはデータベースからデータを選択する最初の方法ですが、SQL インジェクションの問題が発生します

    protected void Button1_Click(object sender, EventArgs e)
    {
        Class1 myClass = new Class1();
        lblAns.Text = myClass.getdata("Table1", "Student", "Student = '" + TextBox1.Text + "'");           
    }


    public string getdata(string table,string field,string condition)
    {
        SqlDataReader rdr;
        SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True");
        string sql = "select " + field + " from " + table + " where " + condition;

        try
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand(sql, conn);
            rdr = cmd.ExecuteReader();
            while (rdr.Read())
            {
                return "true";
            }
        }
        catch (System.Data.SqlClient.SqlException ex)
        {
            string msg = "Insert Error:";
            msg += ex.Message;
        }
        finally
        {
            conn.Close();
        }
        return "false";
    }

これは私の 2 番目の方法ですが、行 (rdr = cmd.ExecuteReader();) でエラーが発生します (ExecuteReader にはオープンで使用可能な接続が必要です。接続の現在の状態は閉じられています。)

     public string getdata(SqlCommand command,SqlConnection conn)
    {
        SqlDataReader rdr;
        try
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand();
            cmd = command;
            rdr = cmd.ExecuteReader();
            while (rdr.Read())
            {
                return "true";
            }
        }
        catch (System.Data.SqlClient.SqlException ex)
        {
            string msg = "Select Error:";
            msg += ex.Message;
        }
        finally
        {
            conn.Close();
        }
        return "false";
    }

    public SqlConnection conn()
    {
        SqlConnection conn =  new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True");
        return conn;
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        Class1 myClass = new Class1();
        string strSql;

        strSql = "Select student from Table1 where student=@stu";
        SqlCommand command = new SqlCommand(strSql, myClass.conn());
        command.Parameters.AddWithValue("@stu", TextBox1.Text);
        myClass.getdata(command, myClass.conn());
    }

解決策は最初の方法を使用できますが、SQL インジェクションの問題は発生しませんか?

4

1 に答える 1

3

常に 2 番目のソリューションを使用してください。Sql インジェクションを回避する唯一の方法は、パラメーター化されたクエリを使用することです。

2 番目の例のエラーも修正します。接続をコマンドに関連付けないでください。接続用にグローバル オブジェクトを保持することもお勧めできません。ADO.NETには、これらのオブジェクトの安全な処理を維持しながら、コストのかかる接続のオープン/クローズを回避する接続プールの概念が存在します。

public string getdata(SqlCommand command)
{
    // Using statement to be sure to dispose the connection
    using(SqlConnection conn = new SqlConnection(connectionString))
    {
       try
       {
            conn.Open();
            cmd.Connection = conn;
            SqlDataReader rdr = cmd.ExecuteReader();
            while (rdr.Read())
            {
                return "true";
            }
        }
        catch (System.Data.SqlClient.SqlException ex)
        {
             string msg = "Select Error:";
             msg += ex.Message;
             return msg;
        }
  }
  return "false";
}
于 2013-05-16T08:26:21.867 に答える