如何使用相同的外键更新行而不更新它们

Posted

技术标签:

【中文标题】如何使用相同的外键更新行而不更新它们【英文标题】:How to update rows with the same foreign key without updating them all 【发布时间】:2019-10-05 06:03:06 【问题描述】:

我正在从事我的大学项目,我需要一些有关 Oracle 数据库的帮助。

我有两张桌子USERFORMACADEMICTRAINING

用户表单

Name           Null?    Type         
-------------- -------- ------------ 
USER_ID        NOT NULL NUMBER(5)    
FIRSTNAME      NOT NULL VARCHAR2(30) 
LASTNAME       NOT NULL VARCHAR2(30) 
EMAIL          NOT NULL VARCHAR2(60) 
BORN_DATE      NOT NULL DATE         
PHONE          NOT NULL VARCHAR2(20) 
ACCESSPASSWORD NOT NULL VARCHAR2(30) 

学术培训

Name           Null?    Type          
-------------- -------- ------------- 
AT_ID          NOT NULL NUMBER(5)     
START_DATE     NOT NULL DATE          
END_DATE       NOT NULL DATE          
INSTITUTION    NOT NULL VARCHAR2(100) 
COURSE         NOT NULL VARCHAR2(70)  
AT_DESCRIPTION          VARCHAR2(200) 

AT_ID 是在USER_ID 列上引用USERFORM 的外键。

我想知道是否有某种方法可以UPDATE 一行而不影响具有相同外键的其他行。

【问题讨论】:

要仅更新 1 行,您需要一个主键(或一组列)来仅定位 1 行。但是,如果您的数据库中没有这样的组合并且这只是 1 次练习,我想使用您正在使用的工具(例如 SQL Developer)是可行的。 很高兴知道,我需要一个具有更多增长能力的数据库,我会根据您的建议工作,谢谢! 您需要更新哪些表和列,是什么阻止了您这样做?还有,PL/SQL 代码是怎么来的? 我需要更新所有列上的ACADEMICTRAINING。我可以更新,但是,如果我使用其他行上使用的外键更新一行,则两者都会更新,这对我不利。基本上,现在我使用的是UPDATE academictraining SET ~columns and values~ WHERE at_id = userform.user_id。该外键意味着用户可以对其个人资料进行一项或多项学术培训,但我需要控制他正在更新的行。 【参考方案1】:

您的数据结构混乱,这让您感到困惑。你为什么将 user 列命名为 AT_ID。也没有声明外键。更好的方法是:

CREATE TABLE ACADEMICTRAINING (
    USER_ID NUMBER(5) NOT NULL FOREIGN KEY REFERENCES USERFORM(USER_ID),
    START_DATE DATE NOT NULL,         
    END_DATE  DATE NOT NULL       
    INSTITUTION VARCHAR2(100) NOT NULL
    COURSE VARCHAR2(70) NOT NULL 
    AT_DESCRIPTION VARCHAR2(200) 
);

您确实希望在表中有一个主键。在大多数情况下,我会推荐一个自动递增的主键。但这在 Oracle 12 之前的 Oracle 中很难自动完成。这样的列应该称为 ACADEMICTRAINING_ID

相反,您确实想要一个唯一的密钥。我不知道什么符合您的要求,但假设前两列不能重复(可能涉及更多列)。那么:

ALTER TABLE ACADEMICTRAINING ADD CONSTRAINT UNQ_ACADEMICTRAINING_2
    UNIQUE (USER_ID, START_DATE);

话虽如此,您在UPDATE 中需要的是一种选择哪个行的方法。像这样的:

UPDATE ACADEMICTRAINING
    SET . . .
    WHERE USER_ID = :USER_ID AND START_DATE = :START_DATE;

如果你有一个主键,它看起来像:

UPDATE ACADEMICTRAINING
    SET . . .
    WHERE ACADEMICTRAINING_ID = :ACADEMICTRAINING_ID;

【讨论】:

【参考方案2】:

试试这个。

 Update ACADEMICTRAINING
 set COURSE = 'BSC.CS'
 where AT_ID = (select USER_ID
                from USERFORM
                where FIRSTNAME = 'Ali'
                and LASTNAME = 'Ahmed'
                and PHONE = '44425183658558' );

【讨论】:

仍在更新具有相同外键的所有行,我想这样做或这样做没有任何区别WHERE AT_ID = USERFORM.USER_ID

以上是关于如何使用相同的外键更新行而不更新它们的主要内容,如果未能解决你的问题,请参考以下文章

当值相同时,如何单独显示行而不重叠

如何解决无法添加或更新子行:Spring JPA 中的外键约束失败错误?

django-rest-framework:如何更新嵌套的外键?我的更新方法甚至没有被调用

如何更新具有外键约束的数据库?

如何在 React Hooks 中向表中添加行而不重复?

如何根据ID更新另一张纸上的行而不用空白单元格覆盖?