【发布时间】:2015-02-04 21:56:28
【问题描述】:
在我的数据库中,大多数表中都有两列“IsActive”和“IsDeleted”,它们都是 BIT 类型。 我需要做的是,从表中删除“IsDeleted”列,但在删除之前复制 IsDeleted 到 IsActive 列的反向值。
以下是不同的场景:
1.如果“IsActive”和“IsDeleted”都存在,只需将“IsDeleted”的反向值复制到“IsActive”,然后删除“IsDeleted”列。
2.如果存在IsDeleted但不存在IsActive,只需将“IsDeleted”列重命名为“IsActive”,然后将所有值取反即可。
IF COL_LENGTH('table_name','IsDeleted') IS NOT NULL
BEGIN
IF COL_LENGTH('table_name','IsActive') IS NOT NULL
BEGIN
UPDATE table_name
SET IsActive = ~IsDeleted
END
ELSE
BEGIN
EXEC sp_RENAME 'table_name.IsDeleted', 'IsActive', 'COLUMN'
UPDATE table_name
SET IsActive = ~IsActive
END
ALTER TABLE table_name
DROP CONSTRAINT DF_table_name_IsDeleted
ALTER TABLE table_name DROP COLUMN IsDeleted
END
现在我想对数据库中的所有表做同样的事情。 怎么做?我不想为每个表手动编写查询。 在泛型查询中,表名和约束名是不知道的。
编辑: 到目前为止我已经尝试过
EXEC sp_MSforeachtable '
IF COL_LENGTH(''?'',''IsDeleted'') IS NOT NULL
BEGIN
IF COL_LENGTH(''?'',''IsActive'') IS NOT NULL
BEGIN
UPDATE ?
SET IsActive = ~IsDeleted
END
ELSE
BEGIN
EXEC sp_RENAME ''?.IsDeleted'', ''IsActive'', ''COLUMN''
UPDATE ?
SET IsActive = ~IsActive
END
DECLARE @ConstraintName nvarchar(200)
SELECT @ConstraintName = Name FROM SYS.DEFAULT_CONSTRAINTS
WHERE PARENT_OBJECT_ID = OBJECT_ID(''?'')
AND PARENT_COLUMN_ID = (SELECT column_id FROM sys.columns
WHERE NAME = N''IsDeleted''
AND object_id = OBJECT_ID(N''?''))
IF @ConstraintName IS NOT NULL
BEGIN
ALTER TABLE ?
DROP CONSTRAINT @ConstraintName
END
ALTER TABLE ?
DROP COLUMN IsDeleted
END'
但它给了我错误:
来自here 我知道了如何在不知道名称时删除约束 '@ConstraintName' 附近的语法不正确
【问题讨论】:
-
i) 为什么不在所有缺失的表中检查只创建 IsActive 列。 ii) 交换值。 iii) 正确验证一切是否正常。 iv) 然后简单地删除所有 IsDeleted 列。
-
啊!实际上,我希望对 db 中的所有表进行通用查询。我不想为每个表编写查询。有可能吗?
-
当然很有可能。你应该为它写一个通用的proc。但猜想它会使用游标和动态查询。我建议你自己试试,问你在哪里被击中。使用 INFORMATION_SCHEMA.TABLES 和 INFORMATION_SCHEMA.COLUMNS
-
@KumarHarsh-你能把代码给我看一下吗?
-
约束的名称必须是文字字符串,而不是在变量中。需要使用动态SQL来执行语句
EXEC (''ALTER TABLE ? DROP CONSTRAINT '' + @ConstraintName + '')
标签: sql sql-server