简体   繁体   中英

How can i resolve an ORA-01427 error (Single-row subquery returns more than one row)?

My query keeps returning an ORA-01427 error and I don't know how to resolve it.

update db1.CENSUS set (notes)
    =
    (
            select notes
            from db2.CENSUS cen
            where  db1.CENSUS.uid = cen.uid

    )
where headcount_ind = 'Y' and capture_FY = '2015'

You are getting the error because there exists more than one row in db2.CENSUS for at least value of uid . (There could be more.) You can figure out which values of uid are causing the issue by doing the following:

SELECT uid, COUNT(*)
  FROM db2.census
 GROUP BY uid
HAVING COUNT(*) > 1;

At that point you can do a number of things. You can delete the extra rows (maybe there aren't that many and you don't want them anyway) and update as in your original query, or you can use aggregation in the subquery you're using to update, eg:

update db1.CENSUS set (notes)
=
(
        select MAX(notes)
        from db2.CENSUS cen
        where  db1.CENSUS.uid = cen.uid

)
where headcount_ind = 'Y' and capture_FY = '2015';

In addition, with your query the way it is above, if there is not a corresponding value of notes in db2.CENSUS for some value of db1.CENSUS.uid , db1.CENSUS.notes will be set to NULL . Maybe that's the behavior you want? If not, you'll want something like the following:

UPDATE db1.census c1
   SET c1.notes = ( SELECT max(c2.notes)
                      FROM db2.census c2
                     WHERE c2.uid = c1.uid )
 WHERE c1.headcount_ind = 'Y'
   AND c1.capture_FY = '2015'
   AND EXISTS ( SELECT 1 FROM db2.census c2
                 WHERE c2.uid = c1.uid );

quick and dirty is

update db1.CENSUS  cen set cen.notes
    =
    (
            select MAX(notes)
            from db2.census census
            where  db1.DW_HRT_PERSONNEL_CENSUS.uid = census.uid

    )
where cen.headcount_ind = 'Y' and cen.capture_FY = '2015'

But, this probably does not do what you want. You have more than one note entered by one member of db1.DW_HRT_PERSONNEL_CENSUS.

In order to prevent this error you must know the relationships between the tables. Is this a one member of db1.DW_HRT_PERSONNEL_CENSUS maps to one note, or, more likely, one member of db1.DW_HRT_PERSONNEL_CENSUS can make many census notes? A more likely solution is:

CURSOR census_taker IS
SELECT db1.DW_HRT_PERSONNEL_CENSUS.UID
FROM  db1.DW_HRT_PERSONNEL_CENSUS;

For each census_taker in db1.DW_HRT_PERSONNEL_CENSUS LOOP
update db1.CENSUS  cen set cen.notes
    =
    (       select census.notes
            from db2.census census
            where  db1.DW_HRT_PERSONNEL_CENSUS.uid = census.uid
    )
where cen.headcount_ind = 'Y' 
and cen.capture_FY = '2015'
and cen.PERSONNEL_CENSUS_UID = census_taker.UID;

END LOOP;

The error means the subquery

select notes
  from db2.CENSUS census
 where db1.CENSUS.uid = census.uid

is returning more than one row with notes, while the UPDATE statement is expecting a single value to be returned.

Try the following.

update db1.CENSUS set (notes) = (select notes
                                   from db2.CENSUS census
                                        inner join db1.CENSUS db1Census on db1Census.uid = census.uid
                                  where db1Census.headcount_ind = 'Y'
                                    and db1Census.capture_FY = '2015')
 where headcount_ind = 'Y' and capture_FY = '2015'

This might also give you the same error if there are duplicate entries in db2.CENSUS for the uid and where headcount_ind = 'Y' and capture_FY = '2015'

You can also use analytics functions in your sub query such as

RANK() OVER (PARTITION BY census.uid ORDER BY 1 DESC)

and then choose the first rank or second rank

Your update query expects the inner query to resolve to a single record, but it is actually an array. If each result in the inner query has the same value, you can do this:

update A a set a.x = (select b.x from B b where ... and ROWNUM=1)

Eg

update db1.CENSUS set (notes)
    =
    (
            select notes
            from db2.CENSUS cen
            where  db1.CENSUS.uid = cen.uid
            and ROWNUM=1 

    )
where headcount_ind = 'Y' and capture_FY = '2015'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM