2009-09-18 46 views
0

拉記錄假設你有WIDGETS表:SQL可以由可能的三個值或者根本沒有

  • 爲widgetid INT
  • ColorID INT(查找值:紅,藍,綠,黃,黑,布朗)
  • SizeID INT(查找值:小,中,大,大)
  • 重量INT(查找值:超輕,輕,正常,重,UltraHeavy

好吧,這是表的一般想法。我不需要查找名稱,我所擁有的是lookupvalue ID。所以從這個表,我就能夠拉列表回到符合下面要說的crieria:

  1. 告訴我誰是紅色或藍色或黑色的所有部件
  2. 告訴我誰是紅色或所有小工具藍,和小或醫學
  3. 告訴我誰是沉重的所有部件只
  4. 告訴我誰是沉重和黃所有小
  5. 告訴我誰是沉重和黃大或小的所有部件
  6. 告訴我所有隻有大號的小配件只有
  7. 讓我看看所有隻有綠色的小工具

想到這個主意嗎?我一直在嘗試使用Stored Proc,它允許我發送某種類型的參數。即使嘗試了動態SQL,但得到奇怪的錯誤。現在不記得了。

我嘗試3,排序的作品,如果我能得到它在一個Proc工作,並能夠調節出其加入的我想要什麼,我已經試過

例子:

注:以我的例子:(CourseID是爲widgetid)和(STATEID是ColorID)和(CreditTypeID是SizeID)和(SubjectID是WeightID)

嘗試方法1

ALTER PROCEDURE [dbo].[CourseListFullInfoByStateCreditSubject] 
    @StateIDs VARCHAR(200) = '', 
    @CreditTypeIDs VARCHAR(200) = '', 
    @SubjectTypeIDs VARCHAR(200) = '' 
AS 

BEGIN 

    DECLARE @SQL AS NVARCHAR(MAX) 
    SET @SQL = 'SELECT DISTINCT 
        C.CourseID, 
        LU.FirstName, 
        LU.LastName, 
        (SELECT COUNT(ReviewID) FROM Review AS R WHERE R.CourseID = C.CourseID) AS ReviewCount 
       FROM [Course] AS C WITH(NOLOCK) 
       JOIN LexUser AS LU ON LU.LexUserID = C.PresenterID ' 

If @StateIDs IS NOT NULL AND @StateIDs <> '''' AND @StateIDs <> '0' 
BEGIN 
    SET @SQL = @SQL + ' JOIN CourseToState AS CS ON CS.CourseID = C.CourseID AND CHARINDEX('','' + CAST(CS.StateID AS VARCHAR) + '','', '','' + @StateIDs + '','') > 0 ' 
END 

If @CreditTypeIDs IS NOT NULL AND @CreditTypeIDs <> '' AND @CreditTypeIDs <> '0' 
BEGIN 
    SET @SQL = @SQL + 'JOIN CourseToCreditType As CC ON CC.CourseID = C.CourseID AND CHARINDEX('','' + CAST(CC.CreditTypeID AS VARCHAR) + '','', '','' + @CreditTypeIDs + '','') > 0 ' 
END 

If @SubjectTypeIDs IS NOT NULL AND @SubjectTypeIDs <> '' AND @SubjectTypeIDs <> '0' 
BEGIN 
    SET @SQL = @SQL + 'JOIN CourseToSubject As CSu ON CSu.CourseID = C.CourseID AND CHARINDEX('','' + CAST(CSu.SubjectID AS VARCHAR) + '','', '','' + @SubjectTypeIDs + '','') > 0 ' 
END 

EXEC sp_executesql @SQL 

有了嘗試1我嘗試發送的ID的:

[CourseListFullInfoByStateCreditSubject] ''1,2,4'', ''0'', ''0'' 

...但我得到一個錯誤,「附近有語法錯誤 '1'。「

嘗試方法2,使同樣的錯誤

DECLARE @SQL AS NVARCHAR(MAX) 
SET @SQL = 'SELECT DISTINCT 
        C.CourseID, 
        LU.FirstName, 
        LU.LastName, 
        (SELECT COUNT(ReviewID) 
        FROM Review AS R 
        WHERE R.CourseID = C.CourseID) AS ReviewCount 
      FROM [Course] AS C WITH(NOLOCK) 
      JOIN LexUser AS LU ON LU.LexUserID = C.PresenterID ' 

If @StateIDs IS NOT NULL AND @StateIDs <> '''' AND @StateIDs <> '0' 
BEGIN 
    SET @SQL = @SQL + ' JOIN CourseToState AS CS ON CS.CourseID = C.CourseID AND CHARINDEX('','' + CAST(CS.StateID AS VARCHAR) + '','', '','' + @StateIDs + '','') > 0 ' 
END 

If @CreditTypeIDs IS NOT NULL AND @CreditTypeIDs <> '' AND @CreditTypeIDs <> '0' 
BEGIN 
    SET @SQL = @SQL + 'JOIN CourseToCreditType As CC ON CC.CourseID = C.CourseID AND CHARINDEX('','' + CAST(CC.CreditTypeID AS VARCHAR) + '','', '','' + @CreditTypeIDs + '','') > 0' 
END 

If @SubjectTypeIDs IS NOT NULL AND @SubjectTypeIDs <> '' AND @SubjectTypeIDs <> '0' 
BEGIN 
    SET @SQL = @SQL + 'JOIN CourseToSubject As CSu ON CSu.CourseID = C.CourseID AND CHARINDEX('','' + CAST(CSu.SubjectID AS VARCHAR) + '','', '','' + @SubjectTypeIDs + '','') > 0' 
END 

嘗試方法3 - 排序作品 此方法僅如果我把它的ID對每個菲爾德的作品,我不能離開一個空白得到「所有」,我不能把它在一個存儲過程,而這正是我試圖嘗試#做2

DECLARE @StateIDs VARCHAR(200) = '' 
DECLARE @CreditTypeIDs VARCHAR(200) = '' 
DECLARE @SubjectTypeIDs VARCHAR(200) = '' 
SET @StateIDs = '1,3,2,' 
SET @CreditTypeIDs = '1,3' 
SET @SubjectTypeIDs = '1,2,3,4' 

SELECT DISTINCT 
     C.CourseID, 
     LU.FirstName, 
     LU.LastName, 
     (SELECT COUNT(ReviewID) FROM Review AS R WHERE R.CourseID = C.CourseID) AS ReviewCount 
    FROM [Course] AS C WITH(NOLOCK) 
    JOIN LexUser AS LU ON LU.LexUserID = C.PresenterID 
    JOIN CourseToState AS CS ON CS.CourseID = C.CourseID AND CHARINDEX(',' + CAST(CS.StateID AS VARCHAR) + ',', ',' + @StateIDs + ',') > 0 
    JOIN CourseToCreditType As CC ON CC.CourseID = C.CourseID AND CHARINDEX(',' + CAST(CC.CreditTypeID AS VARCHAR) + ',', ',' + @CreditTypeIDs + ',') > 0 
    JOIN CourseToSubject As CSu ON CSu.CourseID = C.CourseID AND CHARINDEX(',' + CAST(CSu.SubjectID AS VARCHAR) + ',', ',' + @SubjectTypeIDs + ',') > 0 

回答

0

怎麼是這樣的:

請用逗號分隔的條件列表中的存儲過程,應該像

DECLARE @colorConditions VARCHAR(100) 
SET @colorConditions = ' Red, Blue, Green, Yellow, Black, Brown, ' 

DECLARE @sizeConditions VARCHAR(100) 
SET @sizeConditions = ' Small, Med, Big, Large, ' 

DECLARE @weightConditions VARCHAR(100) 
SET @weightConditions = ' UltraLight, Light, Normal, Heavy, UltraHeavy, ' 

DECLARE @SQL VARCHAR(1000) 
SET @SQL = 
    'SELECT * 
     FROM Widgets W 
     INNER JOIN Colors C 
     ON W.ColorID = C.ColorID AND ''' + @colorConditions + ''' LIKE ''% '' + C.Color + '', %'' 
     INNER JOIN Sizes S 
     ON W.SizeID = S.SizeID AND ''' + @sizeConditions + ''' LIKE ''% '' + S.Size + '', %'' 
     INNER JOIN Weight WT 
     ON W.WeightID = W.WeightID AND ''' + @weightConditions + ''' LIKE '' %'' + WT.Weight + '', %''' 

EXEC (@SQL) 

這裏沒有什麼特別。它所做的只是將每個特徵(顏色,大小,重量)與符合條件的逗號分隔列表進行匹配。如果你想過濾藍色項目,你應該傳遞字符串'藍色'。側面的空格和逗號應該存在,因爲它們更容易在那裏與SQL進行對抗。然後,條件字符串比較像這樣每種顏色值:

Condition string: 

' Blue, Green, ' 

Colors: 

Red 
Blue 
Green 

...AND ' Blue, Green, ' LIKE '% Red, %' -- fails 
...AND ' Blue, Green, ' LIKE '% Blue, %' -- succeeds 
...AND ' Blue, Green, ' LIKE '% Green, %' -- succeeds 

這必須動態執行,除非你分割開出的條件不知何故到一個臨時表,並使用IN操作。

0

嘗試從左邊小工具加入到所有的查找工作並使用Where過濾出相應的行。

0

試試這個......來調用它,對於每個參數,傳遞null來忽略,或者位掩碼 你想包括的值的組合。根據以下圖表 ...

-- ----Color ---- 
Red = 1 
Blue = 2 
Green = 4 
Yellow = 8 
Black = 16 
Brown = 32 
Red Or Green = 5 

-- ---- Size --- 
Small = 1 
Medium = 2 
Big = 4 
Large = 8 

-- ----Weight ---- 
UltraLight = 1 
Light  = 2 
Normal  = 4 
Heavy  = 8 
UltraHeavy = 16 

此外,改變在數據庫(在查找表中兩者的PK在窗口小部件表,FKS)查找的整數值,使得它們的所有的兩個適當的權力(1,2,4,8,16 ...)

-- ------------------------- 
Create procedure GetWidgets 
@Color TinyInt = Null, 
@Size TinyInt = Null 
@Weight TinyInt = Null 
As 
Set NoCount On 

-- ------------------------------- 

    Select * From Widgets 
    Where Color & IsNull(@Color, Color)> 0 
     And Size & IsNull (@Size,Size) > 0 
     And Weight & IsNull (@Weight, Weight) > 0 

    Return 0 
-- ------------------------- 

0

此解決方案的前提條件是分裂表值函數。網上有很多例子,但我建議使用使用Tally或「Numbers」表的變體,因爲它是最快的。一旦你有了,解決方案有點微不足道:

Declare @StateIdList nvarchar(max) 
Declare @CreditTypeIdList nvarchar(max) 
Declare @SubjectTypeIds nvarchar(max) 

Select F1....Fn 
From Course As C 
Where (
     @StateIdList Is Null 
     Or Exists(
        Select 1 
        From CourseToState As CS1 
         Join dbo.Split(@StateIdList) As S1 
          On S1.Id = CS1.Id 
        Where CS1.CourseId = C.CourseId 
        ) 
     ) 
    And (
     @CreditTypeIdList Is Null 
     Or Exists(
        Select 1 
        From CourseToCreditType As CT1 
         Join dbo.Split(@CreditTypeIdList) As S1 
          On S1.Id = CT1.Id 
        Where CT1.CourseId = C.CourseId 
        ) 
     ) 
    And (
     @SubjectTypeIds Is Null 
     Or Exists(
        Select 1 
        From CourseToSubject As CSu1 
         Join dbo.Split(@CreditTypeIdList) As S1 
          On S1.Id = CSu1.Id 
        Where CSu1.CourseId = C.CourseId 
        ) 
     ) 
相關問題