【问题标题】:Oracle Sql Update with values using foreign key?Oracle Sql 使用外键更新值?
【发布时间】:2010-11-26 11:13:39
【问题描述】:
Table 1:
Name, x1-X2, fk1, fk2.
Table 2:
K1(parent for table 1),X

如何更新表 1,其第二列 x1-x2 依赖于表 2 中的 fk1、fk2

Table1:
a,1.0,1,2
b,-3.0,2,3

Table 2
1,4.0
2,5.0
3,2.0

【问题讨论】:

  • 既然表2中有X1和X2,为什么还要fk1和fk2。你不能只用一个吗?
  • 因为表 1 有 2 行与表 2 映射
  • 那么,x1 和 x2 对应于哪一行?
  • 对不起,表 2 将只有一个 X 值
  • 你能展示一些示例数据吗?

标签: oracle


【解决方案1】:

不太确定我是否理解这个问题,参照完整性约束不会阻止您更新表。如果您需要在事务中做很多工作,您可以查看Deferred Constraints。你有机会澄清你的意思吗?

【讨论】:

    【解决方案2】:

    不确定到底是什么问题,也许你需要稍微改一下问题。

    一般来说,外键约束确保被引用的表中存在对应的行。

    当您使用外键更新行并尝试设置不指向此类主行的值时,您将立即或在您提交时收到错误(取决于何时强制执行约束,可以延期)。

    除此之外,该更新与任何其他更新没有什么不同。

    【讨论】:

      【解决方案3】:

      由于表 1 中的数据依赖于表 2 中的数据,您将无法直接“更新”表 1。

      您必须对表 2 执行更新,然后重新计算表 1。

      您可以在事务中执行此操作,也可以在表 2 上的触发器中执行此操作。

      另一种选择可能是让表一仅保存外键和名称,然后创建一个计算 X1-X2 值的视图。

      编辑

      在查看示例数据后,我认为您不能明确地将表 2 更新为表 1 的更新结果。

      例如,如果您将表 1 的第二列更新为 43,您如何知道设置表 2 的特定行的值(可能是 40 和 3、20 和 23 等)

      【讨论】:

      • 因为我正在处理已经创建的表。我正在寻找更新第一个表的查询...一旦表 table2 中有更新,我将从我的应用程序触发该查询
      • 由于表 1 是 (x1-x2),您现在将知道表 2 中特定行的 X 值是什么。如果您有 x1 和 x2 列,您可以这样做,但我不是当然你可以,否则。除非我错过了什么。
      • 对不起,应该说“你不会知道”
      • 我将更新表 2 并重新计算表 1 中所有受影响的行
      【解决方案4】:

      使用此设置:

      CREATE TABLE table2 (k NUMBER PRIMARY KEY, x NUMBER);
      CREATE TABLE table1 (
         NAME VARCHAR2(10) PRIMARY KEY, 
         diff NUMBER, 
         fk1 NUMBER REFERENCES table2, 
         fk2 NUMBER REFERENCES table2);
      

      以下更新将使用 table2 的值“刷新”列 table1.diff

      SQL> UPDATE (SELECT child.diff old_diff, parent2.x - parent1.x new_diff
        2            FROM table1 child
        3            JOIN table2 parent1 ON (child.fk1 = parent1.k)
        4            JOIN table2 parent2 ON (child.fk2 = parent2.k))
        5     SET old_diff = new_diff
        6   WHERE old_diff != new_diff
        7      OR (old_diff IS NULL AND new_diff IS NOT NULL)
        8      OR (old_diff IS NOT NULL AND new_diff IS NULL);
      

      只有需要更新的行才会被刷新(感谢 where 子句)。

      【讨论】:

      • 你真的可以这样更新表达式吗?我希望看到 UPDATE table1 SET diff = (SELECT ...) WHERE (...);并且 SELECT 将与您所拥有的类似 - 只有 new_diff - 最后一个三点将是与您所拥有的类似的条件。
      • 是的,乔纳森,因为我们只更新子表并且连接是保留键的(对于每个连接,table1 中的一行使用此连接最多指向 table2 的一行)。至少从 8i 开始就可以更新密钥保留的子查询了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      • 1970-01-01
      相关资源
      最近更新 更多