2014-11-13 24 views
0

我有一個存儲過程,其中我傳入一個產品類型(prod_type)作爲參數,最多四次。潛在地,這些參數中的每一個可能都是空的,在這種情況下它們應該被忽略。他們應該在每種產品類型之間有一個OR操作符,以便我們收集所有要求的產品類型。TSQL可選參數在同一個字段上工作

如果可能的話,我想避免使用通過sp_ExecuteSQL傳遞的動態SQL(我知道這很容易)。

的什麼,我試圖做一個簡單的,孤立的版本是下面的討論:

CREATE TABLE #Products (Prod_ID int, prod_type int); 

INSERT INTO #Products 
SELECT 1, 2 
UNION ALL 
SELECT 2, 3 
UNION ALL 
SELECT 3, 3 
UNION ALL 
SELECT 4, 1 
UNION ALL 
SELECT 4, 5 

DECLARE @prod_type1 as int; 
DECLARE @prod_type2 as int; 
DECLARE @prod_type3 as int; 
DECLARE @prod_type4 as int; 

SET @prod_type1 = NULL; 
SET @prod_type2 = 2; 
SET @prod_type3 = NULL; 
SET @prod_type4 = 3; 

Select * from #Products 
WHERE ((prod_type = ISNULL(@prod_type1,prod_type)) 
OR (prod_type = ISNULL(@prod_type2,prod_type)) 
OR (prod_type = ISNULL(@prod_type3,prod_type) 
OR (prod_type = ISNULL(@prod_type4,prod_type)))) 

在哪裏,我想執行的是一樣的東西:

Select * from [Product].[Product] 
WHERE (prod_type = 2 OR prod_type = 3) 

顯然,上述ISNULL的解決方法將不起作用,因爲ISNULL方法會將每行的產品類型與自身進行比較,這將導致正面的「命中」。 COALESCE將會有同樣的問題。

任何人都可以提出一個解決方案,不涉及使用sp_ExecuteSQL?

回答

0

試試像這樣改變你Where Clause

Select * 
from 
#Products 
WHERE prod_type in(@prod_type1,@prod_type2,@prod_type2,@prod_type4) 
1

試試這個:

DECLARE @ProdTypes TABLE (Prod_Type INT NOT NULL); 

INSERT INTO @ProdTypes (Prod_Type) VALUES (2); 
INSERT INTO @ProdTypes (Prod_Type) VALUES (3); 

SELECT pr.* 
FROM #Products pr 
WHERE EXISTS (SELECT 1 
       FROM @ProdTypes pt 
       WHERE pt.Prod_Type = pr.Prod_Type); 

使用EXISTS允許什麼是邏輯上一個OR條件。如果找到匹配,這樣就不會在@ProdTypes除非通過所有行運行EXISTS將退出:

  • 沒有匹配值
  • 的匹配值是集合中的最後一個; - )

但很多時候它會在掃描整個表變量之前退出。

編輯:
此外,你不應該在多個@Prod_TypeX參數,你的程序通過。相反,在經過INTS的CSV列表,並使用SQLCLR-或基於XML的字符串分離器插入到表變量,如:

INSERT INTO @ProdTypes (Prod_Type) 
    SELECT CONVERT(INT, csv.SplitVal) 
    FROM dbo.SQLCLRorXMLbasedSplitter(@ProdTypesCSV) csv; 
+1

同樣想法。最佳方法+1。 – Rahul

相關問題