oracle查询错误单行子查询returns多行

Error in oracle query Single row subquery returns more than one row

知道这里有什么问题吗?如何将以下 Sybase 查询转换为 Oracle。

Sybase 查询

Update student  s1 set s1.delay = (select  date1 - date2 from cource c where c.ID = c1.ID and 
c.value  ='On' and c.Act_id = 
select max(Act_id) from cource c2 where c2.Id = C.id and c2.value ='On')
from student s1, Cource c1
where c1.id = s1.id and 
c1.value ='On' and 
s1.status = 'active' and 
s1.currentprofile = s1.prevProfile

将上述查询转换为 oracle 后出现此错误“单行子查询 returns 多于一行”

Update student  s1 set s1.delay = (select (select  date1 - date2 from cource c where c.ID = c1.ID and             
c.value  ='On' and c.Act_id = 
select max(Act_id) from cource c2 where c2.Id = C.id and c2.value ='On')
from student s1, Cource c1
where c1.id = s1.id and 
c1.value ='On' and 
s1.status = 'active' and 
s1.currentprofile = s1.prevProfile)
Where Exists
(select (select  date1 - date2 from cource c where c.ID = c1.ID and c.value  ='On' and c.Act_id = 
select max(Act_id) from cource c2 where c2.Id = C.id and c2.value ='On')
from student s1, Cource c1
where c1.id = s1.id and 
c1.value ='On' and 
s1.status = 'active' and 
s1.currentprofile = s1.prevProfile)

您应该使用密钥保留视图来使用此查询进行更新。 Oracle 不允许在 Update 查询中使用 From 子句或使用 Correlated update 或 Merge with update only。

Post

相关更新:

UPDATE table1 t1
   SET (name, desc) = (SELECT t2.name, t2.desc
                         FROM table2 t2
                        WHERE t1.id = t2.id)
 WHERE EXISTS (
    SELECT 1
      FROM table2 t2
     WHERE t1.id = t2.id )

Sybase 查询(用于解释目的):

update student s1 
   set s1.delay = 
   (select (date1 -date2) 
      from cource c 
     where ****c.id = c1.id****(II)
       and c.value  ='On' 
       and c.Act_id = select max(Act_id) 
                        from cource c2 
                       where c2.Id = C.id 
                         and c2.value ='On')
  ****from student s1
     , cource c1****(I)
 where c1.id = s1.id 
   and c1.value ='On' 
   and s1.status = 'active' 
   and s1.currentprofile = s1.prevProfile;

在更新时我们可以看到两个主要情况,

  1. 首先,如果您看到 ****from student s1 , cource c1****(I) 部分,请确保您只更新 student table 中匹配 id 的行] 在 cource table 以及更多条件中,并且因为 Oracle 不允许直接在 update 语句的 from 子句中进行此类检查,所以它可以是替换为 exists 子句,可以在下面的 Oracle 查询中看到。

  2. 其次,上述 Sybase 查询中的 ****c.id = c1.id****(II) 部分确保它进一步仅通过 co-relateset 子句的数据提取到 ids 我们在第一步中发现,对于 Oracle,我们需要用正在更新的实际 table 替换,即 student 因为我们已经在第一步中用 exists 确定了什么ids 必须更新。

Oracle查询(实际查询):

update student s1 
   set s1.delay = (select (date1 - date2)
                     from cource c 
                    where c.id = s1.id 
                      and c.value  ='On' 
                      and c.act_id = select max(act_id) 
                                       from cource c2 
                                      where c2.Id = c.id 
                                        and c2.value ='On')
from student s1
where s1.status = 'active' 
  and s1.currentprofile = s1.prevprofile
  and exists (select 1 
                from cource c1
               where c1.id = s1.id 
                 and c1.value ='On');