我被困在写这个查询。我有这些表:
菜肴:
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();
}
}
答案 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
一旦你重写了查询,纠正它应该是微不足道的。