SQL 临时表上的后缀

Posted

技术标签:

【中文标题】SQL 临时表上的后缀【英文标题】:Suffix on SQL temp tables 【发布时间】:2019-05-06 18:42:00 【问题描述】:

我正在制作一个将表名打印到临时表中的脚本。

我需要它像这样在末尾添加一个后缀

#temptable1 
#temptable2 
...
#temptableXXX

我的问题是当我使用排名时它不会增加,并且标识在游标中不起作用。

我已经发布了两次尝试。其中一个被注释掉了。

DECLARE @suffix VARCHAR(1000)
DECLARE #crs insensitive CURSOR FOR
    SELECT IDENTITY(int, 1, 1) AS ID --rank() over (partition by name order by 
name)  --as Identity(1,1) 
    INTO name
    FROM sys.tables
    FOR READ ONLY

OPEN #crs

FETCH NEXT FROM #crs INTO @suffix 

WHLIE @@FETCH_STATUS = 0
BEGIN
    DECLARE @TableName VARCHAR(100)
    DECLARE @TabName CURSOR

    SET @TabName = CURSOR FOR 
        SELECT NAME + @suffix
        FROM sys.tables 
        ORDER BY name

    OPEN @TabName 

    PRINT '--- Her skal header printes '

    FETCH NEXT FROM @TabName INTO @TableName 

    WHILE @@FETCH_STATUS = 0  
    BEGIN  
        PRINT @TableName
        ----------------------------------------------------------------- start loop tabel

        ----------------------------------------------------------------- slut loop tabel
        Fetch next from @TabName into @TableName 
    END 

    CLOSE @TabName;  
    DEALLOCATE @TabName;   
END

CLOSE #crs 
DEALLOCATE #crs

【问题讨论】:

你想在这里做什么?为什么需要为此使用光标?您是否只是想列出所有表名,如TableName1, TableName2 .. 我正在做一个制作增量脚本的脚本。为此,我正在使用很多#temptables,但它们需要在每次运行后递增 1,因此我得到 #temp1、#temp2 等。否则编译器会说该表已经存在 您仍然不需要光标。但这也是XY Problem,您可以在其中寻求y 解决方案的帮助,但没有描述主要的x 问题。构建许多#temptables 可能会被重构。 【参考方案1】:

我认为你只是在寻找

SELECT CONCAT(Name, ROW_NUMBER() OVER(ORDER BY Name)) TableName
FROM Sys.Tables;

【讨论】:

我认为你是对的。非常感谢。真的很头疼 是的,@Maltbeer,请这样做 - 如果他们来到这里遇到与您相同的问题,这将帮助其他人找到这个答案。 这个问题的另一个解决方案是。转换(nvarchar(3),@nr)【参考方案2】:

首先,不要使用光标 :) 我会这样做:

DECLARE 
    @Table_Name As Varchar(200)
    , @Message As VarChar(Max)
    , @Suffix As Int = 1
    , @Temp_Table_Name As Varchar(100)


Select Distinct 
    name
    , 0 As Processed
Into #Temp_Names
    from sys.tables

While Exists (Select Top 1 1
    FROM #Temp_Names
        WHERE Processed = 0)    
BEGIN
    Select Top 1 
        @Table_Name = name
            From #Temp_Names
            WHERE Processed = 0
    Set @Temp_Table_Name = 'TempTable' + Cast(@Suffix As Varchar(100))

/*

your code here

*/

    Update #Temp_Names
        Set Processed = 1
    Where name = @Table_Name
    Set @Suffix = @Suffix + 1

End

您可能需要调整 Varchar 尺寸 - 我是从臀部拍摄的。

【讨论】:

使用 while 循环比使用游标更好吗?事实上,经过良好调整的游标可以在 while 循环中略微增加。但这根本不需要任何查看。 我不是性能专家——我只知道当我使用这个结构而不是等效的光标时,这每次都会让光标失望。我说的是“数量级”差异。 将光标替换为 while 循环,反之亦然,就像将 vega 替换为 yugo 参加一级方程式比赛。想谈谈“数量级”的差异......使用基于集合的逻辑。 我不反对,@SeanLange。我只知道我看到了什么,我将 15 分钟到 25 秒称为“一个数量级”。 如果你在while循环和游标之间有那么大的区别,那就是非常错误的。它们通常非常接近,光标几乎总是占据优势。但无论如何,如果循环可能不是这里最好的构造,因为我们可以轻松地做一些基于集合的逻辑。 :)【参考方案3】:

试试这个-

SELECT NAME+CAST(RANK() OVER(ORDER BY NAME) AS VARCHAR) AS NEW_NAME 
FROM SYS.TABLES

【讨论】:

【参考方案4】:

这个问题的另一个解决方案是这样的。

declare @nr int = 0;
set @nr = @nr +1 ;
#TmpTab_'+CONVERT(nvarchar(3), @nr)+'

【讨论】:

以上是关于SQL 临时表上的后缀的主要内容,如果未能解决你的问题,请参考以下文章

使用临时表上的函数检查约束

临时表上的 distkey 和 sortkey - Redshift

在主表上的数据库触发器中将数据插入临时表

如何在 SQL Server 2012 中创建的临时表上查找索引列表

提高大型表上的 SQL Server 查询性能

特定列上的SQL内部联接