如何枚举SQL Server数据库中的表并执行DML

时间:2013-10-20 08:21:22

标签: sql-server tsql

如何以可以对它们执行DML的方式为其表枚举数据库?我已经完成了从单个语句中检索表名:

SELECT TABLE_NAME FROM MyDB.INFORMATION_SCHEMA.TABLES;

我的大多数表都有一个具有相同名称的特殊字段,我想通过表枚举将它们全部更新为相同的值。数据库的结构使我无法使用参照完整性进行更新传播,这是我手动更新的一种特殊情况。我不确定如何循环并更新其中的公共字段,并为没有SpecialField的表指定了try-catch块。如:

declare @i int =0;
While(@i < MyDB.INFORMATION_SCHEMA.TABLES.length)
begin
   begin try
     Update MyDB.INFORMATION_SCHEMA.TABLES[i] set SpecialField= SomeValue;
   end try
   begin catch end catch
   set @i=@i+1;
end

感谢。

3 个答案:

答案 0 :(得分:2)

您必须使用动态SQL,即在字符串(VarChar)中构造UPDATE语句并使用EXEC命令执行命令。由于我不知道您使用的具体RDBMS,我不能举个例子。但基本上,它看起来与此相似:

declare @cmd VarChar(80)
declare @i int =0;
While(@i < MyDB.INFORMATION_SCHEMA.TABLES.length)
begin
   begin try
     set @cmd='Update '+MyDB.INFORMATION_SCHEMA.TABLES[i];
     set @cmd=@cmd +' set SpecialField= '+cast(SomeValue as VarChar);
     exec (@cmd)
   end try
   begin catch end catch
   set @i=@i+1;
end

答案 1 :(得分:1)

以下是使用sp_MSforeachtable的解决方案,但我承认它看起来并不简单 但是,它会直接查找包含正确列的表 表名可通过语句中的?访问,但格式为'[dbo].[tablename]'

exec sp_MSforeachtable  '
    IF ''?'' IN (
        SELECT ''['' + TC.TABLE_SCHEMA + ''].['' + TC.TABLE_NAME + '']''
        FROM INFORMATION_SCHEMA.COLUMNS TC
        WHERE TC.COLUMN_NAME = ''SpecialField''
        )
    BEGIN
        EXECUTE sp_executesql N''UPDATE ? SET [SpecialField] = NULL'';
        PRINT ''? done'';
    END
    ELSE 
        PRINT ''? skipped'';
';

答案 2 :(得分:1)

我用这种方式完成了它,所以其他人可以使用我的代码:

DECLARE @DBTables TABLE (
    ID int,
    Name varchar(200)
);

with DBTables as
(
    SELECT Row_Number() over(order by TABLE_NAME) as ID,TABLE_NAME as Name FROM  
                                            PTBilling.INFORMATION_SCHEMA.TABLES
)
insert into @DBTables (ID,Name) select ID,Name from DBTables;

declare @cmd varchar(1000);
declare @OldID int =10714;
declare @NewID int=200;
declare @ID int =1;
declare @tableMaxID int=(select max(ID) from @DBTables);
While(@ID < @tableMaxID)
begin
   begin try
     set @cmd='Update '+ (select top 1 Name from @DBTables where ID=@ID);
     set @cmd= @cmd +' set ID= '+ cast(@NewID as varchar)+ 
                   ' where ID=' + cast(@OldID as varchar);
     exec (@cmd)
   end try
   begin catch end catch
   set @ID = @ID+1;
end