2008-09-27 119 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])); 
     } 
    } 
}