SQL查询字符串

时间:2012-08-29 08:49:20

标签: sql sql-server

我正在尝试从我使用变量生成的字符串中执行SQL查询。此SP生成一个Select查询,当我手动执行此查询时,它可以工作,但是当它在SP中时,会出现类似

的错误
  

消息911,级别16,状态4,过程sp_Products_Select,第26行
  数据库'SELECT *,(从SectionID =的Section中选择Section   产品不存在。确保输入名称   正确。

从SP生成的查询

SELECT 
   *, 
   (Select Section 
    From Sections 
    Where SectionID = dbo.Products.SectionID) as Section,
   (Select Category 
    From Categories 
    Where CategoryID = Products.CategoryID) as Category 
FROM 
    Products 
WHERE 
    1 = 1AND (Status = 1 OR Status = 0)

我的SP是,

ALTER PROC [dbo].[sp_Products_Select]
    @ProductID int,
    @Status int,
    @CategoryID int,
    @SectionID int
AS

DECLARE @SQL varchar(500)
SET @SQL ='SELECT *,(Select Section From Sections Where SectionID = Products.SectionID) as Section,(Select Category From Categories Where CategoryID = Products.CategoryID) as Category FROM Products WHERE 1 = 1';
IF @ProductID <> '0' BEGIN
    SET @SQL += 'AND ProductID = @ProductID';
END
IF  @Status <> 0 BEGIN 
    SET @SQL += 'AND Status = @Status';
END ELSE BEGIN
    SET @SQL += 'AND (Status = 1 OR Status = 0)';
END
IF @CategoryID <> '0' BEGIN
    SET @SQL += 'AND CategoryID = @CategoryID';
END
IF @SectionID <> '0' BEGIN
    SET @SQL += 'AND SectionID = @SectionID';
END

EXEC @SQL

如何正确地从SP执行此查询?

4 个答案:

答案 0 :(得分:3)

您在WHERE子句中缺少空格:

WHERE 
    1 = 1AND (Status = 1 OR Status = 0)

必须是:

WHERE 
    1 = 1 AND (Status = 1 OR Status = 0)
         *
         * space here is absolutely essential!

因此,您需要更改构建T-SQL语句的存储过程代码,以便在1 = 1AND ....之间放置至少一个空格 {1}}

这不是问题,正如马丁史密斯发现的......

更新:确定 - 所以似乎根本不需要空间......

但是:尝试使用

EXEC (@SQL)

我认为你需要在执行时将SQL语句放入括号中。

答案 1 :(得分:1)

尝试简化您的查询,

SELECT  a.*, b.Section, c.Section
FROM    Products a
            INNER JOIN Sections b
                ON a.SectionID = a.SectionID
            INNER JOIN Categories c
                ON a.SectionID = c.Category

并且在SET @SQL语法中,您需要add extra space与他们合作。

SET @SQL += ' AND ProductID = @ProductID';
             ^ here

答案 2 :(得分:1)

<强>编辑:

因此EXEC(..)无法解决您的所有问题!

我认为你甚至需要声明@ProductID和@CategoryID以及动态查询的其他参数,如果你想在里面运行它们。

EXEC启动另一个范围,就像其他StoredProcedure调用一样。在另一个范围内,您的@variables将不可用。您可以在临时表上进行引用,但不能在内存表或变量上进行引用。

我会说,改变这些行:

SET @SQL += 'AND ProductID = @ProductID'

对于这样的事情(这个有点难看):

SET @SQL += 'AND ProductID = ' + CAST(@ProductID as varchar(20))

查看sq_executesql,您可以使用此参数定义参数和值。如果您使用大量临时查询检查SQL事件探查器,则引擎也会执行相同的操作。只需使用sp_executesql和参数将输入作为动态sql运行。

答案 3 :(得分:0)

1 = 1后需要一个空格

'SELECT *,(Select Section From Sections Where SectionID = Products.SectionID) as Section,(Select Category From Categories Where CategoryID = Products.CategoryID) as Category FROM Products WHERE 1 = 1 ';