C# 如何更新多个表中的同一列

C# 如何更新多个表中的同一列,c#,sql,C#,Sql,我想说明如何更新同一sql数据库中多个表中的同一列,但这些表通过一个表中的主键和另一个表中的forgin键的列相互关联。请帮助我更改主键从来都不是一件有趣的事:这就是为什么许多人喜欢使用自然键的原因。没有单一语句的标准SQL方法来实现这一点;相反,您必须插入具有新主键的主表行的副本,更新子表以引用新行,并删除原始行 可以在外键约束上指定所需内容。在这里检查,例如,检查 类似的内容也适用于您的sql方言 [CONSTRAINT symbol] FOREIGN KEY [id] (index_col

我想说明如何更新同一sql数据库中多个表中的同一列,但这些表通过一个表中的主键和另一个表中的forgin键的列相互关联。请帮助我更改主键从来都不是一件有趣的事:这就是为什么许多人喜欢使用自然键的原因。没有单一语句的标准SQL方法来实现这一点;相反,您必须插入具有新主键的主表行的副本,更新子表以引用新行,并删除原始行

可以在外键约束上指定所需内容。在这里检查,例如,检查

类似的内容也适用于您的sql方言

[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
  REFERENCES tbl_name (index_col_name, ...) ON UPDATE CASCADE

CREATE TABLE Parent(
  PID SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
  Name VARCHAR(20),
  PRIMARY KEY (PID)
);

CREATE TABLE Child(
  CID SMALLINT UNSIGNED NOT NULL PRIMARY KEY,
  PID SMALLINT UNSIGNED NOT NULL,
  FOREIGN KEY (PID) REFERENCES Parent (PID)
    ON UPDATE CASCADE
);

INSERT INTO PARENT (Name) VALUES ('Joe');
INSERT INTO PARENT (Name) VALUES ('Max');
INSERT INTO Child (CID, PID) VALUES (1, 1);
INSERT INTO Child (CID, PID) VALUES (2, 2);

SELECT * FROM Parent;
SELECT * FROM Child;

Parent             Child
+------+------+    +------+------+
| PID  | Name |    | CID  | PID  |
+------+------+    +------+------+
| 1    | Joe  |    | 1    | 1    |
+------+------+    +------+------+
| 2    | Max  |    | 2    | 2    |
+------+------+    +------+------+

UPDATE Parent SET PID='5000' WHERE PID='1';
SELECT * FROM Parent;
SELECT * FROM Child;

Parent             Child
+------+------+    +------+------+
| PID  | Name |    | CID  | PID  |
+------+------+    +------+------+
| 5000 | Joe  |    | 1    | 5000 |
+------+------+    +------+------+
| 2    | Max  |    | 2    | 2    |
+------+------+    +------+------+

在此示例中,可能会出现问题,具体取决于您的数据库系统。如果DB系统在某个点处于“AUTOINC模式”时未检查PID是否已分配,则autoincremnt值可能会达到5000,并且插入可能会失败,因为已经有一行具有此PID。取决于DB系统在指定自动递增时如何处理主键列的更改

您要回答的问题是带有级联更新的外键,如jitter的回答中所述。然而,与大多数设计考虑事项一样,如果返回并分析执行此类操作的潜在需求,您就不必问这个问题

虽然这是可行的,但这意味着随着时间的推移,数据库实体上的主键不可靠,这也意味着数据库可能需要在级联过程中执行大量工作(并且在执行此类更新时必须维护更多锁,这会增加阻塞的可能性)

关于随时间变化的可靠性,假设您有一个仓库维护帐户的历史余额:
AcctPK
EffectiveDate
Balance
,如果您在数据库中添加此作为另一个级联FK关系,那么现在您可能有大量行要级联更新。如果数据仓库位于单独的数据库中,则无法强制执行引用完整性,因此不会发生级联,现在您不再具有更改
AcctPK
之前帐户的连续性

假设您将数据导出给为每行提供某种信息的服务的供应商。现在,当供应商返回结果时,您无法匹配某些行,因为您发送的PK不再存在于您的数据中

在这两种情况下,您都可以通过保存PK更改的更改记录来解决此问题,但最终,这归结为(可能)PK选择不当


我强烈建议您重新考虑您的主键选择,如果它将经常改变。一种替代方法是使用代理
标识
或自动编号作为PK(而FK关系则基于此)。它永远不需要级联更新,您当前用作“自然”主键的另一个字段可以在正常的
更新中更改,而无需进行级联。

没有足够的信息来帮助您…请添加更多详细信息