2015-02-17 169 views
1

我有以下过程将字符串参数传递给我,例如,2,3,。该程序应返回一组行,其中CategoryId等于23无法执行SQL Server存储过程

CREATE PROCEDURE [dbo].[GetItemListProcedure] 
    (@CategoriesIdString VARCHAR(1000)) 
AS 
    SET NOCOUNT ON; 

    DECLARE @SQLQuery NVARCHAR(MAX); 

    SET @SQLQuery = N'SELECT Item.Id, Item.ModelId, Item.ItemCode, Item.CategoryId, 
      (SELECT TOP (1) Category.CategoryName FROM Category WHERE Category.Id = Item.CategoryId) AS CategoryName 
         FROM Item 
         LEFT OUTER JOIN Category ON Item.CategoryId = Category.Id'; 

    IF (@CategoriesIdString IS NOT NULL) 
    BEGIN 
     SET @SQLQuery += N' WHERE CHARINDEX('','' + CONVERT(VARCHAR(12), Item.CategoryId) + '','', '' + @CategoriesIdString + '') > 0'; 
    END 

    DECLARE @ParmDefinition NVARCHAR(600); 
    SET @ParmDefinition = N'@categoriesId VARCHAR(1000); 

    PRINT @SQLQuery; 

    EXEC sp_executesql @SQLQuery, @ParmDefinition, @categoriesId = @CategoriesIdString 

    RETURN 0 

这过程中,由于某种原因,不返回任何记录。

但是,如果我运行下面的查询:

DECLARE @CategoriesIdString VARCHAR(1000) 
SET @CategoriesIdString = ',2,3,'; 

SELECT 
    Item.Id, Item.ModelId, Item.ItemCode, Item.CategoryId, 
    (SELECT TOP (1) Category.CategoryName 
    FROM Category 
    WHERE Category.Id = Item.CategoryId) AS CategoryName 
FROM 
    Item 
LEFT OUTER JOIN    
    Category ON Item.CategoryId = Category.Id 
WHERE 
    CHARINDEX(',' + CONVERT(VARCHAR(12), Item.CategoryId) + ',', @CategoriesIdString) > 0 

然后我得到了一些行。

我在存储过程中做了什么错误?

我也试过这样:

SET @SQLQuery += N' WHERE CHARINDEX('','' + CONVERT(VARCHAR(12), Item.CategoryId) + '','', @CategoriesIdString) > 0'; 

但得到一个错误:

{"Must declare the scalar variable \"@CategoriesIdString\"."}

+2

做一个“print @sqlquery”来查看执行前查询的内容。然后,您可以将其复制并粘贴到management studio中,然后直接执行以查看语法错误的位置。 – ganders 2015-02-17 20:21:41

回答

2

你不需要在这种情况下使用动态T-SQL声明。其中一个方法是使用这样的:

DECLARE @TempXML XML = CONVERT(XML, '<t>' + REPLACE(@CategoriesIdString, ',', '</t><t>') + '</t>') 

;WITH DataSource ([CategoryId]) AS 
(
    SELECT T.c.value('.', 'VARCHAR(100)') 
    FROM @TempXML.nodes('/t') AS T(c) 
    WHERE LEN(T.c.value('.', 'VARCHAR(100)')) > 0 
) 
SELECT Item.Id 
     ,Item.ModelId 
     ,Item.ItemCode 
     ,Item.CategoryId 
     ,(SELECT TOP (1) Category.CategoryName FROM Category WHERE Category.Id = Item.CategoryId) AS CategoryName 
FROM Item 
LEFT OUTER JOIN Category 
    ON Item.CategoryId = Category.Id 
LEFT JOIN DataSource 
    ON Item.CategoryId = DataSource.CategoryId 
WHERE DataSource.CategoryId IS NOT NULL 
    OR @CategoriesIdString IS NULL 

的想法是通过@CategoriesIdString参数进行过滤,如果它是NOT NULL使用LEFT JOIN