【问题标题】:SQL Cycles or Multiple Cascade PathsSQL 循环或多个级联路径
【发布时间】:2014-07-18 18:12:26
【问题描述】:

我遇到了循环问题。我正在为 IT 部门开发库存系统。 我有 3 张桌子的问题。

INVENTORY 表用于保存用户操作的历史记录,SOFTWAREHARDWARE 表用于存储库存。

我想为SOFTWAREHARDWARE 表保留一个唯一的inventoryID,当我使用ON CASCADE DELETE 时出现错误:

消息 1785,第 16 级,状态 0,第 1 行
在表“inventory”上引入 FOREIGN KEY 约束“fk_inventory_inventoryIDhw”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。

这是我的桌子。谁能帮帮我?如何解决问题。在网上找不到正确的解决方案。谢谢

CREATE TABLE inventory
( 
   statusID int,
   inventoryStatus nvarchar(15),
   inventoryID int,
   userName nvarchar(15),
   dates datetime2,
   inventoryAction nvarchar(10),
   categoryID int,

   CONSTRAINT pk_inventory_statusID PRIMARY KEY(statusID),
   CONSTRAINT fk_inventory_inventoryIDsw FOREIGN KEY(inventoryID) REFERENCES     software(inventoryID) ON DELETE CASCADE, 
   CONSTRAINT fk_inventory_inventoryIDhw FOREIGN KEY(inventoryID) REFERENCES hardware(inventoryID) ON DELETE CASCADE,
   CONSTRAINT fk_inventory_userName FOREIGN KEY(userName) REFERENCES users(userName) ON DELETE CASCADE
)
GO

CREATE TABLE hardware
(
   inventoryID int,
   hardwareID int,
   partNumber nvarchar(15),
   serial nvarchar(50),
   price float,
   supportID int,
   manufacturerID int,
   categoryID int,
   description nvarchar,
   deviceTypeID int,

   CONSTRAINT pk_hardware_inventoryID PRIMARY KEY(inventoryID),
   CONSTRAINT fk_hardware_categoryID FOREIGN KEY(categoryID) REFERENCES category(categoryID) ON DELETE CASCADE, 
   CONSTRAINT fk_hardware_supportID FOREIGN KEY(supportID) REFERENCES support(supportID) ON DELETE CASCADE,
   CONSTRAINT fk_hardware_deviceTypeID FOREIGN KEY(deviceTypeID) REFERENCES deviceType(deviceTypeID) ON DELETE CASCADE,
   CONSTRAINT fk_hardware_manufacturerID FOREIGN KEY(manufacturerID) REFERENCES manufacturer(manufacturerID) ON DELETE CASCADE,
)
GO

CREATE TABLE software
(
   inventoryID int,
   softwareID int,
   version nvarchar(10),
   name nvarchar(50),
   license nvarchar(50),
   price float,
   supportID int,
   categoryID int,
   manufacturerID int,
   programTypeID int,
   description nvarchar,

   CONSTRAINT pk_software_inventoryID PRIMARY KEY(inventoryID),
   CONSTRAINT fk_software_categoryID FOREIGN KEY(categoryID) REFERENCES category(categoryID) ON DELETE CASCADE, 
   CONSTRAINT fk_software_supportID FOREIGN KEY(supportID) REFERENCES support(supportID) ON DELETE CASCADE,
   CONSTRAINT fk_software_programTypeID FOREIGN KEY(programTypeID) REFERENCES     programType(programTypeID) ON DELETE CASCADE,
   CONSTRAINT fk_software_manufacturerID FOREIGN KEY(manufacturerID) REFERENCES     manufacturer(manufacturerID) ON DELETE CASCADE
)
GO

【问题讨论】:

  • Bad habits to kick : declaring VARCHAR without (length) - 您应该始终为您使用的任何varchar 列(例如description)、变量和参数提供长度
  • 你的外键关系都是错误的——它们应该从SoftwareHardwareInventory——但反过来也不行!您需要在SoftwareHardware 中都有一个InventoryId (FK) - 但您绝对不需要对Inventory 中的那些“子”表进行FK 约束!这就是导致您的ON DELETE CASCADE 设置循环的原因!
  • @marc_s 感谢您的评论。我将为 nvarchar 添加长度。关于PK和FK。我需要将它们设置为 FK 而不是在软件和硬件表中拥有库存 PK,而在库存表中它应该是 PK?我有点困惑。
  • 是的 - 你有 InventoryInventoryID 定义为 PK - 然后你有两个子表用于软和硬件,它们都充当“子”表(有点像OOP 中的对象继承),他们只需要引用Inventory.InventoryID - 就是这样,也不需要从库存到子表的 FK - 这太多了......
  • @marc_S 感谢您的帮助。现在好像工作了。由于现在有一棵正常的树,我没有错误。

标签: sql sql-server


【解决方案1】:

据我所知,与多个父表关联的同一列上的多个 fk 约束是不可行的。您可能需要另一个表来维护这种关系。请看:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=173589

【讨论】:

    【解决方案2】:

    将同一列作为与多个父表关联的多个外键约束的一部分会产生参照完整性问题。

    最好的方法是规范化设计并引入一个中间表来将关系保留为 2 个(或更多)关系。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-10
      • 1970-01-01
      • 1970-01-01
      • 2017-02-09
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多