我正在处理脚本,其中包括对数据库的更改,这些更改可能会使数据库暂时处于无效状态。目前我在开始时禁用所有约束,然后使用以下代码在脚本末尾重新启用它们:
/*** Disable all constraints ***/
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
/*** Enable all constraints ***/
EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
但这并没有禁用空约束,因为我从我所读到的内容中理解,空约束的处理方式与FK约束不同。
我认为有必要更改所有表以使它们允许为null,然后在脚本末尾再次更改它们。
我不能“硬编码”表格的名称,因为我没有这些信息,所以我不能做很多陈述,如:
ALTER TABLE someTable ALTER COLUMN someColumn INT NULL
它需要是动态的。有关如何实现这一目标的任何想法?
修改
我无法处理的一种情况是向现有表添加新的非空列。我无法控制添加此列的脚本(它由自动化工具创建),创建的脚本为ALTER TABLE someTable ADD someColumn INT NOT NULL
,在此语句之后会发生一些删除/插入/更新,使someTable
成为处于有效状态,但错误发生在ALTER
语句
答案 0 :(得分:0)
这是一个脚本,我从中选择text
类型的所有字段,使其成为varchar(max)
。
您的方法类似,但您需要根据自己的需要进行修改。
更改SQL以找到所需的正确c.xtype。
根据您的要求修改WHERE语句,将@sql_select更改为您的需求。
打印它进行测试,如果它是你需要的话,取消注释EXEC。
我的代码(编辑):
-- change all text to varchar(max)
DECLARE @sql_select NVARCHAR(MAX);
DECLARE @table_name VARCHAR(MAX);
DECLARE @column_name VARCHAR(MAX);
DECLARE local_column_update_cursor CURSOR FOR
SELECT c.name as column_name, o.name as table_name
FROM dbo.syscolumns c, dbo.sysobjects o
WHERE c.xtype IN (35,99) -- text/ntext
AND o.id = c.id
AND OBJECTPROPERTY(o.id, N'IsUserTable') = 1
OPEN local_column_update_cursor
FETCH NEXT FROM local_column_update_cursor
INTO @column_name, @table_name
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql_select = 'ALTER TABLE ' + @table_name + ' ALTER COLUMN ' + @column_name + ' VARCHAR(MAX)'
--EXEC sp_executesql @sql_select
PRINT @sql_select
FETCH NEXT FROM local_column_update_cursor
INTO @column_name, @table_name
END
DEALLOCATE local_column_update_cursor
GO
如果我有更多时间,我可能会编辑以便在以后完成它。