SQL中exec的细微之处

时间:2013-03-27 07:22:53

标签: 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 @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 ASSET

生成此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,Level 16,State 62,Procedure GetPage,Line 12
  找不到存储过程'select *,ROW_NUMBER()over(order by ONE)R INTO FOO FROM(select *,1 ONE from asset)T'。
  Msg 208,Level 16,State 1,Procedure GetPage,Line 14
  无效的对象名称'#FOO'。

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

1 个答案:

答案 0 :(得分:6)

在你的exec中使用括号

EXEC (@SQL); 

EXECUTE (Transact-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 ' ]
[;]