【问题标题】:How do I drop table variables in SQL-Server? Should I even do this?如何在 SQL-Server 中删除表变量?我应该这样做吗?
【发布时间】:2011-08-04 22:36:00
【问题描述】:

我在脚本中有一个表变量(不是存储过程)。两个问题:

  1. 如何删除表变量? Drop Table @varName 给出“Incorrect snytax”错误。
  2. 我应该一直这样做吗?我听说这是一个很好的做法。像这样的小脚本真的有必要吗?

这是我的代码:

Declare @projectList table(
    name varchar(40) NOT NULL);

Insert Into @projectList
Values ('BCR-00021')

Select *
From @projectList

Drop Table @projectList -- does not work

【问题讨论】:

  • 您不能自己删除它们,因此您的问题的第二部分不适用。

标签: sql sql-server table-variable


【解决方案1】:

表变量会自动本地化并自动删除——您不必担心。

【讨论】:

  • +1 - 即使你想不能删除它们 - 只要会话打开,它们就会一直存在,就像任何其他变量一样。它们也不受交易影响。
  • @JNKs 指出它们不受事务影响很重要,您可以使用表变量来保存数据并在错误导致回滚后写入日志表。
  • 不,不一样。临时表参与事务。
  • 它们也不等同于 CTE。
  • 你不能删除它们,但你可以删除它们 'delete @projectList' ;)
【解决方案2】:

表变量就像 int 或 varchar 变量。

您无需丢弃它们。它们与 int 或 varchar 变量具有相同的 scope 规则

变量的范围是可以引用该变量的 Transact-SQL 语句的范围。变量的范围从声明它的那一刻开始一直持续到声明它的批处理或存储过程结束。

【讨论】:

  • 你知道表变量创建的 tempdb 对象在超出范围时是否会被清理吗?还是服务器要等到会话关闭后再清理它们?
【解决方案3】:

就像 TempTables 一样,在 TempDB 中也创建了一个本地表变量。表变量的作用域是声明它的批处理、存储过程和语句块。它们可以作为过程之间的参数传递。当您关闭创建它们的会话时,它们会自动删除。

【讨论】:

  • #temp 表与@table 变量不同,它不会在补丁或作用域结束后自动删除,只有在存储过程中创建并且存储过程完成时才会自动删除执行
【解决方案4】:

但是你们都忘了提到,如果在循环中使用变量表,则需要在循环中再次加载数据之前清空(删除@table)。

【讨论】:

    【解决方案5】:

    如果其他人遇到这个...并且您确实需要像在循环中那样删除它,您可以从表变量中删除所有内容:

    DELETE FROM @tableVariableName
    

    【讨论】:

    • 但是id会递增,循环声明时不会再设置为1
    • 这将删除 Table 变量中的所有行,以便循环中的下一次迭代为空。这符合我的要求。谢谢。
    【解决方案6】:

    这里有一个解决方案

    Declare @tablename varchar(20)
    DECLARE @SQL NVARCHAR(MAX)
    
    SET @tablename = '_RJ_TEMPOV4'
    SET @SQL = 'DROP TABLE dbo.' + QUOTENAME(@tablename) + '';
    
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(@tablename) AND type in (N'U'))
        EXEC sp_executesql @SQL;
    

    在 SQL Server 2014 上运行良好 克里斯托夫

    【讨论】:

      【解决方案7】:

      临时表变量被保存到 temp.db 并且范围仅限于当前执行。因此,与删除临时表(例如删除表#tempTable)不同,我们不必显式删除临时表变量@tempTableVariable。它由 sql server 自动处理。

      drop table @tempTableVariable -- Invalid
      

      【讨论】:

        【解决方案8】:

        确实,您不需要删除@local_variable

        但是如果你使用#local_table,它可以做到,例如能够多次重新执行查询很方便。

        SELECT *
        INTO #recent_records
        FROM dbo.my_table t
        WHERE t.CreatedOn > '2021-01-01'
        ;
        
        SELECT *
        FROM #recent_records
        ;
        
        /*
          can DROP here, otherwise will fail with the following error
          on re-execution in the same window (I use SSMS DB client):
        
          Msg 2714, Level ..., State ..., Line ...
          There is already an object named '#recent_records' in the database.
        */
        DROP TABLE #recent_records
        ;
        

        您还可以将 SELECT 语句放在 TRANSACTION 中,以便能够在没有显式 DROP 的情况下重新执行:

        BEGIN TRANSACTION
        
          SELECT *
          INTO #recent_records
          FROM dbo.my_table t
          WHERE t.CreatedOn > '2021-01-01'
          ;
        
          SELECT *
          FROM #recent_records
          ;
        
        ROLLBACK
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-01
          • 2010-09-21
          • 1970-01-01
          • 2018-08-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多