简体   繁体   English

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

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

I created a dynamic stored procedure that starts as follows. 我创建了一个动态存储过程,其开始如下。

I can save this without errors but when I execute it it seems it doesn't recognise the @temp variable as it throws the following error: "Must declare the table variable "@temp"." 我可以保存它而不会出错,但是在执行它时似乎无法识别@temp变量,因为它会引发以下错误:“必须声明表变量“ @temp”。“

Could this be because of wrong quotes / escaping and if, how do I have to change this in order to have it right (I am pretty new to SQL so some of the quotes could be wrong or missing) ? 这可能是因为错误的引号/转义,如果是的话,我该如何更改它才能使其正确(我对SQL还是很陌生,所以某些引号可能是错误的或丢失的)?

My SP (first part): 我的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 + '
        ...

Many thanks in advance for any help with this, Mike. 迈克,在此先感谢您的帮助。

As I have already mentioned in comments section, Dynamic Sql has its own scope, any variable declared outside of that scope arent visible to dynamic sql, Your have to declare the variable inside your dynamic sql. 正如我在评论部分中已经提到的那样,Dynamic Sql有自己的作用域,在该作用域之外声明的任何变量对于动态sql都是不可见的,您必须在动态sql内部声明该变量。 Something like as follows.... 如下所示。

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 + '

Hope you are doing fine, well i think you may reconsider using a variable table because SQL won't understand what the @temp variable means when you will execute the EXEC(@sql), i recommand using a temp table instead of a variable table, here's the new code : 希望你做得很好,好吧,我认为您可能会重新考虑使用变量表,因为当执行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

I hope thiw will help you 希望thiw能帮到你

When you EXEC or sp_executesql, you get another name space (scope) for the process space. 当您执行EXEC或sp_executesql时,将为进程空间获得另一个名称空间(作用域)。 Change from a table variable to a local temp table, #temp. 从表变量更改为本地临时表#temp。

Below is a quick example using sp_who2 illustrating use of a local temp table. 以下是使用sp_who2的快速示例,说明了本地临时表的使用。

Sincerely 诚挚

J Ĵ

Code Snippet 代码段

-- 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