Sql 如何在加入表时进行更新
我有三张桌子 Stude_课程及其记录如下Sql 如何在加入表时进行更新,sql,oracle,join,sql-update,Sql,Oracle,Join,Sql Update,我有三张桌子 Stude_课程及其记录如下 empid ename emp_status emp_year 1 Raja 6 1 2 Poo 5 2 3 Bhasker 6 3 Student1表包含以下记录 empid ename emp_status 1 Raja 6 2 Poo 6 3 Bhasker 6 empid emp_ye
empid ename emp_status emp_year
1 Raja 6 1
2 Poo 5 2
3 Bhasker 6 3
Student1表包含以下记录
empid ename emp_status
1 Raja 6
2 Poo 6
3 Bhasker 6
empid emp_year
1 1
2 1
3 1
研究年度包含以下记录
empid ename emp_status
1 Raja 6
2 Poo 6
3 Bhasker 6
empid emp_year
1 1
2 1
3 1
我需要一个查询,以使用student1.emp_状态更新stude_course.emp_状态,并使用stude_year.emp_year更新stude_course.emp_year。为了更新这些记录,我使用了下面的查询
update
(
select sc.emp_status stud_emp_status,sc.emp_year stud_emp_year,s.emp_status stud_status,sy.emp_year stud_year from stude_course sc,student1 s,stud_year sy
where sc.empid = s.empid
and s.empid = sy.empid
and sc.empid = 2) st
set st.stud_emp_status = st.stud_status, st.stud_emp_year = st.stud_year;
我使用equi join连接了三个表,并为所有连接的表指定了别名st,为columnname指定了别名,然后尝试使用给定的别名表和列名更新值
预期结果:
empid ename emp_status emp_year
1 Raja 6 1
2 Poo 6 1
3 Bhasker 6 1
But i got error like
SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table
01779. 00000 - "cannot modify a column which maps to a non key-preserved table"
*Cause: An attempt was made to insert or update columns of a join view which
map to a non-key-preserved table.
*Action: Modify the underlying base tables directly.
您可以按如下方式直接更新该表:
UPDATE STUDE_COURSE SC
SET (SC.EMP_YEAR, SC.EMP_STATUS) =
(SELECT SY.EMP_YEAR, S1.STATUS FROM STUD_YEAR SY JOIN STUDENT1 S1
ON (S1.EMPID = SY.EMPID)
WHERE SY.EMPID = SC.EMPID)
WHERE SC.EMPID = 2;
MERGE INTO STUDE_COURSE SC
USING
(SELECT SY.EMP_YEAR, S1.EMP_STATUS, S1.EMPID FROM STUD_YEAR SY JOIN STUDENT1 S1
ON (S1.EMPID = SY.EMPID)) S
ON (SC.EMPID = S.EMPID)
WHEN MATCHED THEN
UPDATE SET SC.EMP_STATUS = S.EMP_STATUS, SC.EMP_YEAR = S.EMP_YEAR
或者您也可以按如下方式使用MERGE
:
UPDATE STUDE_COURSE SC
SET (SC.EMP_YEAR, SC.EMP_STATUS) =
(SELECT SY.EMP_YEAR, S1.STATUS FROM STUD_YEAR SY JOIN STUDENT1 S1
ON (S1.EMPID = SY.EMPID)
WHERE SY.EMPID = SC.EMPID)
WHERE SC.EMPID = 2;
MERGE INTO STUDE_COURSE SC
USING
(SELECT SY.EMP_YEAR, S1.EMP_STATUS, S1.EMPID FROM STUD_YEAR SY JOIN STUDENT1 S1
ON (S1.EMPID = SY.EMPID)) S
ON (SC.EMPID = S.EMPID)
WHEN MATCHED THEN
UPDATE SET SC.EMP_STATUS = S.EMP_STATUS, SC.EMP_YEAR = S.EMP_YEAR
干杯 您可以直接更新表格,如下所示:
UPDATE STUDE_COURSE SC
SET (SC.EMP_YEAR, SC.EMP_STATUS) =
(SELECT SY.EMP_YEAR, S1.STATUS FROM STUD_YEAR SY JOIN STUDENT1 S1
ON (S1.EMPID = SY.EMPID)
WHERE SY.EMPID = SC.EMPID)
WHERE SC.EMPID = 2;
MERGE INTO STUDE_COURSE SC
USING
(SELECT SY.EMP_YEAR, S1.EMP_STATUS, S1.EMPID FROM STUD_YEAR SY JOIN STUDENT1 S1
ON (S1.EMPID = SY.EMPID)) S
ON (SC.EMPID = S.EMPID)
WHEN MATCHED THEN
UPDATE SET SC.EMP_STATUS = S.EMP_STATUS, SC.EMP_YEAR = S.EMP_YEAR
或者您也可以按如下方式使用MERGE
:
UPDATE STUDE_COURSE SC
SET (SC.EMP_YEAR, SC.EMP_STATUS) =
(SELECT SY.EMP_YEAR, S1.STATUS FROM STUD_YEAR SY JOIN STUDENT1 S1
ON (S1.EMPID = SY.EMPID)
WHERE SY.EMPID = SC.EMPID)
WHERE SC.EMPID = 2;
MERGE INTO STUDE_COURSE SC
USING
(SELECT SY.EMP_YEAR, S1.EMP_STATUS, S1.EMPID FROM STUD_YEAR SY JOIN STUDENT1 S1
ON (S1.EMPID = SY.EMPID)) S
ON (SC.EMPID = S.EMPID)
WHEN MATCHED THEN
UPDATE SET SC.EMP_STATUS = S.EMP_STATUS, SC.EMP_YEAR = S.EMP_YEAR
干杯 当涉及连接时,我不确定您使用的更新子查询语法是否可行。我们可以尝试使用相关子查询编写更新:
UPDATE stude_course sc
SET
emp_status = (SELECT s.emp_status
FROM student1 s
INNER JOIN stud_year sy ON s.empid = sy.empid
WHERE sc.empid = s.empid),
emp_year = (SELECT sy.emp_year
FROM student1 s
INNER JOIN stud_year sy ON s.empid = sy.empid
WHERE sc.empid = s.empid)
WHERE
sc.empid = 2;
当涉及连接时,我不确定您使用的更新子查询语法是否可行。我们可以尝试使用相关子查询编写更新:
UPDATE stude_course sc
SET
emp_status = (SELECT s.emp_status
FROM student1 s
INNER JOIN stud_year sy ON s.empid = sy.empid
WHERE sc.empid = s.empid),
emp_year = (SELECT sy.emp_year
FROM student1 s
INNER JOIN stud_year sy ON s.empid = sy.empid
WHERE sc.empid = s.empid)
WHERE
sc.empid = 2;
无法修改映射到非键保留表的列
您尝试更新的列位于STUDE\u课程
表中。但是Oracle在查看了您的表结构之后,决定您的联接查询不能保证只包含STUDE\u课程中的每一行
如果向表中添加约束,以向Oracle保证查询中不会重复STUDE\u课程
中的行,则更新
将起作用
让我们走过去
首先,让我们重新创建您当前的情况:
设置表和数据
尝试更新(失败)
添加约束以告知Oracle联接不会复制目标表中的行
再试一次。。。(工程)
1行已更新
性能警告
这种语法并不常见(请参阅其他答案),我曾经遇到过这种奇怪的情况。结果是CBO优化了连接,结果集中的行顺序与实际更新的表中的行顺序不同。结果,Oracle到处更新块,多次接触每个块,导致性能非常差。通过目标表添加一个订单。rowid
修复了它。那真是令人头痛
无法修改映射到非键保留表的列
您尝试更新的列位于STUDE\u课程
表中。但是Oracle在查看了您的表结构之后,决定您的联接查询不能保证只包含STUDE\u课程中的每一行
如果向表中添加约束,以向Oracle保证查询中不会重复STUDE\u课程
中的行,则更新
将起作用
让我们走过去
首先,让我们重新创建您当前的情况:
设置表和数据
尝试更新(失败)
添加约束以告知Oracle联接不会复制目标表中的行
再试一次。。。(工程)
1行已更新
性能警告
这种语法并不常见(请参阅其他答案),我曾经遇到过这种奇怪的情况。结果是CBO优化了连接,结果集中的行顺序与实际更新的表中的行顺序不同。结果,Oracle到处更新块,多次接触每个块,导致性能非常差。通过目标表添加一个订单。rowid
修复了它。这真是一个令人头痛的问题。这也可以用一个子查询来编写<代码>(emp_status,emp_year)=(选择s.emp_status,sy.emp_yer from…)!这也可以通过单个子查询编写<代码>(emp_status,emp_year)=(选择s.emp_status,sy.emp_yer from…)!