【问题标题】: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。该外键意味着用户可以对其个人资料进行一项或多项学术培训,但我需要控制他正在更新的行。

标签: sql oracle join sql-update


【解决方案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
    猜你喜欢
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多