0

我正在尝试使用 sp_MSforeachtable 向我的所有具有命名约束的表添加一个新列。

到目前为止,我已经这样做了:

USE [MYTable]
GO
exec sp_MSforeachtable 'ALTER TABLE ? ADD ChangedBy nvarchar(100) DEFAULT (suser_name()) NOT NULL'

除了约束名称出现类似:DF_TableName_Change_51EF2864 我希望它被命名为 DF_TableName_ChangedBy

我玩过,发现 PARSENAME(''?'',1) 会给我表格的名称。反正有没有使用这个动态构建约束名称?

Example: ... CONSTRAINT ''DF_''+PARSENAME(''?'',1)+''_CreatedBy'' DEFAULT ...

(这似乎行不通,但我将其包括在内是为了让您了解我希望可以完成的事情。)

谢谢你的帮助!

4

1 回答 1

0

这有点麻烦,但您可以通过将列添加为可为空、添加约束、决定要为预先存在的行存储什么值、然后使列不为空来做到这一点。我也会回避不受支持的、未记录的存储过程。我发现sp_MSforeachdb 存在问题这里有一个解决方法),这也可能在这里表现出来。这就是我将如何做到这一点:

DECLARE @sql NVARCHAR(MAX);
SET @sql = N'';

SELECT @sql = @sql + CHAR(13) + CHAR(10) + N'ALTER TABLE '
  + QUOTENAME(SCHEMA_NAME([schema_id])) + '.'
  + QUOTENAME(name) 
  + ' ADD ChangedBy NVARCHAR(100) NOT NULL;
ALTER TABLE '  + QUOTENAME(SCHEMA_NAME([schema_id])) + '.'
  + QUOTENAME(name) + ' ADD CONSTRAINT DF_' + name 
  + '_ChangedBy DEFAULT (SUSER_SNAME()) FOR ChangedBy;
  UPDATE ' + QUOTENAME(SCHEMA_NAME([schema_id])) + '.'
  + QUOTENAME(name) + ' SET ChangedBy = N''pre-existing'';
  ALTER TABLE ' + QUOTENAME(SCHEMA_NAME([schema_id])) + '.'
  + QUOTENAME(name) + ' ALTER COLUMN ChangedBy NVARCHAR(100) NOT NULL;'
  FROM sys.tables WHERE is_ms_shipped = 0;

PRINT @sql;
--EXEC sys.sp_executesql @sql;

(当您相信它正在执行您期望的操作时更改注释。请注意,您可能不会在 PRINT 输出中看到整个命令;根据您拥有的表的数量,它可能会被截断。您可以使用 TOP 1 或一个针对 sys.tables 的附加 WHERE 子句,以查看单个表的命令集是什么样的。)

您也可以在之后简单地重命名约束:

DECLARE @sql NVARCHAR(MAX);
SET @sql = N'';

SELECT @sql = @sql + CHAR(13) + CHAR(10) 
+ N'EXEC sp_rename N''' + c.name + ''',N''DF_' + t.name
+ '_ChangedBy'', N''OBJECT'';'
FROM sys.default_constraints AS c
INNER JOIN sys.tables AS t
ON c.parent_object_id = t.[object_id]
WHERE c.name LIKE 'DF[_]%[_]Change[_]%'
AND LOWER(c.[definition]) LIKE '%suser%';

PRINT @sql;
--EXEC sys.sp_executesql @sql;

这些脚本都假设您没有愚蠢的对象名称,例如1 of My Friend's Cool High % Table!.

于 2012-08-31T17:49:48.527 回答