将值“1”设置为整个数据库中所有表的特定列?

set value `1` to a specific column for all tables in whole database?

我们的数据库有 450 多个 table。最近我们在 Db 中的每个 table 中添加了 BusinessUnit int 列,没有默认值 1。现在我们要为所有 table 现有行中的 BusinessUnit 列设置 1。有什么办法可以用单个查询来做到这一点吗?对于单个 table 很容易,如下所示

update tablename set BusinessUnit=1

可能在 sys.tablessys.columns 的帮助下,我们可以在一个查询中完成此操作。

还是删除所有 BusinessUnit column 并使用默认值重新添加更好?

如有任何建议,我们将不胜感激。

不一定,您必须生成动态 SQL 或编写脚本。

我通常 select 来自 INFORMATION_SCHEMA(或 sys.tables)的表,然后将其复制到 Excel 并生成一个 UPDATE 语句(或其他)使用公式。将其复制到管理工作室并按开始。

首先让我们从真实你这里遇到的问题开始。您将 same 列添加到数据库中的每个 table 这一事实无疑是一个缺陷。对于每一行,您不可能在 every table 上需要此列。它可能非常 容易引入引用完整性问题。例如,您已将值添加到每个 table,并且这些 table 可能具有关系。那么,当您将 TableX 中的 BusinessUnit 列的值更新为 2 时会发生什么,但不要将 all 与其相关的行更新为 2TableA TableBTableZ 中?然后你有一个与一个 BusinessUnit 相关的“父”行和一个与另一个相关的“子”行。这很可能不是期望或预期的行为。

最喜欢的列应该添加到几个 tables,我们不知道 tables(我们对您的设计一无所知)但很可能在最低点在关系中。然后,如果您需要知道 BusinessUnit 与什么相关,您将确保查询 JOINs 到相关的 table 以找出 BusinessUnit 该行属于什么(或者也许根据您的设计使用 EXISTS

话虽这么说,你可以这样做,但它可能不会很快,而且会很昂贵。它肯定不会解决我上面提到的引用完整性问题。为此,您需要使用动态 SQL。 Asd 我们正在更新 450~ tables,我将每个 UPDATE 包装在它自己的事务中,这样当进程运行时它不会最终锁定 每个 你的 table。我还假设 您使用的是 SQL 服务器的受支持版本,因此可以访问 STRING_AGG。如果您不使用旧的 FOR XML PATH 方法。

DECLARE @SQL nvarchar(MAX),
        @CRLF nchar(2) = NCHAR(13) = NCHAR(10);

SELECT @SQL = STRING_AGG(
              N'BEGIN TRANSCATION;' + @CRLF +
              N'    UPDATE ' + QUOTENAME(s.[name]) + N'.' + QUOTENAME(t.[name]) + @CRLF +
              N'    SET ' + QUOTENAME(c.[name]) + N' = 1;' + @CRLF +
              N'COMMIT;',@CRLF)
FROM sys.schemas s
     JOIN sys.tables t ON s.schema_id = t.schema_id
     JOIN sys.columns c ON t.object_id = c.object_id
WHERE c.[name] = N'BusinessUnit';

--Your best friends
--PRINT @SQL;
--SELECT @SQL;

EXEC sys.sp_executesql @SQL;