0

asp.net のデータベースとして SQL Server 2008 を使用しています。そして、<a>タグをクリックしてWebフォームに移動するときに、テーブル名を渡しています。では、リンクをクリックすると、受け取った値に応じてSQLクエリが変更されるようにするにはどうすればよいでしょうか?

例えば:

 <li class="last">
    <a href="category.aspx?cat=Architect&sub=Architects">Item 1.1</a>
 </li>

ここcatには、テーブル名とsub条件名が含まれています。

そして反対側で私はやっています:

SqlConnection con=new SqlConnection("Data Source=ANURAG-PC;Initial Catalog=dbPortal;Persist Security Info=True;User ID=sa;Password=anurag");
SqlDataAdapter da;
DataSet ds=new DataSet();
static DataTable dt = new DataTable();

protected void Page_Load(object sender, EventArgs e) 
{
   if (IsPostBack == false)
   {
      string s = Request.QueryString["cat"];
      string s1 = Request.QueryString["sub"];

      da = new SqlDataAdapter("select * from Architect where subcategory3='" + s1 + "'",con);
      da.Fill(ds,"tab");
      dt = ds.Tables["tab"];
      DataGrid1.DataSource = dt;
      DataGrid1.DataBind();
   }
}

Architectだから私はちょうど渡したいテーブル名を与えることを望んでいますs- どうすればそれを行うことができますか?

4

4 に答える 4

1

現在行っていることは非常に単純な SQL インジェクションにつながり、データベースが大きなリスクにさらされるため、これに対する他の解決策を考えることをお勧めします。すべてのテーブルの列挙型を取得し、テーブル名の代わりにクエリ文字列でテーブルの ID を渡すことをお勧めします。また、文字列を連結する前に、SQL インジェクションから条件文字列が有効であることを確認する必要があります。

于 2012-07-04T10:53:09.920 に答える
0

あなたのデザインは本当に最適ではありません。カテゴリとサブカテゴリの両方にリンクされた中央テーブルにすべてのデータを格納することを検討することは可能ですか?

いくつかの弱点があります。SQL の文字列を連結すると、SqlInjection 攻撃を受けやすくなります。たとえば、ドロップダウン リストから値を選択している場合でも、クライアント側のスクリプトがコンボ ボックスの値を変更したり、攻撃者がサーバー側のイベント ハンドラにデータを送信したりする可能性があります。

さらに、複数のテーブルからデータを取得する必要があるということは、結果でさまざまなスキーマを処理しなければならない可能性があることを意味します。これが予想される場合 (つまり、一部のテーブルが他のテーブルよりも多くの列を持っている場合)、適切に処理できます。

クエリは次のようになります。

protected void Page_Load(object sender, EventArgs e) 
{
   if (IsPostBack == false)
   {
      string s = Request.QueryString["cat"];
      string s1 = Request.QueryString["sub"];

      if(String.IsNullOrEmpty(s) || String.IsNullOrEmpty(s1)) { return; } //Improve Validation and error reporting

      using(SqlConnection conn = new SqlConnection("Data Source=ANURAG-PC;Initial Catalog=dbPortal;Persist Security Info=True;User ID=sa;Password=anurag"))
      {
        using(SqlCommand command = new SqlCommand(conn))
        {
            command.CommandType = CommandType.Text;
            command.CommandText = "SELECT * FROM Table WHERE Category = @Category AND SubCategory = @SubCategory";

            command.Parameters.Add(new SqlParameter() { Type = SqlDbType.String, Name = "@Category", Value = s });
            command.Parameters.Add(new SqlParameter() { Type = SqlDbType.String, Name = "@SubCategory", Value = s1 });

            conn.Open();

            using(SqlDataReader reader = command.ExecuteReader())
            {
                DataTable data = new DataTable("MyData");
                data.Load(reader);
                DataGrid1.DataSource = data;
                DataGrid1.DataBind();
            }

        }
      }
   }
}

元のモデルに行き詰まっている場合は、テーブル名をホワイトリストに登録して、パラメーター化されたクエリを使用できるようにすることをお勧めします。

protected void Page_Load(object sender, EventArgs e) 
{
   if (IsPostBack == false)
   {
      string s = Request.QueryString["cat"];
      string s1 = Request.QueryString["sub"];

      if(String.IsNullOrEmpty(s) || String.IsNullOrEmpty(s1)) { return; } //Improve Validation and error reporting

      using(SqlConnection conn = new SqlConnection("Data Source=ANURAG-PC;Initial Catalog=dbPortal;Persist Security Info=True;User ID=sa;Password=anurag"))
      {
        using(SqlCommand command = new SqlCommand(conn))
        {
            command.CommandType = CommandType.Text;

            switch(s)
            {
                case "Architect":
                    command.CommandText = "SELECT * FROM Architect WHERE SubCategory = @SubCategory";
                    break;
                case "SomethingElse":
                    command.CommandText = "SELECT * FROM SomethingElse WHERE SubCategory = @SubCategory";
                    break;
                default:
                    return; //Again, improve error handling
            }

            command.Parameters.Add(new SqlParameter() { Type = SqlDbType.String, Name = "@SubCategory", Value = s1 });

            conn.Open();

            using(SqlDataReader reader = command.ExecuteReader())
            {
                DataTable data = new DataTable("MyData");
                data.Load(reader);
                DataGrid1.DataSource = data;
                DataGrid1.DataBind();
            }

        }
      }
   }
}

ただし、上記の例のいずれかを実装したとしても、まだ大きな問題があるということです。データ アクセス コード、ビジネス ロジック、およびプレゼンテーション コードはすべて、このページのコード ビハインドに取り込まれています。必要な場所でこれを繰り返す必要があり、多くの重複が発生します。これは、バグを修正する必要がある場合に特に問題になります。

代わりに、クラスを作成するか、 ORMを使用してこのすべての作業を処理することを検討する場合があるため、代わりに Architect オブジェクトのリスト、またはクラスまたはコンポーネントからの SomethingElse のリストを要求し、aspx を残してプレゼンテーションを処理します。 . ここでは、ORM を使用したくない理由についても説明しています。

このルートに従うと、コードは次のようになります。

protected void Page_Load(object sender, EventArgs e) 
{
   if (IsPostBack == false)
   {
      string s = Request.QueryString["cat"];
      string s1 = Request.QueryString["sub"];
      //Still do validation on s and s1

      ObjectFactory of = new ObjjectFactory();
      DataGrid1.DataSource = ObjectFactory.GetObjects(s, s1);
      DataGrid1.DataBind();
    }
 }

事実上、オブジェクトを取得して収集する方法を心配するのは他の誰かの仕事になり、コード ビハインドに含まれるコードを大幅に削減できます。さらに、さまざまなインターフェイスで簡単に再利用できます。

于 2012-07-04T11:41:58.560 に答える
0
da = new SqlDataAdapter("select * from " + s + " where subcategory3='" + s1 + "'",con);
于 2012-07-04T10:51:55.340 に答える
-1

このような ?

SqlConnection con=new SqlConnection("Data Source=ANURAG-PC;Initial Catalog=dbPortal;Persist Security Info=True;User ID=sa;Password=anurag");
    SqlDataAdapter da;
    DataSet ds=new DataSet();
    static DataTable dt=new DataTable();


        protected void Page_Load(object sender, EventArgs e) 
        {
            if (IsPostBack == false)
            {
                string s = Request.QueryString["cat"];
                string s1 = Request.QueryString["sub"];


                da = new SqlDataAdapter("select * from '"+s+"' where subcategory3='" + s1 + "'",con);
                da.Fill(ds);
                dt = ds.Tables[0];
                DataGrid1.DataSource = dt;
                DataGrid1.DataBind();

            }



        }
于 2012-07-04T10:52:55.173 に答える