从具有许多外键的表中删除

时间:2013-01-23 16:09:48

标签: sql sql-server-2008 tsql cascading-deletes

目前我正在使用树状结构的DB工作。基本上有一个顶级表,并且大约有10个表在该表上有外键。这些表中的每一个都有另外10个具有外键约束的表。现在我的目标是从主表中删除一些记录,并删除子孙,孙子等等。但是外键当然是一项艰巨的任务。

我已经搜索了一下并且使用级联删除检查了这个question,我想如果我只处理几张桌子就可以做到这一点。但是,在我目前的设置中,逐个更改100个表格仍然不太令人愉快。

因此,当询问是否有一种简单的方法可以在涉及多个表时删除具有外键的值。

由于我可以控制相对较小的数据库,因此查询效率和其他人删除值的风险并不是真正的问题。所以在所有表​​上应用级联删除可能很容易,但我也对完全不同的解决方案持开放态度(在microsoft server studio 2008中使用T-SQL)。

5 个答案:

答案 0 :(得分:2)

你看过这个吗?这个人根据数据库中的外键关系自动生成delete语句:

Generate Delete Statement From Foreign Key Relationships in SQL 2008?

我个人并不是它的忠实粉丝,但这是值得尝试的。

答案 1 :(得分:1)

我认为以不同方式执行此类操作的最佳方法是使用逻辑删除,使用名为“status”的列,或者控制该字段是否仍在您的程序逻辑下进行考虑。必须仅在顶级表上创建状态列。在SQL语句中,您插入“where status = 1”或类似的内容。

希望有所帮助,因为这是一个完全不同的方法。

答案 2 :(得分:1)

删除级联对于“主”表来说是一个很好的解决方案。

为避免手动更改所有表格,您可以使用一个脚本,如here所示,稍作更改(最后一行,按表名更改<yourTable>)。

select
  DropStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
      '].[' + ForeignKeys.ForeignTableName + 
      '] DROP CONSTRAINT [' + ForeignKeys.ForeignKeyName + ']; '
,  CreateStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
      '].[' + ForeignKeys.ForeignTableName + 
      '] WITH CHECK ADD CONSTRAINT [' +  ForeignKeys.ForeignKeyName + 
      '] FOREIGN KEY([' + ForeignKeys.ForeignTableColumn + 
      ']) REFERENCES [' + schema_name(sys.objects.schema_id) + '].[' +
  sys.objects.[name] + ']([' +
  sys.columns.[name] + ']) ON DELETE CASCADE; '
 from sys.objects
  inner join sys.columns
    on (sys.columns.[object_id] = sys.objects.[object_id])
  inner join (
    select sys.foreign_keys.[name] as ForeignKeyName
     ,schema_name(sys.objects.schema_id) as ForeignTableSchema
     ,sys.objects.[name] as ForeignTableName
     ,sys.columns.[name]  as ForeignTableColumn
     ,sys.foreign_keys.referenced_object_id as referenced_object_id
     ,sys.foreign_key_columns.referenced_column_id as referenced_column_id
     from sys.foreign_keys
      inner join sys.foreign_key_columns
        on (sys.foreign_key_columns.constraint_object_id
          = sys.foreign_keys.[object_id])
      inner join sys.objects
        on (sys.objects.[object_id]
          = sys.foreign_keys.parent_object_id)
        inner join sys.columns
          on (sys.columns.[object_id]
            = sys.objects.[object_id])
           and (sys.columns.column_id
            = sys.foreign_key_columns.parent_column_id)
    ) ForeignKeys
    on (ForeignKeys.referenced_object_id = sys.objects.[object_id])
     and (ForeignKeys.referenced_column_id = sys.columns.column_id)
 where (sys.objects.[type] = 'U')
  and (sys.objects.[name]  = '<yourTable>')

您在Management Studio查询窗口中复制第一列结果,执行,然后对第二列执行相同操作,并且完成后,您已完成。

答案 3 :(得分:0)

除非您愿意牺牲数据完整性,否则请使用T_SQL CASCADE DELETE选项。您可以创建“ALTER TABLE PARENT1 ADD FOREIGN KEY”并将您的方式复制并粘贴到安全的解决方案中。

这比开发和测试程序化解决方案花费的时间少得多,如果通过第三方程序(如Mgmt)发布删除语句,则不会执行该解决方案。工作室。

答案 4 :(得分:-1)

正如您引用的问题所述,您可以通过使用ON DELETE CASCADE自动处理删除。