2008-09-27 191 views
5

问题:在[ñ]在配方成分SQL服务器:动态where子句

阿贾克斯建议的搜索。那就是:匹配多种配料的食谱。

例如:SELECT Recipes using "flower", "salt"将产生:"Pizza", "Bread", "Saltwater"等等。

表:

Ingredients [ 
    IngredientsID INT [PK], 
    IngredientsName VARCHAR 
] 

Recipes [ 
    RecipesID INT [PK], 
    RecipesName VARCHAR 
] 

IngredientsRecipes [ 
    IngredientsRecipesID INT [PK], 
    IngredientsID INT, 
    RecipesID INT 
] 

查询:

SELECT 
    Recipes.RecipesID, 
    Recipes.RecipesName, 
    Ingredients.IngredientsID, 
    Ingredients.IngredientsName 
FROM 
    IngredientsRecipes 

    INNER JOIN Ingredients 
    ON IngredientsRecipes.IngredientsID = Ingredients.IngredientsID 

    INNER JOIN Recipes 
    ON IngredientsRecipes.RecipesID = Recipes.RecipesID 
WHERE 
    Ingredients.IngredientsName IN ('salt', 'water', 'flower') 

我目前正在建设由于WHERE条款的动态性质使用ASP.NET C#我的查询。

我咬了一口,我不得不在我的代码层中构建查询,而不是使用存储过程/纯SQL,这在理论上应该快得多。

你们有没有想过如何将我的代码层中的所有逻辑移到纯SQL,或者至少我如何优化我所做的工作?

第一步SELECT IngredientsID FROM IngredientsINSERT INTO temp-table

第二步

我沿着临时表的行思SELECT RecipesName FROM Recipes加入了与IngredientsRecipestemp-table.IngredientsID

回答

7

您有两种选择。如果您使用SQL Server 2008(或Oracle),则可以传入table value parameter

如果您使用SQL Server 2005中,你如果你正在使用的东西比2005年早些时候可以使用XML to simulate this capability

,你需要连接的ID在一个字符串,并创建一个UDF解析他们。

2

加盟取决于你怎么上正在处理输入的成分我认为这个当前的方法有一些SQL注入风险。

您可以将连接条件名添加到可能更快的连接条件中。

你也可以散列成分的组合信息进行快速查找。

+0

我同意。脚本注入问题也是我的担忧之一。你能否详细说明“hasing”? – roosteronacid 2008-09-27 22:15:47

+0

如果您有用户从可能的成分列表中进行选择,那么您可以在您的成分表格中选择,可以在您的where语句中以编程方式使用这些id,并且不会出现注射问题。 – Brettski 2008-09-27 22:20:44

+0

例如如果您通过添加盐水面粉来处理MD5或SHA1散列,您将获得一个值(您的散列)。在你的查找中,你可以找到与此匹配的项目。 正如你比较一个值而不是列表,它会更快。 – alexmac 2008-09-27 22:27:17

3

你至少可以参数化的地方clausule避免SQL注入,东西一样:

using System.Data; 
using System.Data.SqlClient; 
using System.Text; 

class Foo 
{ 
    public static void Main() 
    { 
     string[] parameters = {"salt", "water", "flower"}; 
     SqlConnection connection = new SqlConnection(); 
     SqlCommand command = connection.CreateCommand(); 
     StringBuilder where = new StringBuilder(); 
     for (int i = 0; i < parametes.Length; i++) 
     { 
      if (i != 0) 
       where.Append (","); 
      where.AppendFormat ("@Param{0}", i); 
      command.Parameters.Add (new SqlParameter ("Param" + i, parameters [i])); 
     } 
    } 
}