change select to select distinct
Main Topics
Browse All TopicsI am trying to correct this PL/SQL code (9i database) to update correctly. I am getting the error ORA-01427: single-row subquery returns more than one row because there can be the same value for rcrapp3_yr_in_coll_2 for different rcrapp1_pidms/rcrapp3_pidm
UPDATE rprlcrt
SET rprlcrt_clas_code =
(SELECT rcrapp3_yr_in_coll_2
FROM rcrapp3, rcrapp1
WHERE rcrapp1_curr_rec_ind = 'Y'
AND RCRAPP1_INFC_CODE = 'EDE'
AND RCRAPP1_INFC_CODE = RCRAPP3_INFC_CODE
AND RCRAPP1_SEQ_NO = RCRAPP3_SEQ_NO
AND rcrapp1_aidy_code = '0708'
AND rcrapp1_pidm = rcrapp3_pidm
AND rcrapp3_aidy_code = '0708'
AND rcrapp3_yr_in_coll_2 <> '0')
WHERE rprlcrt_cint_code IS NULL AND rprlcrt_cert_date IS NULL;
**************************
I guess I need a cursor to cycle thru the table RPRLCRT for each ID and update with the nested subquery. Here is my attempt to write a cursor. Please advise
CREATE OR REPLACE PROCEDURE update_loans_1
IS
v_rprlcrt_pidm NUMBER;
CURSOR c_select_pidm
IS
SELECT rprlcrt_pidm
FROM RPRLCRT
WHERE rprlcrt_cint_code IS NULL AND rprlcrt_cert_date IS NULL;
BEGIN
OPEN c_select_pidm;
LOOP
FETCH c_select_pidm
INTO v_rprlcrt_pidm;
SELECT rcrapp3_yr_in_coll_2
FROM rcrapp3, rcrapp1
WHERE rcrapp1_curr_rec_ind = 'Y'
AND RCRAPP1_INFC_CODE = 'EDE'
AND RCRAPP1_INFC_CODE = RCRAPP3_INFC_CODE
AND RCRAPP1_SEQ_NO = RCRAPP3_SEQ_NO
AND rcrapp1_aidy_code = '0708'
AND rcrapp1_pidm = rcrapp3_pidm
AND rcrapp3_aidy_code = '0708'
AND rcrapp3_yr_in_coll_2 <> '0'
AND rcrapp1_pidm = v_rprlcrt_pidm;
COMMIT;
EXIT WHEN c_select_pidm%NOTFOUND;
END LOOP;
END;
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
Well I would prefer the first approach, with the single update statement.
You get the ORA-01427 error because the subquery returns more than one rows.
sujit_kumar comment is basically correct: You don't seem to link the subquery with the external statement.
Weel I don't quite agree with the rcrapp1.<Foreign Key> = rprlcrt.<Primary Key> expression. It could be
rcrapp1.<Primary Key> = rprlcrt.<Foreign Key> as well, but the main idea is that you need a link there.
OK, lets start from the beginning. Try to give an example:
assume that you have two rows in rprlcrt, one has pidms=1 and the other pidms=2. The both have rprlcrt_cint_code IS NULL AND rprlcrt_cert_date IS NULL.
TO what value to you want to set rprlcrt_clas_code in each case?
If you can try the following in your production environment:
SELECT rprlcrt_clas_code,
(SELECT rcrapp3_yr_in_coll_2
FROM rcrapp3, rcrapp1
WHERE rcrapp1_curr_rec_ind = 'Y'
AND RCRAPP1_INFC_CODE = 'EDE'
AND RCRAPP1_INFC_CODE = RCRAPP3_INFC_CODE
AND RCRAPP1_SEQ_NO = RCRAPP3_SEQ_NO
AND rcrapp1_aidy_code = '0708'
AND rcrapp1_pidm = rcrapp3_pidm
AND rcrapp3_aidy_code = '0708'
AND rcrapp3_yr_in_coll_2 <> '0'
AND rcrapp3_pidm = rprlcrt_pidm) new_rprlcrt_clas_code
FROM rprlcrt
WHERE rprlcrt_cint_code IS NULL AND rprlcrt_cert_date IS NULL;
Does it run or do you get an error? If not does it return any value or do you get null?
I want to set it to the matching value in the rcrapp3 table "rcrapp3_yr_in_coll_2".
When I run your code in production I get 214 records, some have blank new_rprlcrt_clas_codes.
When I run
SELECT rcrapp3_yr_in_coll_2
FROM rcrapp3, rcrapp1
WHERE rcrapp1_curr_rec_ind = 'Y'
AND RCRAPP1_INFC_CODE = 'EDE'
AND RCRAPP1_INFC_CODE = RCRAPP3_INFC_CODE
AND RCRAPP1_SEQ_NO = RCRAPP3_SEQ_NO
AND rcrapp1_aidy_code = '0708'
AND rcrapp1_pidm = rcrapp3_pidm
AND rcrapp3_aidy_code = '0708'
AND rcrapp3_yr_in_coll_2 <> '0'
I get over 2400 records.
The key is "matching value in the rcrapp3 table" How do you match it?
Is it with "rcrapp3_pidm = rprlcrt_pidm" ? If yes then is it possible that you don't have a matching row for some cases?
Since you get 214 records with my query, then those rows have
prlcrt_cint_code IS NULL AND rprlcrt_cert_date IS NULL
Since some rows have null in new_rprlcrt_clas_codes, then for those rows there was no matching row found in rcrapp3 table. If that is acceptable, then your update statement should be (I think you already tried it):
UPDATE rprlcrt
SET rprlcrt_clas_code =
(SELECT rcrapp3_yr_in_coll_2
FROM rcrapp3, rcrapp1
WHERE rcrapp1_curr_rec_ind = 'Y'
AND RCRAPP1_INFC_CODE = 'EDE'
AND RCRAPP1_INFC_CODE = RCRAPP3_INFC_CODE
AND RCRAPP1_SEQ_NO = RCRAPP3_SEQ_NO
AND rcrapp1_aidy_code = '0708'
AND rcrapp1_pidm = rcrapp3_pidm
AND rcrapp3_aidy_code = '0708'
AND rcrapp3_yr_in_coll_2 <> '0'
AND rcrapp3_pidm = rprlcrt_pidm)
WHERE rprlcrt_cint_code IS NULL AND rprlcrt_cert_date IS NULL;
I've updated my cursor:
/* Formatted on 2007/08/01 11:58 (Formatter Plus v4.8.6) ECSU-Admin Computing */
CREATE OR REPLACE PROCEDURE update_loans_1
IS
v_rprlcrt_pidm NUMBER;
CURSOR c_select_pidm
IS
SELECT rprlcrt_pidm
FROM rprlcrt
WHERE rprlcrt_cint_code IS NULL AND rprlcrt_cert_date IS NULL;
BEGIN
OPEN c_select_pidm;
LOOP
FETCH c_select_pidm
INTO v_rprlcrt_pidm;
UPDATE rprlcrt
SET rprlcrt_clas_code =
(SELECT rcrapp3_yr_in_coll_2
FROM rcrapp3, rcrapp1
WHERE rcrapp1_curr_rec_ind = 'Y'
AND rcrapp1_infc_code = 'EDE'
AND rcrapp1_infc_code = rcrapp3_infc_code
AND rcrapp1_seq_no = rcrapp3_seq_no
AND rcrapp1_aidy_code = '0708'
AND rcrapp1_pidm = rcrapp3_pidm
AND rcrapp3_aidy_code = '0708'
AND rcrapp3_yr_in_coll_2 <> '0'
AND rcrapp1_pidm = v_rprlcrt_pidm);
EXIT WHEN c_select_pidm%NOTFOUND;
END LOOP;
CLOSE c_select_pidm;
END;
Why do you insist on the cursor? The single update statement should be faster and the code is simpler.
Anyway, if you want to use the cursor, your code is NOT correct:
You loop within the cursor, but you update the entire table:
UPDATE rprlcrt
SET rprlcrt_clas_code =
(SELECT rcrapp3_yr_in_coll_2
FROM rcrapp3, rcrapp1
WHERE rcrapp1_curr_rec_ind = 'Y'
AND rcrapp1_infc_code = 'EDE'
AND rcrapp1_infc_code = rcrapp3_infc_code
AND rcrapp1_seq_no = rcrapp3_seq_no
AND rcrapp1_aidy_code = '0708'
AND rcrapp1_pidm = rcrapp3_pidm
AND rcrapp3_aidy_code = '0708'
AND rcrapp3_yr_in_coll_2 <> '0'
AND rcrapp1_pidm = v_rprlcrt_pidm);
If you want to use the cursor then if rprlcrt_pidm is unique in rprlcrt change the update statement to:
Why do you insist on the cursor? The single update statement should be faster and the code is simpler.
Anyway, if you want to use the cursor, your code is NOT correct:
You loop within the cursor, but you update the entire table:
UPDATE rprlcrt
SET rprlcrt_clas_code =
(SELECT rcrapp3_yr_in_coll_2
FROM rcrapp3, rcrapp1
WHERE rcrapp1_curr_rec_ind = 'Y'
AND rcrapp1_infc_code = 'EDE'
AND rcrapp1_infc_code = rcrapp3_infc_code
AND rcrapp1_seq_no = rcrapp3_seq_no
AND rcrapp1_aidy_code = '0708'
AND rcrapp1_pidm = rcrapp3_pidm
AND rcrapp3_aidy_code = '0708'
AND rcrapp3_yr_in_coll_2 <> '0'
AND rcrapp1_pidm = v_rprlcrt_pidm)
WHERE rprlcrt_pidm = v_rprlcrt_pidm;
Another approach is (If rprlcrt_pidm is not unique)
CREATE OR REPLACE PROCEDURE update_loans_1
IS
v_rprlcrt_pidm NUMBER;
v_rowid ROWID;
CURSOR c_select_pidm
IS
SELECT rprlcrt_pidm, rowid
FROM rprlcrt
WHERE rprlcrt_cint_code IS NULL AND rprlcrt_cert_date IS NULL;
BEGIN
OPEN c_select_pidm;
LOOP
FETCH c_select_pidm
INTO v_rprlcrt_pidm, v_rowid;
UPDATE rprlcrt
SET rprlcrt_clas_code =
(SELECT rcrapp3_yr_in_coll_2
FROM rcrapp3, rcrapp1
WHERE rcrapp1_curr_rec_ind = 'Y'
AND rcrapp1_infc_code = 'EDE'
AND rcrapp1_infc_code = rcrapp3_infc_code
AND rcrapp1_seq_no = rcrapp3_seq_no
AND rcrapp1_aidy_code = '0708'
AND rcrapp1_pidm = rcrapp3_pidm
AND rcrapp3_aidy_code = '0708'
AND rcrapp3_yr_in_coll_2 <> '0'
AND rcrapp1_pidm = v_rprlcrt_pidm)
WHERE rowid = v_rowid;
EXIT WHEN c_select_pidm%NOTFOUND;
END LOOP;
CLOSE c_select_pidm;
END;
PS: And don't forget the commit at the end :)
Business Accounts
Answer for Membership
by: sujit_kumarPosted on 2007-08-01 at 07:06:23ID: 19608866
you need to write a corelated sub-query (So that the join returns single row inside the sub-query.
Something like this,
UPDATE rprlcrt
SET rprlcrt_clas_code =
(SELECT rcrapp3_yr_in_coll_2
FROM rcrapp3, rcrapp1
WHERE rcrapp1_curr_rec_ind = 'Y'
AND RCRAPP1_INFC_CODE = 'EDE'
AND RCRAPP1_INFC_CODE = RCRAPP3_INFC_CODE
AND RCRAPP1_SEQ_NO = RCRAPP3_SEQ_NO
AND rcrapp1_aidy_code = '0708'
AND rcrapp1_pidm = rcrapp3_pidm
AND rcrapp3_aidy_code = '0708'
AND rcrapp3_yr_in_coll_2 <> '0'
AND rcrapp1.<Foreign Key> = rprlcrt.<Primary Key> -- Change this as per your table structure.
)
WHERE rprlcrt_cint_code IS NULL AND rprlcrt_cert_date IS NULL;