0

部屋のリストを送信する Web サービスを ASP.Net で構築します。

パラメータはコンマで区切られた ID です。

それらを文字列に保存し、SQL 選択クエリを作成しました。

4 つのパラメーターすべてを送信すると、すべてが正常に機能し、結果が得られます。しかし、4未満を送信すると、エラーが発生します。

System.Data.SqlClient.SqlException: Incorrect syntax near ')'.

入力した値だけを選択するために、SQL クエリでパラメータをオプションに設定するにはどうすればよいですか?

これまでの私のコードは次のとおりです。

internal static List<RAUM> Raum(string RAUMKLASSE_ID, string STADT_ID, string GEBAEUDE_ID, string REGION_ID)
{
    List<RAUM> strasseObject = new List<RAUM>();
    string raumklasseid = RAUMKLASSE_ID;
    string gebaudeid = GEBAEUDE_ID;
    string stadtid = STADT_ID;
    string regionid = REGION_ID;

    using (SqlConnection con = new SqlConnection(@"Data Source=Localhost\SQLEXPRESS;Initial Catalog=BOOK-IT-V2;Integrated Security=true;"))
    using (SqlCommand cmd = new SqlCommand(@"SELECT r.BEZEICHNUNG AS BEZEICHNUNG, r.ID AS ID FROM RAUM r WHERE RAUMKLASSE_ID IN (" + raumklasseid + ") AND STADT_ID IN (" + stadtid + ") AND GEBAEUDE_ID IN (" + gebaudeid + ") AND REGION_ID IN (" + regionid + ")", con))
    {
        con.Open();

        using (SqlDataReader rdr = cmd.ExecuteReader())
        {
            while (rdr.Read())
            {
                if (rdr["BEZEICHNUNG"] != DBNull.Value && rdr["ID"] != DBNull.Value)
                {
                    strasseObject.Add(new RAUM()
                    {
                        RaumName = rdr["BEZEICHNUNG"].ToString(),
                        RaumID = rdr["ID"].ToString()
                    });
                }
            }
        }
    }

    return strasseObject;
}

よろしくお願いします。

4

2 に答える 2

2

REGION_IDパラメータが空の文字列であると想像してください。クエリのその部分は次のようになります。

...AND REGION_ID IN ()...

AND REGION_ID IN (" + regionid + ")"変数はregionid空の文字列に置き換えられるためです。これは有効な SQL 構文ではないため、その例外が発生します。

次のように関数を宣言します。

private static void AppendConstrain(StringBuilder query, string name, string value)
{
    if (String.IsNullOrWhiteSpace(value))
        return;

    if (query.Length > 0)
        query.Append(" AND ");
    
    query.AppendFormat("{0} IN ({1})", name, value);
}

次に、コードを変更して、次の方法でクエリを作成します。

StringBuilder constrains = new StringBuilder();
AppendConstrain(contrains, "RAUMKLASSE_ID", RAUMKLASSE_ID);
AppendConstrain(contrains, "GEBAEUDE_ID", GEBAEUDE_ID);
AppendConstrain(contrains, "STADT_ID", STADT_ID);
AppendConstrain(contrains, "REGION_ID", REGION_ID);

StringBuilder query =
    new StringBuilder("SELECT r.BEZEICHNUNG AS BEZEICHNUNG, r.ID AS ID FROM RAUM r");

if (constrains.Length > 0)
{
    query.Append(" WHERE ");
    query.Append(constrains);
}

using (SqlCommand cmd = new SqlCommand(query.ToString(), con))
{
    // Your code...
}

警告: このコードは、SQL インジェクションに対して脆弱であるため、本番環境またはユーザーからの入力時には使用しないでください。より良いアプローチについては (受け入れられた回答にとどまらないでください) 、SQL IN 句のパラメーター化を参照してください。

于 2012-06-19T11:25:44.250 に答える
0

ストアド プロシージャを記述してパラメータを渡す方が常に優れた方法です。しかし、あなたのアプローチでは、値がわからないため、クエリを分割する必要があります。だから、あなたのコードはそのようなものになります..

自分でテストしてください、私はそれをチェックしませんでした

string raumklasseid = RAUMKLASSE_ID;
        string gebaudeid = GEBAEUDE_ID;
        string stadtid = STADT_ID;
        string regionid = REGION_ID;
        string whereClause = string.Empty;

if (!string.IsNullorEmpty(raumklasseid))
{
   whereClause = "RAUMKLASSE_ID IN (" + raumklasseid + ")";
}
if (!string.IsNullorEmpty(stadtid ))
{
   if(string.IsNullorEmpty(whereClause)
      whereClause = "STADT_ID IN (" + stadtid + ")";
   else 
      whereClause += "AND RSTADT_ID IN (" + stadtid + ")";
}
if (!string.IsNullorEmpty(stadtid ))
{
   if(string.IsNullorEmpty(whereClause)
      whereClause = "STADT_ID IN (" + stadtid + ")";
   else 
      whereClause += "AND RSTADT_ID IN (" + stadtid + ")";
}
if (!string.IsNullorEmpty(regionid))
{
   if(string.IsNullorEmpty(whereClause)
      whereClause = "REGION_ID IN (" + regionid + ")";
   else 
      whereClause += "AND REGION_ID IN (" + regionid + ")";
}

if(!string.IsNullorEmpty(whereClause)
whereClause = "WHERE " + whereClause ;

// now your cmd should be like that

using (SqlCommand cmd = new SqlCommand(@"SELECT r.BEZEICHNUNG AS BEZEICHNUNG, r.ID AS ID FROM RAUM r " + whereClause , con))
于 2012-06-19T11:20:38.773 に答える