2011-10-25 36 views
0

我必須在我的存儲過程中執行SELECT ... FROM ... WHERE .. IN查詢。WHERE ... IN ...問題與SQL Server存儲過程

下面是代碼從我的存儲過程

ALTER PROCEDURE [dbo].[SP_GetQuestionSetMultiCat] 
    -- Add the parameters for the stored procedure here 
    @PIN varchar(50), 
    @CatIds varchar(50), 
    @Range int, 
    @Que_Type varchar(50) 

AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    declare @qtId as int; 
    select @qtId = Que_Type_Id from dbo.QuestionType_Tbl where [email protected]_Type; 


    -- Insert statements for procedure here 

     Select Top(@Range) 
      QId, 
      Que_Type_Id, 
      Que_Level_Id, 
      Que_Category_Id, 
      Que, 
      Opt1, 
      Opt2, 
      Opt3, 
      Opt4, 
      Ans 
     From 
      dbo.Que_Tbl 
     Where 
      (Que_Category_Id in (cast(@CatIds as varchar))) 
      and ([email protected]) 
      and (Qid not in (Select Que_Id From dbo.UserQuestion_Mapping where [email protected] and [email protected])) 


END 

看WHERE條件。 Que_Category_Id是int類型。我想要執行的是 -

Where Que_Category_Id in (1,2,3,4) 

傳遞的in值是從我的C#代碼轉換而來的字符串。

當我執行這樣的查詢 -

exec SP_GetQuestionSetMultiCat '666777','4,5,6',5,'Practice' 

它產生錯誤 - 轉換VARCHAR值時

轉換失敗 '{4,5,6}' 爲int數據類型。

任何人都可以幫助我解決這個問題。

感謝您分享寶貴的時間。

回答

3

1)Conversion failed when converting the varchar value '{4,5,6}' to data type int.

此錯誤的原因是data type precedenceINT數據類型比VARCHAR數據類型(16-INT與27-VARCHAR)具有「更高」的優先級。 因此,SQL Server正試圖將'{4,5,6}'轉換爲INT,而不是相反。

2)相反,我會轉換@CatIdsXML,然後使用nodes(...) method表變量(@IDs):

SET ANSI_WARNINGS ON; 

DECLARE @CatIds VARCHAR(50) = '4,5,6'; 

DECLARE @x XML; 
SET  @x = '<node>' + REPLACE(@CatIds, ',', '</node> <node>') + '</node>'; 
DECLARE @IDs TABLE 
(
    ID INT PRIMARY KEY 
); 
INSERT @IDs(ID) 
SELECT t.c.value('.', 'INT') 
FROM @x.nodes('/node') t(c); 

--Test  
SELECT * 
FROM @IDs 

3)的下一步是使用IN (SELECT ID FROM @IDs)代替in (cast(@CatIds as varchar))重寫查詢:

SET ANSI_WARNINGS ON; 

ALTER PROCEDURE [dbo].[SP_GetQuestionSetMultiCat] 
    -- Add the parameters for the stored procedure here 
    @PIN varchar(50), 
    @CatIds varchar(50), 
    @Range int, 
    @Que_Type varchar(50) 

AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    declare @qtId as int; 
    select @qtId = Que_Type_Id from dbo.QuestionType_Tbl where [email protected]_Type; 

    --Start: New T-SQL code 
    DECLARE @x XML; 
    SET  @x = '<node>' + REPLACE(@CatIds, ',', '</node> <node>') + '</node>'; 
    DECLARE @IDs TABLE 
    (
     ID INT PRIMARY KEY 
    ); 
    INSERT @IDs(ID) 
    SELECT t.c.value('.', 'INT') 
    FROM @x.nodes('/node') t(c); 
    --End 

    -- Insert statements for procedure here 

     Select Top(@Range) 
      QId, 
      Que_Type_Id, 
      Que_Level_Id, 
      Que_Category_Id, 
      Que, 
      Opt1, 
      Opt2, 
      Opt3, 
      Opt4, 
      Ans 
     From 
      dbo.Que_Tbl 
     Where 
      --The search condition is rewritten using IN(subquery) 
      Que_Category_Id in (SELECT ID FROM @IDs) 
      and ([email protected]) 
      and (Qid not in (Select Que_Id From dbo.UserQuestion_Mapping where [email protected] and [email protected])) 


END 

4)呼叫存儲過程:

exec SP_GetQuestionSetMultiCat '666777','4,5,6',5,'Practice'