Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Usenet -> c.d.o.misc -> Re: PL/SQL help needed

Re: PL/SQL help needed

From: Peter Schneider <pschneider_at_knuut.de>
Date: 25 Jul 1999 17:41:51 +0200
Message-ID: <m3lnc4n3cw.fsf@linus.dyndns.org>


jrg_at_idworld.net (James Garrison) writes:

> In my declare section I've defined a cursor. If I cut and paste the
> select statement into SQLPLUS it returns the correct number of rows.
> When I run my script opening the cursor with a FOR..IN..LOOP it
> returns every row in the table. I'm trying to use
> DBMS_OUTPUT.PUT_LINE statements to diagnose the error but am unable to
> get it to work correctly. Here's an example:
>
> Delcare
>
> CURSOR some_policies IS
> SELECT p.policy_number, p.policy_date_time
> FROM policy p, register_cur rc
> WHERE p.policy_number = rc.policy_number
> AND p.renewal_code = 1
> AND rc.status_1 = 5;
>
> **********Running the above select statement from the sql> command
> line correctly returns 2 rows*************
>
> BEGIN
> FOR policy_number IN some_policies LOOP
> UPDATE policy p
> SET non_renewal_reason = 'I'
> WHERE p.policy_number = policy_number
> AND P.policy_date_time = policy_date_time;
> COMMIT;
>
> *********This updates every row in the table!************
>
> DBMS_OUTPUT.PUT_LINE (SQL%ROWCOUNT || ' policies.');
>
> **This gives a row count of every row in the table! It should be 2***
>
> DBMS_OUTPUT.PUT_LINE ('Policy number ' || v_policy_no || ' .');
>
> ******How can I map policy number into v_policy_no????*************
>
> END LOOP;
> END;
>
> I have two problems: 1. Why is every row getting returned when I open
> the cursor. 2. How can I display the policy numbers affected by the
> update.
>
> TIA. Please help asap, let me know if you need more detail on the
> problem. The script is much longer than this snippet.

James,

the reason for the problem is your UPDATE statement:

UPDATE policy p
SET non_renewal_reason = 'I'
WHERE p.policy_number = policy_number
AND P.policy_date_time = policy_date_time;

policy_number and policy_date_time are not values that you fetched from your cursor, they are the original columns in your table; so your are comparing each of these columns to itself. This is the reason why all records in your policy table qualify for the update.

To get this to work, you should make the following modifications:

FOR policy_rec IN some_policies LOOP

   UPDATE policy p
   SET non_renewal_reason = 'I'
   WHERE p.policy_number = policy_rec.policy_number    AND P.policy_date_time = policy_rec.policy_date_time; END LOOP; If you use a cursor FOR-Loop, this implicitly declares a record loop variable with has your cursor%ROWTYPE. To use the fetched values, you need to use dot-notation to access individual components of the record variable.

It's also a good idea to follow a specific naming convention: use _cur for cursor declarations and _rec for record variables. This will make the code clearer, and it's less prone to naming conflicts.

To address your second problem: you could include

DBMS_OUTPUT.PUT_LINE('Updating policy number: ' || policy_rec.policy_number);

just before the UPDATE statement. But you should remove it in production code, because this is likely to cause a DBMS_OUTPUT buffer overflow if many loop iterations are performed.

HTH,
Peter

--
Peter Schneider
pschneider_at_knuut.de Received on Sun Jul 25 1999 - 10:41:51 CDT

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US