Sql 条件下的不同结果

Sql 条件下的不同结果,sql,sql-server,Sql,Sql Server,在陈述中不太明白。第一种变体很好用: select manufacturers.id from manufacturers where manufacturers.id in (select manufacturerId from pcs group by manufacturerId having count(manufacturerId) > 1) 但当我将子查询作为一个过

在陈述中不太明白。第一种变体很好用:

select manufacturers.id
from manufacturers
where manufacturers.id in (select manufacturerId 
                           from pcs group by manufacturerId 
                           having count(manufacturerId) > 1)
但当我将子查询作为一个过程时:

CREATE PROCEDURE [dbo].Get_manufacturers @productType varchar(50)  
as 
begin   
declare @query varchar(500)   
set @query='select manufacturerId from ' +  QuoteName(@productType) + ' 
               group by manufacturerId having count(manufacturerId) > 1'   
declare @t table (manufacturerId int)
insert into @t exec(@query)
select manufacturerId from @t;
end


select manufacturers.id
from manufacturers
where manufacturers.id in (Get_manufacturers 'pcs')
我得到一个错误:Msg 102,15级,状态1,第4行 “pcs”附近的语法不正确


让制造商的PC正常工作。我错在哪里?

正如@Gordon Linoff所说,过程不会返回表。 但是,如果要存储存储过程的输出数据,则需要将其放入表e中。g、 :

DECLARE @manufactures TABLE (Id int)
INSERT INTO @manufactures
exec Get_manufacturers 'pcs'

select manufacturers.id
from manufacturers
where manufacturers.id IN (SELECT Id FROM @manufactures)

您可以使用临时表代替表变量。

正如@Gordon Linoff所说,过程不会返回表。 但是,如果要存储存储过程的输出数据,则需要将其放入表e中。g、 :

DECLARE @manufactures TABLE (Id int)
INSERT INTO @manufactures
exec Get_manufacturers 'pcs'

select manufacturers.id
from manufacturers
where manufacturers.id IN (SELECT Id FROM @manufactures)
可以使用临时表而不是表变量

在陈述中不太明白


Get_制造商的PC正常工作-它返回一个表

您误解了
存储过程
处于
状态

            select m.id
            from manufacturers M
            where m.id IN (select t.manufacturerId From #tmp_manufacturers T)
发件人:

存储过程返回的不是子查询,也不是表达式。 这里有一个链接来了解子查询是什么

子查询是嵌套在另一个T-SQL中的SELECT语句 声明

所以存储过程不是子查询,它不是SELECT语句。 但即使您说存储过程返回一个表,这也是错误的:您可以将一个表联接到另一个表,但不能联接存储过程的结果。 即使您将过程返回的结果集作为“表”进行“查看”,它也不是表

在陈述中不太明白


Get_制造商的PC正常工作-它返回一个表

您误解了
存储过程
处于
状态

            select m.id
            from manufacturers M
            where m.id IN (select t.manufacturerId From #tmp_manufacturers T)
发件人:

存储过程返回的不是子查询,也不是表达式。 这里有一个链接来了解子查询是什么

子查询是嵌套在另一个T-SQL中的SELECT语句 声明

所以存储过程不是子查询,它不是SELECT语句。 但即使您说存储过程返回一个表,这也是错误的:您可以将一个表联接到另一个表,但不能联接存储过程的结果。
即使您将过程返回的结果集作为“表”来“查看”,它也不是表。

根据Rokuto和Gordon Linoff的建议,通过省略表声明来更改过程:

            ALTER PROCEDURE [dbo].Get_manufacturers @productType nvarchar(50)  
            as 
            begin   
            declare @query nvarchar(500)   
            set @query= N'select manufacturerId from ' +  QuoteName(@productType) + ' 
                           group by manufacturerId having count(manufacturerId) > 1'   
            ---declare @t table (manufacturerId int)
            ---insert into @t exec(@query)
            ---select manufacturerId from @t;
            exec(@query)
            end
            GO
然后,使用临时表填写存储过程的结果

            IF(OBJECT_ID('tempdb..#tmp_manufacturers') IS NOT NULL)
            BEGIN
                DROP TABLE #tmp_manufacturers
            END

            CREATE TABLE #tmp_manufacturers
            (
               manufacturerId int
            )

            INSERT INTO #tmp_manufacturers (manufacturerId)
            EXEC dbo.Get_manufacturers 'pcs'
最后,将其添加到您的IN状态中

            select m.id
            from manufacturers M
            where m.id IN (select t.manufacturerId From #tmp_manufacturers T)

根据Rokuto和Gordon Linoff的建议,通过省略表声明来修改过程:

            ALTER PROCEDURE [dbo].Get_manufacturers @productType nvarchar(50)  
            as 
            begin   
            declare @query nvarchar(500)   
            set @query= N'select manufacturerId from ' +  QuoteName(@productType) + ' 
                           group by manufacturerId having count(manufacturerId) > 1'   
            ---declare @t table (manufacturerId int)
            ---insert into @t exec(@query)
            ---select manufacturerId from @t;
            exec(@query)
            end
            GO
然后,使用临时表填写存储过程的结果

            IF(OBJECT_ID('tempdb..#tmp_manufacturers') IS NOT NULL)
            BEGIN
                DROP TABLE #tmp_manufacturers
            END

            CREATE TABLE #tmp_manufacturers
            (
               manufacturerId int
            )

            INSERT INTO #tmp_manufacturers (manufacturerId)
            EXEC dbo.Get_manufacturers 'pcs'
最后,将其添加到您的IN状态中

            select m.id
            from manufacturers M
            where m.id IN (select t.manufacturerId From #tmp_manufacturers T)


这不是存储过程的工作方式,因此您编写的代码毫无意义。您可以考虑创建一个存储函数。但是,在SQL Server中,这些不能使用动态SQL。换句话说,如果需要存储过程,则需要将结果插入表中,然后在查询中使用该表。@Gordon Linoff。好啊如何解决这个问题?让制造商的PC正常工作-它返回一个表。我怀疑我不理解这种情况。不,过程不返回表,在过程中选择返回结果集。任务需要表值函数是的,SSMS是一个客户端,它以您指示服务器交互的方式与服务器交互,并显示它的设计意图。存储过程不是这样工作的,因此您编写代码毫无意义。您可以考虑创建一个存储函数。但是,在SQL Server中,这些不能使用动态SQL。换句话说,如果需要存储过程,则需要将结果插入表中,然后在查询中使用该表。@Gordon Linoff。好啊如何解决这个问题?让制造商的PC正常工作-它返回一个表。我怀疑我不理解这种情况。不,过程不返回表,在过程中选择返回结果集。任务需要表值函数是的,SSMS是一个客户端,它与服务器交互的方式与您指示的交互方式相同,并显示它的设计目的。错误:过程Get_manufacturers,第7行INSERT EXEC语句无法执行nested@IgorSeliverstov正如您所看到的,您的过程是无效的。我不知道您为什么要这样做,但请检查是否将
declare@t table(manufacturerId int)insert替换为@t exec(@query)并从@t中选择manufacturerIdexec(@query)
进行代码>将有帮助(无需在过程中向表中插入数据)。错误:过程获取,第7行不能插入INSERT exec语句nested@IgorSeliverstov正如您所看到的,您的过程是无效的。我不知道您为什么要这样做,但请检查是否将
declare@t table(manufacturerId int)insert替换为@t exec(@query)并从@t中选择manufacturerIdexec(@query)
进行代码>将有所帮助(无需在过程中向表中插入数据)。怎么办?如果您只想在查询中使用与原始post不同的表名,只需使用动态SQL即可。您可以将其封装在存储过程中(整个过程,而不仅仅是子查询),或者您根本不需要动态代码,如果您可以精确地确定您试图实现的目标,那么还可以有其他解决方案。怎么办?如果您只想在查询中使用与原始post不同的表名,只需使用动态SQL即可。您可以将其封装在存储过程中(整个过程,而不仅仅是一个子查询),或者您根本不需要动态代码,如果您可以精确地确定您试图实现的目标,那么可能还有其他解决方案