1

如何以可以对它们执行 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

谢谢。

4

3 回答 3

2

您必须使用动态SQL,即UPDATE在字符串(VarChar)中构造语句并使用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
于 2013-10-20T08:28:07.980 回答
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'';
';
于 2013-10-20T09:02:52.620 回答
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
于 2013-10-20T09:41:40.430 回答