【问题标题】:In SQL Server 2008 ,is it possible to disable auto drop of global temp table在 SQL Server 2008 中,是否可以禁用全局临时表的自动删除
【发布时间】:2010-05-13 11:14:36
【问题描述】:

问题 1:我在 SQL Server 2008 中使用全局临时表。但是一旦我的连接关闭,这个临时表就会被删除。有什么办法可以禁用自动删除

问题 2:如果两个连接正在访问同一个全局临时表,而另一个连接正在访问 尝试删除该全局临时表,SQL Server 是否正确处理此同步?

【问题讨论】:

    标签: sql-server temp-tables


    【解决方案1】:

    您可以在存储过程中创建全局临时表并使用启动选项对其进行标记。

    SQL Server 为在启动过程中创建的所有全局临时表维护一个大于零的引用计数。

    一些示例代码

    CREATE PROC dbo.CreateGlobalTempTables
    AS
    CREATE TABLE ##my_temp_table
    (
       fld1 INT NOT NULL PRIMARY KEY,
       fld2 INT NULL
    );
    GO
    
    EXEC dbo.sp_procoption 'dbo.CreateGlobalTempTables', 'startup', 'true';
    

    全局临时表将在启动时自动创建并持续存在,直到有人明确删除它。

    【讨论】:

      【解决方案2】:

      如果您需要一个表在创建它的连接终止后仍然存在,您应该只创建一个常规表而不是临时表。它仍然可以直接在 tempdb 中创建(让您获得简单的日志记录和服务器重启时自动销毁的好处),但它的名称不会以 ## 为前缀。

      DROP TABLE 是一个事务性语句,如果有任何活动连接使用该表(带锁),它将阻塞。

      【讨论】:

        【解决方案3】:

        当创建##GlobalTempTable 的连接结束时,该表将被删除,除非它有锁。

        您可以从其他进程运行类似的操作来防止表被删除:

        BEGIN TRANSACTION
            SELECT TOP 1 FROM ##GlobalTempTable WITH (UPDLOCK, HOLDLOCK)
        
        
        ...COMMIT/ROLLBACK
        

        但是,当事务结束时,表将被删除。如果您不能使用这样的事务,那么您应该使用使用Process-Keyed Table method 的永久表。

        【讨论】:

        • 除了保持表处于活动状态之外,这是否还会阻止任何其他连接读取(更不用说更新)任何由 TOP 1 选择的随机记录。锁甚至可能从一行升级对页面、范围甚至表锁定阻止更多数据被访问。这可能是不可取的!我不确定,但如果发出此命令时表中没有数据,则不会持有任何锁。
        • 这一切都取决于##globaltemp 表的实现。可能每个进程都有自己的行块? OP从不解释。我敢打赌,真正的解决方案是使用 ##globaltemp 表以外的东西,比如我在答案中链接到的 Process-Keyed Table method
        猜你喜欢
        • 2010-10-15
        • 1970-01-01
        • 1970-01-01
        • 2012-10-17
        • 2021-11-19
        • 2011-12-17
        • 2010-10-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多