将值“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.tables
和 sys.columns
的帮助下,我们可以在一个查询中完成此操作。
还是删除所有 BusinessUnit column
并使用默认值重新添加更好?
如有任何建议,我们将不胜感激。
不一定,您必须生成动态 SQL 或编写脚本。
我通常 select 来自 INFORMATION_SCHEMA
(或 sys.tables
)的表,然后将其复制到 Excel 并生成一个 UPDATE
语句(或其他)使用公式。将其复制到管理工作室并按开始。
首先让我们从真实你这里遇到的问题开始。您将 same 列添加到数据库中的每个 table 这一事实无疑是一个缺陷。对于每一行,您不可能在 every table 上需要此列。它可能非常 容易引入引用完整性问题。例如,您已将值添加到每个 table,并且这些 table 可能具有关系。那么,当您将 TableX
中的 BusinessUnit
列的值更新为 2
时会发生什么,但不要将 all 与其相关的行更新为 2
在 TableA
TableB
和 TableZ
中?然后你有一个与一个 BusinessUnit
相关的“父”行和一个与另一个相关的“子”行。这很可能不是期望或预期的行为。
最喜欢的列应该添加到几个 tables,我们不知道 tables(我们对您的设计一无所知)但很可能在最低点在关系中。然后,如果您需要知道 BusinessUnit
与什么相关,您将确保查询 JOIN
s 到相关的 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;
我们的数据库有 450 多个 table。最近我们在 Db
中的每个 table 中添加了 BusinessUnit int
列,没有默认值 1
。现在我们要为所有 table 现有行中的 BusinessUnit
列设置 1
。有什么办法可以用单个查询来做到这一点吗?对于单个 table 很容易,如下所示
update tablename set BusinessUnit=1
可能在 sys.tables
和 sys.columns
的帮助下,我们可以在一个查询中完成此操作。
还是删除所有 BusinessUnit column
并使用默认值重新添加更好?
如有任何建议,我们将不胜感激。
不一定,您必须生成动态 SQL 或编写脚本。
我通常 select 来自 INFORMATION_SCHEMA
(或 sys.tables
)的表,然后将其复制到 Excel 并生成一个 UPDATE
语句(或其他)使用公式。将其复制到管理工作室并按开始。
首先让我们从真实你这里遇到的问题开始。您将 same 列添加到数据库中的每个 table 这一事实无疑是一个缺陷。对于每一行,您不可能在 every table 上需要此列。它可能非常 容易引入引用完整性问题。例如,您已将值添加到每个 table,并且这些 table 可能具有关系。那么,当您将 TableX
中的 BusinessUnit
列的值更新为 2
时会发生什么,但不要将 all 与其相关的行更新为 2
在 TableA
TableB
和 TableZ
中?然后你有一个与一个 BusinessUnit
相关的“父”行和一个与另一个相关的“子”行。这很可能不是期望或预期的行为。
最喜欢的列应该添加到几个 tables,我们不知道 tables(我们对您的设计一无所知)但很可能在最低点在关系中。然后,如果您需要知道 BusinessUnit
与什么相关,您将确保查询 JOIN
s 到相关的 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;