0

Any Idea what is the problem here ? How to convert the below Sybase query to Oracle.

Sybase query

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

After converting the above query to oracle I am getting this error "Single row sub query returns more than one row"

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)
3
  • 1
    By the way, cource should probably be course. Commented Sep 1, 2020 at 11:10
  • @William Robertson: You are right and the reason I didn't emphasize on it as it was not sure for me the scope of the changes interms of renaming. Commented Sep 1, 2020 at 11:13
  • 1
    Sample data, desired results, and an explanation of the logic would help. Commented Sep 1, 2020 at 11:14

2 Answers 2

1

You should use key presered view to update using this query. Oracle does not allow From clause in Update query Or use Correlated update or Merge with update only.

Post

Correlated update:

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 )
Sign up to request clarification or add additional context in comments.

Comments

0

Sybase query(for explain purpose):

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;

While updating there are two main conditions we can see,

  1. First, if you see the part ****from student s1 , cource c1****(I) this one makes sure you are only updating the rows from student table which has matching id in cource table along with some more conditions, AND because Oracle don't allow such type of checks directly in the from clause of the update statement, it can be replaced with exists clause which can be seen in the below Oracle query.

  2. Second, the part ****c.id = c1.id****(II) in above Sybase query makes sure it further only fetch the data for the set clause by co-relate to the ids we found in the first step and for Oracle this we need to replace with the actual table which is being updated i.e. student because we already make sure with exists in the first step what ids has to be updated.

Oracle Query(actual query):

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');

4 Comments

I have tried. Can you help on this resolve stackoverflow.com/questions/63775974/…
@sujai , I was already checking will take some time to answer but I don't understand the part where it does the sysdate - pd.exittime which is part of else clause of condition pd.exittime != null ..... does it make sense to do sysdate - null ? the result will be null only
it is typo mistake. I have asked to updated the question
@sujai, I answered there but don't know whether it worked or not ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.