Reputation: 1560
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'
Upvotes: 0
Views: 24670
Reputation: 2649
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)
E.g.
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'
Upvotes: 0
Reputation: 1111
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
Upvotes: 0
Reputation: 12485
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, e.g.:
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 );
Upvotes: 2
Reputation: 4551
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;
Upvotes: 0
Reputation: 2688
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'
Upvotes: 0