SQL - 向数据库中的所有表添加一个具有默认值的新列
SQL - Add a new column with a default value to all tables in the DB
我有以下声明:
EXEC sp_MSforeachtable '
DECLARE @defaultId integer;
SET @defaultId = 13;
IF EXISTS(SELECT name FROM sys.sysobjects WHERE Name = N''?'' AND xtype = N''U'')
BEGIN
IF COL_LENGTH(''[?]'',''NewColumn'') IS NULL
BEGIN
ALTER TABLE [?] ADD NewColumn integer null
UPDATE [?]
SET NewColumn = @defaultId
END
END
'
我正在尝试将 NewColumn
列添加到我的数据库中所有没有它的 table 并将默认值设置为 13
。我执行它,它说它成功完成,但没有任何改变。我在这里做错了什么?
注意:我有一个名为 User
的 table,因此是 "[]"
。我不知道这是否会增加额外的复杂性。
我不是特别喜欢调试 sp_MSforeachtable
代码所以我建议你这个方法:
DECLARE @Name AS VARCHAR(128)
DECLARE C_Table CURSOR FOR
SELECT sys.objects.Name
FROM sys.objects
WHERE sys.objects.type = 'U' AND
sys.objects.Name NOT IN (
SELECT DISTINCT sys.objects.Name
FROM sys.objects INNER JOIN
sys.columns ON sys.objects.object_id = sys.columns.object_id
WHERE sys.objects.type = 'U' AND
sys.columns.Name = 'NewColumn'
)
OPEN C_Table
FETCH NEXT FROM C_Table INTO @Name
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC('ALTER TABLE ' + @Name + ' ADD NewColumn INTEGER NULL')
EXEC('ALTER TABLE ' + @Name + ' ADD CONSTRAINT DF_' + @Name + '_A DEFAULT 13 FOR NewColumn')
EXEC('UPDATE ' + @Name + ' SET NewColumn = 13')
FETCH NEXT FROM C_Table INTO @Name
END
CLOSE C_Table
DEALLOCATE C_Table
这是使用 sp_MSforeachtable
和您的语法的替代解决方案;请注意:
- 您需要
PARSENAME
sp_MSforeachtable
提供的名称(即 [yourschema].[yourtable]
),因为 sys.objects.name
仅包含 table 名称(即:yourtable
)
- 您必须使用 2 步,因为似乎无法在
sp_MSforeachtable
中使用 GO
- 你不能在
ALTER TABLE
中使用变量,但你必须指定一个固定的 DEFAULT
这是代码:
EXEC sp_MSforeachtable '
IF EXISTS(SELECT * FROM sys.sysobjects WHERE Name = PARSENAME(''?'', 1) AND xtype = N''U'')
BEGIN
IF COL_LENGTH(PARSENAME(''?'', 1), ''NewColumn'') IS NULL
BEGIN
ALTER TABLE ? ADD NewColumn INT NULL DEFAULT(13)
END
END
'
EXEC sp_MSforeachtable '
DECLARE @defaultId INT
SELECT @defaultId = 13
IF EXISTS(SELECT * FROM sys.sysobjects WHERE Name = PARSENAME(''?'', 1) AND xtype = N''U'')
BEGIN
IF NOT COL_LENGTH(''?'', ''NewColumn'') IS NULL
BEGIN
UPDATE ? SET NewColumn = @defaultId
END
END
'
很可能 NewColumn
没有被识别。尝试
EXEC sp_MSforeachtable '
DECLARE @defaultId integer;
SET @defaultId = 13;
IF EXISTS(SELECT name FROM sys.sysobjects WHERE Name = PARSENAME(''?'',1) AND xtype = N''U'')
BEGIN
IF COL_LENGTH(''?'',''NewColumn'') IS NULL
BEGIN
ALTER TABLE ? ADD NewColumn integer null
EXEC(CONCAT(''UPDATE ? SET NewColumn = '', @defaultId))
END
END'
您需要分两步完成此操作。
update语句在执行前会被求值,会抛出错误(因为此时没有列)
第 1 步(更改 table):
EXEC sp_MSforeachtable '
IF EXISTS(SELECT * FROM sys.sysobjects WHERE Name = parsename(N''?'', 1) AND xtype = N''U'')
BEGIN
IF COL_LENGTH(''[?]'',''NewColumn'') IS NULL
BEGIN
ALTER TABLE [?] ADD NewColumn integer null
END
END
'
第2步(设定值):
EXEC sp_MSforeachtable '
DECLARE @defaultId integer;
SET @defaultId = 13;
IF EXISTS (SELECT * FROM sys.sysobjects WHERE Name = parsename(N''?'', 1) AND xtype = N''U'')
BEGIN
IF COL_LENGTH(''[?]'',''NewColumn'') IS not NULL
BEGIN
UPDATE [?]
SET NewColumn = @defaultId
END
END
'
您提到了默认值。您只使用固定值更新了新列的值,而没有定义默认值。这可能是一个差异,但对于这个问题并不重要。
我有以下声明:
EXEC sp_MSforeachtable '
DECLARE @defaultId integer;
SET @defaultId = 13;
IF EXISTS(SELECT name FROM sys.sysobjects WHERE Name = N''?'' AND xtype = N''U'')
BEGIN
IF COL_LENGTH(''[?]'',''NewColumn'') IS NULL
BEGIN
ALTER TABLE [?] ADD NewColumn integer null
UPDATE [?]
SET NewColumn = @defaultId
END
END
'
我正在尝试将 NewColumn
列添加到我的数据库中所有没有它的 table 并将默认值设置为 13
。我执行它,它说它成功完成,但没有任何改变。我在这里做错了什么?
注意:我有一个名为 User
的 table,因此是 "[]"
。我不知道这是否会增加额外的复杂性。
我不是特别喜欢调试 sp_MSforeachtable
代码所以我建议你这个方法:
DECLARE @Name AS VARCHAR(128)
DECLARE C_Table CURSOR FOR
SELECT sys.objects.Name
FROM sys.objects
WHERE sys.objects.type = 'U' AND
sys.objects.Name NOT IN (
SELECT DISTINCT sys.objects.Name
FROM sys.objects INNER JOIN
sys.columns ON sys.objects.object_id = sys.columns.object_id
WHERE sys.objects.type = 'U' AND
sys.columns.Name = 'NewColumn'
)
OPEN C_Table
FETCH NEXT FROM C_Table INTO @Name
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC('ALTER TABLE ' + @Name + ' ADD NewColumn INTEGER NULL')
EXEC('ALTER TABLE ' + @Name + ' ADD CONSTRAINT DF_' + @Name + '_A DEFAULT 13 FOR NewColumn')
EXEC('UPDATE ' + @Name + ' SET NewColumn = 13')
FETCH NEXT FROM C_Table INTO @Name
END
CLOSE C_Table
DEALLOCATE C_Table
这是使用 sp_MSforeachtable
和您的语法的替代解决方案;请注意:
- 您需要
PARSENAME
sp_MSforeachtable
提供的名称(即[yourschema].[yourtable]
),因为sys.objects.name
仅包含 table 名称(即:yourtable
) - 您必须使用 2 步,因为似乎无法在
sp_MSforeachtable
中使用 - 你不能在
ALTER TABLE
中使用变量,但你必须指定一个固定的DEFAULT
GO
这是代码:
EXEC sp_MSforeachtable '
IF EXISTS(SELECT * FROM sys.sysobjects WHERE Name = PARSENAME(''?'', 1) AND xtype = N''U'')
BEGIN
IF COL_LENGTH(PARSENAME(''?'', 1), ''NewColumn'') IS NULL
BEGIN
ALTER TABLE ? ADD NewColumn INT NULL DEFAULT(13)
END
END
'
EXEC sp_MSforeachtable '
DECLARE @defaultId INT
SELECT @defaultId = 13
IF EXISTS(SELECT * FROM sys.sysobjects WHERE Name = PARSENAME(''?'', 1) AND xtype = N''U'')
BEGIN
IF NOT COL_LENGTH(''?'', ''NewColumn'') IS NULL
BEGIN
UPDATE ? SET NewColumn = @defaultId
END
END
'
很可能 NewColumn
没有被识别。尝试
EXEC sp_MSforeachtable '
DECLARE @defaultId integer;
SET @defaultId = 13;
IF EXISTS(SELECT name FROM sys.sysobjects WHERE Name = PARSENAME(''?'',1) AND xtype = N''U'')
BEGIN
IF COL_LENGTH(''?'',''NewColumn'') IS NULL
BEGIN
ALTER TABLE ? ADD NewColumn integer null
EXEC(CONCAT(''UPDATE ? SET NewColumn = '', @defaultId))
END
END'
您需要分两步完成此操作。
update语句在执行前会被求值,会抛出错误(因为此时没有列)
第 1 步(更改 table):
EXEC sp_MSforeachtable '
IF EXISTS(SELECT * FROM sys.sysobjects WHERE Name = parsename(N''?'', 1) AND xtype = N''U'')
BEGIN
IF COL_LENGTH(''[?]'',''NewColumn'') IS NULL
BEGIN
ALTER TABLE [?] ADD NewColumn integer null
END
END
'
第2步(设定值):
EXEC sp_MSforeachtable '
DECLARE @defaultId integer;
SET @defaultId = 13;
IF EXISTS (SELECT * FROM sys.sysobjects WHERE Name = parsename(N''?'', 1) AND xtype = N''U'')
BEGIN
IF COL_LENGTH(''[?]'',''NewColumn'') IS not NULL
BEGIN
UPDATE [?]
SET NewColumn = @defaultId
END
END
'
您提到了默认值。您只使用固定值更新了新列的值,而没有定义默认值。这可能是一个差异,但对于这个问题并不重要。