Sql server TSQL中exec的微妙之处

Sql server TSQL中exec的微妙之处,sql-server,tsql,stored-procedures,exec,Sql Server,Tsql,Stored Procedures,Exec,这个存储过程 CREATE PROC GetPage(@blockNumber int, @blockSize int = 40, @query varchar(1000)) AS DECLARE @a int = @blockNumber * @blockSize; DECLARE @b int = @a + @blockSize - 1; DECLARE @fromPos int = PATINDEX('% FROM %', @query); DECLARE @fr

这个存储过程

CREATE PROC GetPage(@blockNumber int, @blockSize int = 40, @query varchar(1000)) 
AS
   DECLARE @a int = @blockNumber * @blockSize;
   DECLARE @b int = @a + @blockSize - 1;
   DECLARE @fromPos int = PATINDEX('% FROM %', @query);
   DECLARE @from varchar(1000) = SUBSTRING(@query, @fromPos, 1000);
   DECLARE @select varchar(1000) = SUBSTRING(@query, 1, @fromPos);
   DECLARE @SQL varchar(1000) = 
      'select *, ROW_NUMBER() over (order by ONE) R INTO #FOO FROM ('
      +@SELECT+',1 ONE'+@from+') T';

   EXEC @SQL;

   SELECT * FROM FOO WHERE RN BETWEEN @a AND @b;

   DECLARE @C INT = (SELECT COUNT(*) FROM #FOO);
   DROP TABLE #FOO
   RETURN @C;
传递时,SELECT*FROM资产生成此SQL

select *, ROW_NUMBER() over (order by ONE) R INTO #FOO 
FROM (select * ,1 ONE from asset) T
当我从SQL Server Management Studio执行此操作时,如下所示:

exec('select *, ROW_NUMBER() over (order by ONE) R INTO #FOO FROM (select * ,1 ONE from asset) T')
它按预期创建表FOO

但是,在执行存储过程时:

exec getpage 5,10,'select * from asset'
我得到这个错误

Msg 2812,16级,状态62,程序GetPage,第12行 找不到存储过程“select*,从select*到FOO的顺序上的行号为R,从资产T到FOO的顺序上的行号为1”。 Msg 208,16级,状态1,程序GetPage,第14行 无效的对象名称“FOO”


我认为第二个信息仅仅是第一个错误的结果。有人知道为什么exec语句在存储过程中的行为不同吗?

在exec语句中使用括号

EXEC (@SQL); 
如果没有括号,您将使用以下内容:

Execute a stored procedure or function [ { EXEC | EXECUTE } ] { [ @return_status = ] { module_name [ ;number ] | @module_name_var } [ [ @parameter = ] { value | @variable [ OUTPUT ] | [ DEFAULT ] } ] [ ,...n ] [ WITH [ ,...n ] ] } [;] 在需要括号的地方,您需要这个

Execute a character string { EXEC | EXECUTE } ( { @string_variable | [ N ]'tsql_string' } [ + ...n ] ) [ AS { LOGIN | USER } = ' name ' ] [;]
碰巧我自己解决了这个问题,但这让我确信你给出了一个正确的答案。荣誉属于你。谢谢你的帮助。你可能认为他们会从参数类型推断,就像.NET方法一样…@mikael eriksson-是否可以使用括号,但将过程的输出分配给一个类似@a=exec@sql的变量