Sql server SQL Server 2019的TempDB缓存问题

Sql server SQL Server 2019的TempDB缓存问题,sql-server,Sql Server,我的问题在SQL Server 2017中有效,但在SQL Server 2019中无效。它与tempdb缓存有关。这与在存储过程中创建临时表以及使用动态SQL更改其结构有关。我们需要这样做,以满足各种动态报告需求。第一次调用它时,结构被缓存,随后对过程的调用失败或返回无效结果。如何防止缓存此类表?下面是一些示例代码,以及它在2017年的工作原理。谢谢你的帮助 CREATE PROCEDURE [dbo].[tempDBCachingCheck] @yearList varchar(ma

我的问题在SQL Server 2017中有效,但在SQL Server 2019中无效。它与tempdb缓存有关。这与在存储过程中创建临时表以及使用动态SQL更改其结构有关。我们需要这样做,以满足各种动态报告需求。第一次调用它时,结构被缓存,随后对过程的调用失败或返回无效结果。如何防止缓存此类表?下面是一些示例代码,以及它在2017年的工作原理。谢谢你的帮助

CREATE PROCEDURE [dbo].[tempDBCachingCheck]
    @yearList varchar(max)
AS
BEGIN
    SET NOCOUNT ON

    DECLARE @yearCount int 
    DECLARE @yearCounter INT 
    DECLARE @yearValue INT 

    DECLARE @sql nvarchar(max) 

    -- With table variable 
    DECLARE @tempYearList TABLE (id INT IDENTITY(1,1), rpt_yr int)
    INSERT INTO @tempYearList (rpt_yr)

    SELECT value FROM STRING_SPLIT(@yearList, ',');                                                                                                                                                                                                                    
                                                               
    SELECT * FROM @tempYearList

    --------------------------------------------------------------------
    --With temporary table, since we will be altering this with dynamic sql 
    CREATE TABLE #returnTable (id INT IDENTITY(1,1))
    
    -- Tried adding a named constraint to not make it cache, but does not work 
    ALTER TABLE #returnTable
    ADD CONSTRAINT UC_ID UNIQUE (id);
        
    SELECT @yearCount = COUNT(*) FROM @tempYearList 
        
    -- Add the years as columns to the return table to demostrate the problem 
    SET @sql = N'ALTER TABLE #returnTable ADD ' 
    SET @yearCounter = 1

    WHILE @yearCounter <= @yearCount 
    BEGIN   
        SELECT @yearValue = rpt_yr FROM @tempYearList WHERE id = @yearCounter

        IF @yearCounter > 1
            SET @Sql = @Sql + N', '

        SET @sql = @sql + N' [' + convert(varchar(20), @yearValue) + N'] float' 
        SET @yearCounter = @yearCounter + 1
    END

    EXECUTE sp_executesql @sql 
    
    SELECT * FROM #returnTable

    -- No need to drop the temporary tables but doing just in case 
    DROP TABLE #returnTable 
END 
GO                               

-- run these statements and you will see the second call with return the cached #returnTable
EXEC tempDBCachingCheck '2019,2020' 
EXEC tempDBCachingCheck '2017,2018,2019,2020'
GO 

-- Clear temp table cache and call in reverse order, then will hit an error 
-- 'A severe error occurred on the current command. The results, if any, should be discarded.' 
USE tempDB
GO 
DBCC FREEPROCCACHE
GO 

EXEC tempDBCachingCheck '2017,2018,2019,2020'
EXEC tempDBCachingCheck '2019,2020'
GO 

这似乎已在一个累积更新中修复。描述似乎符合:

:

当您在SQL Server 2019上重复运行使用带索引的临时表的存储过程时,客户端可能会收到一个意外错误,其中包含消息“当前命令出现严重错误”,并且SQL Server上记录了访问冲突异常。如果在任何以前的SQL Server主版本上执行相同的工作负载,则不会发生此问题

丹·古兹曼(Dan Guzman)建议安装最新的CU是一条可行之路


使用:EXEC tempDBCachingCheck'2017201820192020'和重新编译也会有所帮助。

EXEC tempDBCachingCheck'2017201820192020'和重新编译会改变什么吗?我无法用SQL 2019 CU8重现您问题中的代码。你安装了什么CU?@LukaszSzozda,可以重新编译,但它不会对其他查询使用任何缓存的执行计划,对吗?@DanGuzman,2019的版本如下:Microsoft SQL Server 2019 RTM-15.0.2000.5 X64 2019年9月24日13:48:23版权C 2019 Microsoft Corporation Enterprise Edition 64位Windows 10 Pro 10.0 Build 19041:@GuthalGuthal,我建议您安装。