【问题标题】:Subtleties of exec in TSQLSQL中exec的微妙之处
【发布时间】:2013-03-27 07:22:52
【问题描述】:

这个存储过程

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'

我收到此错误

消息 2812,级别 16,状态 62,过程 GetPage,第 12 行
找不到存储过程 'select *, ROW_NUMBER() over (order by ONE) R INTO FOO FROM (select * ,1 ONE from assets) T'。
消息 208,级别 16,状态 1,过程 GetPage,第 14 行
无效的对象名称“#FOO”。

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

【问题讨论】:

    标签: sql-server tsql stored-procedures exec


    【解决方案1】:

    在你的 exec 中使用括号

    EXEC (@SQL); 
    

    EXECUTE (Transact-SQL)

    没有括号,你使用的是这个:

    执行存储过程或函数 [ { 执行 |执行 } ] { [@return_status =] { 模块名称 [ ; 编号 ] | @module_name_var } [ [ @parameter = ] { 值 | @变量[输出] | [ 默认 ] } ] [ ,...n ] [ 与 [ ,...n ] ] } [;]

    在需要括号的地方你想要这个。

    执行一个字符串 { 执行 |执行 } ( { @string_variable | [ N ]'tsql_string' } [ + ...n ] ) [作为{登录|用户} ='名称'] [;]

    【讨论】:

    • 碰巧我自己解决了这个问题,但这只是让我确定你提供了一个正确的答案。荣誉是你的。谢谢你的帮忙。你会认为他们会从参数类型推断出来,就像 .NET 方法一样......
    • @mikael-eriksson - 无论如何要使用括号,但将 proc 的输出分配给类似 @a = exec (@sql) 的变量
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 2022-01-09
    • 2013-08-12
    相关资源
    最近更新 更多