繁体   English   中英

SQL:遍历一列,将值存储为变量,运行SQL,然后继续进行下一行?

[英]SQL: Looping through a column, stored the value as a variable, run SQL, then move on to the next line?

我目前正在轮换工作,并试图教自己一些SQL技能。

场景:我负责1个数据库-10个带有10个主键的表。 每个月,我们的代码团队都会发布对表的更新。 我想删除表并生成脚本来创建更新的表。

我不只是删除旧表和存储过程,而是想重命名当前表以出于任何原因保留结构/数据。

在我的数据库中,我还有一个名为“ TableUpdateList”的表,其中有1列“ TableName”和10行-每行包含已更新列的名称(行1 = TableName1,行2 = TableName2,行3 = TableName3)

我希望能够“遍历” TableUpdateList表并将每个值插入一组SQL语句中。

例如,以下是我要运行的SQL语句:

--drop the previous backup table
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME = '*TableName1*'+'_Old') DROP TABLE TableName1_Old

-- rename the current tables to _old 
EXEC sp_rename *TableName1*, TableName1_Old;

我正在尝试找到一种方法来滚动TableUpdateList的列,并运行以上两个语句,以该行中存在的任何值将其斜体显示为斜体。

因为我想为了在这里得到答案,所以只是采取了疯狂的尝试,所以必须尝试一些操作,因此这是我的伪代码:

Declare @TableNames as List

For i in @TableNames

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME = '*i*'+'_Old') DROP TABLE TableName1_Old

-- rename the current tables to _old 
EXEC sp_rename *i*, TableName1_Old;

Oi,在此先感谢您提供的任何帮助或指向正确的方向,以便我可以在网上进一步阅读上述内容。

您可以将sp_executesqlCURSORS一起使用以进行此类工作。 这是我认为您需要的:

测试对象:

CREATE TABLE TableName1 ( ID INT )
GO
CREATE TABLE TableName2 ( ID INT )
GO
CREATE TABLE TableNames ( Name NVARCHAR(MAX) )
GO

INSERT  INTO TableNames
VALUES  ( 'TableName1' ),
        ( 'TableName2' )

脚本本身:

DECLARE @name NVARCHAR(MAX) ,
    @dropStatement NVARCHAR(MAX),
    @renameStatement NVARCHAR(MAX)  

DECLARE cur CURSOR FAST_FORWARD READ_ONLY
FOR
    SELECT  Name
    FROM    dbo.TableNames

OPEN cur

FETCH NEXT FROM cur INTO @name

WHILE @@FETCH_STATUS = 0
    BEGIN

        IF EXISTS ( SELECT  *
                    FROM    INFORMATION_SCHEMA.TABLES
                    WHERE   TABLE_NAME = @name + '_Old' )
            BEGIN
                SET @dropStatement = 'DROP TABLE ' + @name + '_Old'
                EXEC sp_executesql  @dropStatement                  
            END

            SET @renameStatement = 'sp_rename ' + @name + ', ' + @name + '_Old';   
                EXEC sp_executesql  @renameStatement

        FETCH NEXT FROM cur INTO @name

    END

CLOSE cur
DEALLOCATE cur

之后,您应该再次添加TableName1TableName2

必须尽可能避免使用游标。

--Preparing script which would check if the old tables exists. If it does,
--it drops the old table
--e.g. first the value 'Table1' is found in TableUpdateList table.
--Then, Table1_Old is deleted and Table1 is renamed to Table1_Old

SELECT 'DROP TABLE ' + b.name + '_Old; EXEC sp_rename ''' + b.name+ ''', ''' + b.name+ '_Old;''' AS [Action] 
INTO #Action
FROM INFORMATION_SCHEMA.TABLES A JOIN TableUpdateList B ON A.TABLE_NAME = b.NAME + '_Old'

DECLARE @sql VARCHAR(8000) 
SELECT @sql = COALESCE(@sql + ' ', '') + [Action]
FROM #Action

select @sql
--EXEC (@sql)

首先验证变量@sql的值。 然后,取消注释最后一行以执行代码。

SQL小提琴

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM