【问题标题】:Should I drop temp table in this scenario?在这种情况下我应该删除临时表吗?
【发布时间】:2014-04-18 06:21:15
【问题描述】:

我有一个在 .Net 网络服务中调用的存储过程,其工作方式如下(伪代码):

CREATE PROC SomeProc AS
BEGIN TRY
BEGIN TRAN
    IF EXISTS (SELECT * FROM sys.tables WHERE name LIKE '#temp%')
        DROP TABLE #temp;

    CREATE TABLE #temp (...);
    /* lots of logic here */

    -- clear up
    IF EXISTS (SELECT * FROM sys.tables WHERE name LIKE '#temp%')
        DROP TABLE #temp;

COMMIT TRAN
END TRY

BEGIN CATCH
    IF EXISTS (SELECT * FROM sys.tables WHERE name LIKE '#temp%')
        DROP TABLE #temp;
    ROLLBACK TRAN;
END CATCH

始终通过与数据库的相同连接(如配置文件中定义)访问 proc。

有人提出了一个担忧,即如果 web 服务和过程被快速连续调用两次,则存在第二次调用的临时表将被第一次调用删除的危险。

这是正确的吗?我认为 SQL Server 是同步的,所以不能同时调用两个过程,SQL 会将请求排队? This post 似乎表明我在做正确的事情,但多线程的答案让我很担心。任何澄清都会有所帮助。

【问题讨论】:

    标签: sql-server web-services azure sql-server-2012


    【解决方案1】:

    本地临时 (#) 表是会话范围的,其他会话不会干扰您在会话中创建的临时表。

    如果您在 tempdb 中对 sys.tables 进行选择,您将看到每个临时表都以会话标识符为后缀。

    此外,无需在存储过程中显式删除临时表,SQL Server 将进行自动清理,并缓存元数据以获得可能的性能优势。

    【讨论】:

    • 谢谢。如果同一个 Web 服务(以及使用该服务的同一个用户)连续两次调用 proc 会怎么样?那么这是否需要删除该表以防止临时表的交叉使用,即会话是否保持在范围内?
    • 不,每次执行过程都是不同的临时表。
    • 在此处阅读有关临时表的部分:technet.microsoft.com/en-us/library/ms174979.aspx
    【解决方案2】:

    可以使用TRUNCATE TABLE

    截断表#temp;

    【讨论】:

    • 这比我现在做的好还是坏,为什么?
    • 它与 DROP TABLE 有点不同。临时表它是一个会话中的表。在你的情况下,这是一个更好的方法。 TRUNCATE TABLE 从表中删除所有行,但表结构及其列、约束、索引等保留。要删除表定义及其数据,请使用 DROP TABLE 语句。
    猜你喜欢
    • 2011-01-17
    • 2022-07-22
    • 2013-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 2010-09-05
    相关资源
    最近更新 更多