SQL Server:动态子句

时间:2020-03-06 14:49:58  来源:igfitidea点击:

问题:

Ajax建议对食谱中的[n]种成分进行搜索。也就是说:将食谱与多种成分相匹配。

例如:`使用"花","盐"的" SELECT食谱"将产生:""比萨饼","面包","盐水""等等。

表格:

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构造查询。

我咬到我必须在代码层中构造查询,而不是使用存储过程/纯SQL,这在理论上应该要快得多。

你们对我如何将所有逻辑从我的代码层转移到纯SQL有任何想法,或者至少我如何优化正在执行的性能?

我在考虑临时表的思路:

第一步:`从配料中选择IngredientsID,然后将其插入到临时表中。

第二步:将" SELECT RecipesName FROM Recipes"与" IngredientsRecipes"相结合,并与" temp-table.IngredientsID"相结合。

解决方案

根据我们处理输入成分的方式,我认为此当前方法具有一些sql注入风险。

我们可以将更快的名称添加到连接条件中,这样可能会更快。

我们还可以哈希配方组合以获得快速查找。

我们有两个选择。如果使用的是SQL Server 2008(或者Oracle),则可以传入表值参数。

如果我们使用的是SQL Server 2005,则可以使用XML来模拟此功能

如果我们使用的早于2005年的版本,则需要将ID串联在单个字符串中,并创建UDF来解析它们。

我们至少可以参数化where子句以避免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]));
        }
    }
}