存储过程导致语法错误

时间:2013-01-30 06:25:03

标签: sql sql-server-2005 stored-procedures

我写了这个存储过程:

CREATE PROCEDURE [dbo].[spGetCuisines]
    @RestaurantID INT ,
    @CuisineID NVARCHAR(200)
AS 
BEGIN
    SET NOCOUNT ON;
    DECLARE @sql NVARCHAR(MAX)

    SET @sql = 'SELECT  CuisineID, CuisineName
    FROM    dbo.Cuisine1
    WHERE   CuisineID IN (
            SELECT  dbo.Dishes1.CuisineID
            FROM    dbo.Dishes1
            WHERE   DishID IN ( SELECT  DishID
                                FROM    dbo.RestaurantDish
                                WHERE   RestaurantID = '
        + CAST(@RestaurantID AS NVARCHAR(MAX)) + ' ) )'                                    
    IF @CuisineID <> ''
        BEGIN
            SET @sql += 'AND Cuisine1.CuisineID IN('
                + CAST(@CuisineID AS NVARCHAR(MAX)) +')'
        END
    EXECUTE sp_executesql @sql; 
END

我正在使用3个表,其列列出如下:

Dishes1

   DishID
   DishName
   CuisineID
   Price 

Cuisine1

   CuisineID
   CuisineName
   Type
   DateCreated
   DateModified
   DateDeleted

RestaurantDish

RestaurantDishID
RestaurantID
DishID

但是我的存储过程在这一行给出了语法错误:

    SET @sql += 'AND Cuisine1.CuisineID IN('+ CAST(@CuisineID AS NVARCHAR(MAX)) +')'

它说:

  

“+”

附近的语法不正确

有人可以指导我吗? SQL Server版本是否与此有关?

3 个答案:

答案 0 :(得分:1)

您使用的语法仅在SQL Server 2008及更高版本上有效。在SQL Server 2005上,您必须更改:

SET @sql += ...

要:

SET @sql = @sql + ...

答案 1 :(得分:1)

这里绝对不需要使用动态SQL - 所以不要!另外:更喜欢 JOIN 而不是子查询 - 加入通常更快,而且坦率地说 - 代码更容易来阅读!

只需使用:

CREATE PROCEDURE [dbo].[spGetCuisines]
    @RestaurantID INT ,
    @CuisineID NVARCHAR(200)
AS 
BEGIN
    SET NOCOUNT ON;
    DECLARE @sql NVARCHAR(MAX)

    SELECT  
        c.CuisineID, c.CuisineName
    FROM    
        dbo.Cuisine1 c
    INNER JOIN
        dbo.Dishes1 d ON d.CuisineID = c.CuisineID
    INNER JOIN
        dbo.Restaurant1 r ON r.DishID = d.DishID
    WHERE  
        r.RestaurantID = @RestaurantID
        AND (@CuisineID = '' OR c.CuisineID = @CuisineID)
END

Aaron Bertrand当然是绝对正确的 - 只有当你传入一个CuisineID作为字符串时,这才有效。

如果您的@CuisineID参数包含多个值,那么您需要这样的内容:

    WHERE  
        r.RestaurantID = @RestaurantID
        AND (@CuisineID = '' OR c.CuisineID IN dbo.Split(@CuisineID))

使用函数Split,您可以将逗号分隔的ID列表拆分为表变量,并使用IN运算符匹配可能值列表。

答案 2 :(得分:0)

你可能传入逗号分隔的字符串吗? 如果是这样,有更好的方法来处理这个问题,请参见此处:

http://codebetter.com/raymondlewallen/2005/10/26/quick-t-sql-to-parse-a-delimited-string/