2

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

我进行了一些搜索,并在使用级联删除时遇到了检查这个问题,我想如果我只处理几个表,这将起到作用。但是,在我目前的环境中,一张一张地改变 100 多张桌子仍然不是一件愉快的事。

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

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

4

5 回答 5

2

你看过这个吗?这家伙正在根据数据库中的外键关系自动生成删除语句:

从 SQL 2008 中的外键关系生成删除语句?

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

于 2013-01-23T16:27:32.593 回答
1

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

希望这会有所帮助,因为这是解决问题的完全不同的方法。

于 2013-01-23T16:14:55.620 回答
1

删除级联将是“主”表的一个很好的解决方案。

为避免手动更改所有表,您可以使用脚本,如在此处找到的稍作更改(最后一行,<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 查询窗口中复制第一列结果,执行,然后对第二列执行相同操作,瞧,大功告成。

于 2013-01-23T16:27:19.400 回答
0

Unless you are willing to sacrifice data integrity, utilize the T_SQL CASCADE DELETE option. You can create an "ALTER TABLE PARENT1 ADD FOREIGN KEY" and copy and paste your way to a safe solution.

This will take far less time than developing and testing a programmatic solution, which will not be executed if a delete statement is issued through a third-party program - like Mgmt. Studio.

于 2013-01-23T16:29:06.253 回答
-1

As was stated in the question you referenced you can automatically take care of the deletion through the use of the ON DELETE CASCADE.

于 2013-01-23T16:28:44.247 回答