我正在尝试使用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 ...
(这似乎不起作用,但我把它包括在内,让我觉得我希望能做些什么。)
感谢您的帮助!
答案 0 :(得分:0)
这有点麻烦,但您可以通过将列添加为可为空来添加约束,确定要为预先存在的行存储的值,然后使列为NOT NULL。我也会回避不受支持的,未记录的存储过程。我发现了a problem with sp_MSforeachdb(with a workaround here),这也有可能在这里表现出来。这就是我如何做到这一点:
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 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 sp_executesql @sql;
这些脚本都假设您没有愚蠢的对象名称,例如1 of My Friend's Cool High % Table!
。