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

时间:2015-01-20 06:41:34

标签: sql sql-server tsql

我目前正在改变工作中的角色,并试图自学一些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,提前感谢任何帮助或指向正确的方向,我可以在这里进一步阅读有关上述内容的信息。

2 个答案:

答案 0 :(得分:0)

您可以将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

答案 1 :(得分:0)

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

--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 fiddle