我正在尝试从我使用变量生成的字符串中执行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执行此查询?
答案 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 = 1
和AND ....
之间放置至少一个空格 {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 ';