2

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

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

从 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

4 回答 4

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

这不是问题,正如 Martin Smith 发现的那样......

更新:好的-毕竟似乎不需要空间.....

但是:尝试使用

EXEC (@SQL)

我相信您在执行时需要将 SQL 语句放入括号中。

于 2012-08-29T08:53:34.917 回答
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
于 2012-08-29T08:55:07.480 回答
1

编辑:

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

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

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

我会说,将这些行更改为:

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

对于这样的事情(顺便说一句,这个有点难看):

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

或者

看一下sq_executesql,您可以使用它为参数定义参数和值。如果您使用大量即席查询检查 SQL Profiler,引擎也会执行相同的操作。只需将输入作为带有 sp_executesql 和参数的动态 sql 运行。

于 2012-08-29T09:08:20.610 回答
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 '; 
于 2012-08-29T08:54:49.653 回答