2

我正在使用包含对数据库的更改的脚本,这些更改可以使数据库暂时处于无效状态。目前我在开始时禁用所有约束,然后在脚本末尾使用以下代码重新启用它们:

/*** 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 约束不同。

我认为有必要更改所有表以使它们允许为空,然后在脚本末尾再次更改它们。

我不能“硬编码”表的名称,因为我没有这些信息,所以我不能做很多陈述,比如:

ALTER TABLE someTable ALTER COLUMN someColumn INT NULL

它需要是动态的。关于如何实现这一目标的任何想法?

编辑: 我无法处理的一种情况是向现有表添加一个新的非空列。我无法控制添加此列的脚本(它是由自动化工具创建的),创建的脚本是ALTER TABLE someTable ADD someColumn INT NOT NULL,在此语句之后发生一些删除/插入/更新,使其someTable处于有效状态,但发生错误在ALTER声明上

4

1 回答 1

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

如果我有更多时间,我可能会稍后根据您的要求进行编辑以完成它。

于 2012-06-11T14:51:11.273 回答