如何在.NET中与AND条件和另一个条件的结果

时间:2013-01-31 16:39:45

标签: sql sql-server tsql

我被困在写这个查询。我有这些表:

菜肴:
 CuisineID
 CuisineName
 CuisineType

菜:
 DishID
DishName
菜系ID

设施:
 FacilityID
 FacilityName

RestaurantDish:  RestaurantDishID  RestaurantID  DishID

餐厅:    RestaurantID    名称    市    地点    PHONENO

我必须根据用户对设施或菜肴或美食的选择来展示餐馆。一旦我有一个餐厅列表,我必须通过每个用户选择进一步完善相同的列表。我写了这个不起作用的stoed程序:

          ALTER PROCEDURE [dbo].[spGetFilterData]
@searchText NVARCHAR(MAX),
@DishIDs NVARCHAR(200) ,
@FacilitDs NVARCHAR(200) ,
@CuisineIDs NVARCHAR(200)
 AS 
BEGIN

    SET NOCOUNT ON;

    DECLARE @sql NVARCHAR(MAX)
    SET @sql = '';

    SET @sql = 'SELECT  RestaurantID ,
            Name ,
            City ,
            Location ,
            Country ,
            PhoneNo1 ,
            PhoneNo2 ,
            PhoneNo3 ,
            FaxNumber ,
            Timings ,
            HappyHour ,
            Menu ,
            Buffet ,
            Rating ,
            DateCreated ,
            Datemodified ,
            DateDeleted
    FROM    dbo.Restaurants AS r
    WHERE   ( RestaurantID IN (
              SELECT    rd.RestaurantID
              FROM      dbo.RestaurantDish AS rd
                        INNER JOIN dbo.Dishes1 AS d ON d.DishID = rd.DishID
              WHERE     ( d.DishName LIKE ''%' + @searchText + '%'''

    IF @DishIDs <> '' 
        BEGIN
            SET @sql =@sql + '   AND d.DishID IN ( ' + @DishIDs + ' )'

        END 
    SET @sql =@sql + ') ) )'       
    SET @sql =@sql + ' AND ( RestaurantID IN (
                 SELECT rf.RestaurantID
                 FROM   dbo.RestaurantFacility AS rf
                        INNER JOIN dbo.Facilities1 AS f ON f.FacilityID = rf.FacilityID
                 WHERE  ( f.FacilityName LIKE ''%' + @searchText + '%'''
    IF @FacilitDs <> '' 
        BEGIN
            SET @sql =@sql + ' AND f.FacilityID IN ( ' + @FacilitDs + ' )'
        END
    SET @sql =@sql + ') ) )'  
    SET @sql =@sql + '  OR ( RestaurantID IN (
                 SELECT RestaurantID
                 FROM   dbo.RestaurantDish
                 WHERE  ( DishID IN (
                          SELECT    dbo.RestaurantDish.DishID
                          FROM      dbo.Cuisine1
                          WHERE     ( CuisineName LIKE ''%' + @searchText
        + '%'')'
    IF @CuisineIDs <> '' 
        BEGIN
            SET @sql = @sql +' AND CuisineID IN ( ' + @CuisineIDs + ' )'
        END
    SET @sql =@sql + ') ) ))'                         
    SET @sql =@sql + '  OR ( Name LIKE ''%' + @searchText + '%'')
            OR ( City LIKE ''%' + @searchText + '%'')
            OR ( Country LIKE ''%' + @searchText + '%'')
            OR ( Buffet LIKE ''%' + @searchText + '%'')
            OR ( Location LIKE ''%' + @searchText + '%'')'
    EXECUTE sp_executesql @sql;     
END

我不知道该怎么做..  这是我的班级:

         public class DBAccess
       {
        public DBAccess()
       {
    //
    // TODO: Add constructor logic here
    //
        }
private SqlConnection GetConnection()
{
    SqlConnection con = null;
    try
    {
        string strCon = ConfigurationManager.ConnectionStrings["food4uConnectionString"].ConnectionString;
        con = new SqlConnection(strCon);
        con.Open();

    }
    catch (Exception ex)
    {
        con.Close();
        throw;
    }
    return con;
}

public List<Restaurants> GetAllRestaurents(string searchText, string dishIDs, string facilityIDs, string cuisineIDS)
{
    List<Restaurants> restaurants = null;
    try
    {
        SqlCommand cmd = new SqlCommand("spGetFilterData", GetConnection());
        cmd.CommandType = System.Data.CommandType.StoredProcedure;

        cmd.Parameters.AddWithValue("searchText", searchText);
        cmd.Parameters.AddWithValue("DishIDs", dishIDs);
        cmd.Parameters.AddWithValue("FacilitDs", facilityIDs);
        cmd.Parameters.AddWithValue("CuisineIDs", cuisineIDS);

        SqlDataReader dreader = cmd.ExecuteReader();
        restaurants = new List<Restaurants>();
        while (dreader.Read())
        {
            restaurants.Add(new Restaurants()
            {
                RestaurantID = (int)dreader["RestaurantID"],
                Name = (string)dreader["Name"],
                City = (string)dreader["City"],
                Country = (string)dreader["Country"],
                Location = (string)dreader["Location"],
                PhoneNo1 = (string)dreader["PhoneNo1"],
                PhoneNo2 = (string)dreader["PhoneNo2"],
                PhoneNo3 = (string)dreader["PhoneNo3"],
                Menu = (string)dreader["Menu"],
                HappyHour = (string)dreader["HappyHour"],
                Buffet = (string)dreader["Buffet"],
                Rating = (string)dreader["Rating"],
                FaxNo = (string)dreader["FaxNumber"],
                Timings = (DateTime)dreader["Timings"],
                DateCreated = (DateTime)dreader["DateCreated"],
                DateDeleted = (DateTime)dreader["DateDeleted"],
                Datemodified = (DateTime)dreader["DateModified"]
            });
        }
    }
    catch (Exception ex)
    {
        throw;
    }

    return restaurants;
}

public List<Facilities1> GetFacilities(int restaurentID, string facilityID)
{
    List<Facilities1> facilities = null;
    try
    {
        SqlCommand cmd = new SqlCommand("spGetFacilities", GetConnection());
        cmd.CommandType = System.Data.CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("RestaurantID", restaurentID);
        cmd.Parameters.AddWithValue("FacilityID", facilityID);
        SqlDataReader dreader = cmd.ExecuteReader();
        facilities = new List<Facilities1>();
        while (dreader.Read())
        {
            facilities.Add(new Facilities1()
            {
                FacilityID = (int)dreader["FacilityID"],
                FacilityName = (string)dreader["FacilityName"]
            });
        }
    }
    catch (Exception ex)
    {
        throw;
    }

    return facilities;
}

public List<Dishes1> GetDishes(int restaurentID, string dishID)
{
    List<Dishes1> dishes = null;
    try
    {
        SqlCommand cmd = new SqlCommand("spGetDishes", GetConnection());
        cmd.CommandType = System.Data.CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("RestaurantID", restaurentID);
        cmd.Parameters.AddWithValue("DishID", dishID);
        SqlDataReader dreader = cmd.ExecuteReader();
        dishes = new List<Dishes1>();
        while (dreader.Read())
        {
            dishes.Add(new Dishes1()
            {
                DishID = (int)dreader["DishID"],
                DishName = (string)dreader["DishName"],
                Price = (int)dreader["Price"]
            });
        }
    }
    catch (Exception ex)
    {
        throw;
    }

    return dishes;
}

public List<Cuisine> GetCuisines(int restaurentID, string cousineID)
{
    List<Cuisine> cuisines = null;
    try
    {
        SqlCommand cmd = new SqlCommand("spGetCuisines", GetConnection());
        cmd.CommandType = System.Data.CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("RestaurantID", restaurentID);
        cmd.Parameters.AddWithValue("CuisineID", cousineID);
        SqlDataReader dreader = cmd.ExecuteReader();
        cuisines = new List<Cuisine>();
        while (dreader.Read())
        {
            cuisines.Add(new Cuisine()
            {
                CuisineID = (int)dreader["CuisineID"],
                CuisineName = (string)dreader["CuisineName"]
            });
        }
    }
    catch (Exception ex)
    {
        throw;
    }

    return cuisines;
}

public List<Dishes1> GetAllDishes()
{
    List<Dishes1> dishes = null;
    try
    {
        SqlCommand cmd = new SqlCommand("Select DishID, DishName From Dishes1", GetConnection());
        cmd.CommandType = System.Data.CommandType.Text;
        SqlDataReader dreader = cmd.ExecuteReader();
        dishes = new List<Dishes1>();
        while (dreader.Read())
        {
            dishes.Add(new Dishes1()
            {
                DishID = (int)dreader["DishID"],
                DishName = (string)dreader["DishName"]
            });
        }
    }
    catch (Exception ex)
    {
        throw;
    }

    return dishes;
}

public List<Cuisine> GetAllCuisine()
{
    List<Cuisine> cuisines = null;
    try
    {
        SqlCommand cmd = new SqlCommand("Select CuisineID,  CuisineName From Cuisine1", GetConnection());
        cmd.CommandType = System.Data.CommandType.Text;
        SqlDataReader dreader = cmd.ExecuteReader();
        cuisines = new List<Cuisine>();
        while (dreader.Read())
        {
            cuisines.Add(new Cuisine()
            {
                CuisineID = (int)dreader["CuisineID"],
                CuisineName = (string)dreader["CuisineName"]
            });
        }
    }
    catch (Exception ex)
    {
        throw;
    }

    return cuisines;
}

public List<Facilities1> GetAllFacilities()
{
    List<Facilities1> facilities = null;
    try
    {
        SqlCommand cmd = new SqlCommand("Select FacilityID, FacilityName from Facilities1", GetConnection());
        cmd.CommandType = System.Data.CommandType.Text;
        SqlDataReader dreader = cmd.ExecuteReader();
        facilities = new List<Facilities1>();
        while (dreader.Read())
        {
            facilities.Add(new Facilities1()
            {
                FacilityID = (int)dreader["FacilityID"],
                FacilityName = (string)dreader["FacilityName"]
            });
        }
    }
    catch (Exception ex)
    {
        throw;
    }

    return facilities;
}

} ///// 这是另一个类:

             public partial class Restaurant : System.Web.UI.Page
       {
public string facility = null;
public string cuis = null;
public string dish = null;
public string location = null;

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        BindListView();
        BindDishesAsCheckBoxes();
    }
}

private void BindListView()
{
    string searchText = this.txtSearch.Text;
    string facilityIDs = hfFacilityID.Value == "" ? "" : hfFacilityID.Value.Remove(hfFacilityID.Value.Length - 1);
    string dishIDs = hfDishID.Value == "" ? "" : hfDishID.Value.Remove(hfDishID.Value.Length - 1);
    string cuisineIDs = hfCuisineID.Value == "" ? "" : hfCuisineID.Value.Remove(hfCuisineID.Value.Length - 1);

    try
    {
        DBAccess objDB = new DBAccess();
        listView.DataSource = objDB.GetAllRestaurents(searchText, dishIDs, facilityIDs, cuisineIDs);
        listView.DataBind();
    }
    catch (Exception ex)
    {

    }
}

private void BindDishesAsCheckBoxes()
{
    try
    {
        DBAccess objdb = new DBAccess();

        //dishes
        chkDishes.DataSource = objdb.GetAllDishes();
        chkDishes.DataBind();

        //cuisines
        chkCuisine.DataSource = objdb.GetAllCuisine();
        chkCuisine.DataBind();

        //facilities
        chkFacilities.DataSource = objdb.GetAllFacilities();
        chkFacilities.DataBind();
    }
    catch (Exception ex)
    {

    }
}

#region itemdatabound

protected void ContactsListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{

    string facilityIDs = hfFacilityID.Value == "" ? "" : hfFacilityID.Value.Remove(hfFacilityID.Value.Length - 1);
    string dishIDs = hfDishID.Value == "" ? "" : hfDishID.Value.Remove(hfDishID.Value.Length - 1);
    string cuisineIDs = hfCuisineID.Value == "" ? "" : hfCuisineID.Value.Remove(hfCuisineID.Value.Length - 1);
    try
    {
        if (e.Item.ItemType == ListViewItemType.DataItem)
        {
            Label lbl1 = (Label)e.Item.FindControl("lblRestaurentID");
            DBAccess objdb = new DBAccess();

            //bind  facility
            Repeater rpFacility = (Repeater)e.Item.FindControl("rptFacility");
            rpFacility.DataSource = objdb.GetFacilities(Convert.ToInt32(lbl1.Text), facilityIDs);
            rpFacility.DataBind();

            //bind  dishes
            Repeater rpDish = (Repeater)e.Item.FindControl("rptDish");
            rpDish.DataSource = objdb.GetDishes(Convert.ToInt32(lbl1.Text), dishIDs);
            rpDish.DataBind();

            //bind  dishes
            Repeater rptCuisine = (Repeater)e.Item.FindControl("rptCuisine");
            rptCuisine.DataSource = objdb.GetCuisines(Convert.ToInt32(lbl1.Text), cuisineIDs);
            rptCuisine.DataBind();
        }
    }
    catch (Exception ex)
    {
        //dvError.Visible = true;
        //lblErrorMessage.Text = ex.Message;
    }
}

#endregion

protected void chkDishes_SelectedIndexChanged(object sender, EventArgs e)
{
    foreach (ListItem item in chkDishes.Items)
    {
        if (item.Selected)
        {
            string id = item.Value;
            hfDishID.Value += id + ",";
            BindListView();
        }
    }
}

protected void chkCuisine_SelectedIndexChanged(object sender, EventArgs e)
{
    foreach (ListItem item in chkCuisine.Items)
    {
        if (item.Selected)
        {
            string id = item.Value;
            hfCuisineID.Value += id + ",";
            BindListView();
        }
    }
}

protected void chkFacilities_SelectedIndexChanged(object sender, EventArgs e)
{
    foreach (ListItem item in chkFacilities.Items)
    {
        if (item.Selected)
        {
            string id = item.Value;
            hfFacilityID.Value += id + ",";
            BindListView();
        }
    }
}

protected void btnSeach_Click(object sender, EventArgs e)
{
    BindListView();
}

}

2 个答案:

答案 0 :(得分:0)

您正在编写动态SQL,这取决于用户正确放置字符串。我认为由于字符串创建中的错误,可能会发生爆炸。

要调试我会改变这一行:

 Execute sp_executesql @sql

 print @sql

这将为您提供表达式的原始文本。你可以复制并粘贴它,看看是什么爆炸了。请记住,动态sql可能会非常混乱,因为您正在将操作转换为您正在从字符串构建的引擎。

您必须确保您的用户传递我认为合法的变量

' ''valA'', ''valB'', ''ValC'' '

在传递varchar字段本身的varchar字段数组时,需要使用双引号标记引号。这会带来一个问题,因为您必须确保自己传入的字段本身是合法的。有些人已经找到了处理这个问题的不同方法,除了调试代码的方法之外,我还可以提供一些建议:

老实说,如果你有SQL Server 2008或更高版本,我会考虑使用'table type'来声明一个可以是表类型的自定义类型。使用您正在寻找的数组填充该表并将其传入。您可以构建在2008年之后采用表类型的表函数。函数IMHO可能并不总是与procs一样好但是它们非常易读并且可以单独作为对象使用链接使它们非常适合遵循封装和可用性规则。

答案 1 :(得分:0)

我假设您动态构建@sql的原因是您希望提供以逗号分隔的ID列表作为菜肴,美食和设施的标准。

然而,这使得查询不可读。所以不要这样做。

根据您的使用情况,针对上述每个条件使用a Table-Valued Parameter,或者为您分割字符串的a split function

简单但可读的分割功能:

ALTER FUNCTION [dbo].[fnStringSplit] (@list ntext)
         RETURNS @table TABLE (token varchar(4000) collate SQL_Latin1_General_CP1_CI_AS) 
AS
BEGIN
      DECLARE @pos       int,
              @textpos   int,
              @chunklen  smallint,
              @chunk     nvarchar(4000),
              @leftover  nvarchar(4000),
              @token     nvarchar(4000),
              @delimiter nchar(1)

      SET @delimiter = N','
      SET @textpos = 1
      SET @leftover = ''
      WHILE @textpos <= datalength(@list) / 2
      BEGIN
         SET @chunklen = 4000 - len(@leftover)
         SET @chunk = @leftover + substring(@list, @textpos, @chunklen)
         SET @textpos = @textpos + @chunklen

         SET @pos = charindex(@delimiter, @chunk)
         WHILE @pos > 0
         BEGIN
            SET @token = left(@chunk, @pos - 1)
            INSERT @table (token) VALUES(@token)
            SET @chunk = substring(@chunk, @pos + 1, len(@chunk))
            SET @pos = charindex(@delimiter, @chunk)
         END

         SET @leftover = @chunk
      END

      INSERT @table(token) VALUES (@leftover)
      RETURN
END

一旦你重写了查询,纠正它应该是微不足道的。