【问题标题】:Copy values from one column to other in all the tables in db将 db 中所有表中的值从一列复制到另一列
【发布时间】: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


【解决方案1】:

sp_MSforeachtable 是一个未记录但广泛使用的存储过程,它遍历数据库中的所有表。 ? 代表表名:

EXEC sp_MSforeachtable '
    IF COL_LENGTH(''?'',''IsDeleted'') IS NOT NULL
     BEGIN
     IF COL_LENGTH(''?'',''IsActive'') IS NOT NULL
      BEGIN
       UPDATE [dbo].[?]
       SET  [IsActive] = ~[IsDeleted]
      END
     ELSE
      BEGIN
       EXEC sp_RENAME ''[?].IsDeleted'', ''IsActive'', ''COLUMN''
       UPDATE [dbo].[?]
       SET  [IsActive] = ~[IsActive]
     END
     ALTER TABLE [dbo].[?] DROP COLUMN [IsDeleted]
    END
'

【讨论】:

  • 首先我从过程中删除了“[dbo]”,因为它正在创建对象名称为:dbo.[dbo].[table_name]。之后当我执行查询时,它给了我错误:Invalid column name 'IsActive'。
  • 当我在手动查询上面运行时。更新工作正常,但删除导致休闲错误:对象“DF_Visualization_Layouts_IsDeleted”依赖于列“IsDeleted”。 “Visualization_Layouts”是表名。并且 IsDeleted 列不在每个表中,这就是为什么我要检查 col 长度是否为空
  • 所以你在IsDeleted 列上有一个默认约束。您必须先将其删除,然后才能重命名。
  • DF_Visualization_Layouts_IsDeleted 是对 IsDeleted 列的约束
  • 我需要删除约束
猜你喜欢
  • 2016-05-05
  • 2011-01-31
  • 2012-02-18
  • 1970-01-01
  • 2015-06-07
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多