繁体   English   中英

SQL Server:动态SQL中声明变量的问题

[英]SQL Server: issue with declaring variable in dynamic SQL

我创建了一个动态存储过程,其开始如下。

我可以保存它而不会出错,但是在执行它时似乎无法识别@temp变量,因为它会引发以下错误:“必须声明表变量“ @temp”。“

这可能是因为错误的引号/转义,如果是的话,我该如何更改它才能使其正确(我对SQL还是很陌生,所以某些引号可能是错误的或丢失的)?

我的SP(第一部分):

    @selection nvarchar(100)
AS
BEGIN

    SET NOCOUNT ON;

    BEGIN

    DECLARE @temp AS TABLE
    (
        ranking int,
        item nvarchar(100),
        groupCount int,
        groupName nvarchar(100)
    )

    DECLARE @sql nvarchar(max)

    SET @sql = '
    INSERT INTO @temp
    (       
                ranking,
                item,
                groupCount,
                groupName
    )
    SELECT      RANK() OVER(ORDER BY COUNT(*) desc, policy) [Rank],
                ' + @selection + ', 
                COUNT(*) AS groupCount,
                ''currentMonth'' AS groupName
    FROM        Log_PE 
    WHERE       CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6), GETDATE(), 112) + ''01'', 112)
    GROUP BY    ' + @selection + '
    ORDER BY    groupCount desc, ' + @selection + '
        ...

迈克,在此先感谢您的帮助。

正如我在评论部分中已经提到的那样,Dynamic Sql有自己的作用域,在该作用域之外声明的任何变量对于动态sql都是不可见的,您必须在动态sql内部声明该变量。 如下所示。

SET @sql = N' DECLARE @temp AS TABLE
             (
              ranking int,
              item nvarchar(100),
              groupCount int,
              groupName nvarchar(100)
              )

INSERT INTO @temp
(       
            ranking,
            item,
            groupCount,
            groupName
)
SELECT      RANK() OVER(ORDER BY COUNT(*) desc, policy) [Rank],
            ' + @selection + ', 
            COUNT(*) AS groupCount,
            ''currentMonth'' AS groupName
FROM        Log_PE 
WHERE       CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6), GETDATE(), 112) + ''01'', 112)
GROUP BY    ' + @selection + '
ORDER BY    groupCount desc, ' + @selection + '

希望你做得很好,好吧,我认为您可能会重新考虑使用变量表,因为当执行EXEC(@sql)时,SQL无法理解@temp变量的含义,因此我建议使用临时表而不是变量表,这是新代码:

BEGIN

    SET NOCOUNT ON;

    BEGIN

if object_id('temp') is not null
  drop table temp

create table temp
    (
        ranking int,
        item nvarchar(100),
        groupCount int,
        groupName nvarchar(100)
    )

    DECLARE @sql nvarchar(max)

    SET @sql = '
    INSERT INTO temp
    (       
                ranking,
                item,
                groupCount,
                groupName
    )
    SELECT      RANK() OVER(ORDER BY COUNT(*) desc, policy) [Rank],
                ' + @selection + ', 
                COUNT(*) AS groupCount,
                ''currentMonth'' AS groupName
    FROM        Log_PE 
    WHERE       CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6),     GETDATE(), 112) + ''01'', 112)
    GROUP BY    ' + @selection + '
    ORDER BY    groupCount desc, ' + @selection + '

...

if object_id('temp') is not null
  drop table temp

希望thiw能帮到你

当您执行EXEC或sp_executesql时,将为进程空间获得另一个名称空间(作用域)。 从表变量更改为本地临时表#temp。

以下是使用sp_who2的快速示例,说明了本地临时表的使用。

诚挚

Ĵ

代码段

-- CREATE LOCAL TABLE
CREATE TABLE #WHO2
(
  [spid] int not null
, [status] varchar (255) not null
, [login] varchar (255) not null
, [host_name] varchar (255) not null
, [blk_by] varchar(10) not null
, [db_name] varchar (255) null
, [command] varchar (255) not null
, [cpu_time] int not null
, [disk_io] int not null
, [last_batch] varchar (255) not null
, [program_name] varchar (255) null
, [spid2] int not null
, [request_id] int not null
); ;

-- DYNAMIC SQL      
DECLARE @VAR_TSQL VARCHAR(MAX);      
SET @VAR_TSQL = 'INSERT #WHO2 EXEC sp_who2';
EXECUTE (@VAR_TSQL);
GO

-- TABLE PERSISTS UNTIL SPID (CONNECTION) IS BROKEN
SELECT * FROM #WHO2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM