2012-08-29 168 views
2

我想从一个字符串执行一个SQL查询,我用变量生成。该SP产生一个选择查询,当我手动执行这个查询它的工作原理,但是当它在SP有像SQL查询字符串

消息911,级别16,状态4,过程sp_Products_Select错误,第26行
数据库“ SELECT *(选择部分与部分,其中SectionID = 产品不存在。请确保名称输入正确 。

从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正确执行这个查询?

+0

只需照顾你的'AND CategoryID = @CategoryID'部分。 –

回答

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 ....

这不是问题,因为马丁·史密斯发现....

更新:好 - 这样的空间似乎并不终究需要.....

:尝试使用

EXEC (@SQL) 

我相信你需要在执行时,它把你的SQL语句转换成支架。

+3

'SELECT 1 WHERE 1 = 1AND 2 = 2'实际上解析得很好。 'EXEC(...)'后面的问题是括号括起来' –

+0

谢谢,我试过但仍然有同样的错误 –

+0

@MartinSmith:嗯....你说得对....我可以**发誓* *在我的日子里,我的问题与基本相同的结构('WHERE 1 = 1AND ....')有关:-) –

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 '; 
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 
1

编辑:

所以EXEC(..)不会解决你所有的问题!

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

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

我会说,改变像那些行:

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

为了这样的事情(这个人是有点难看BTW):

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

OR

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