Home » SQL & PL/SQL » SQL & PL/SQL » PL/SQL - Help - Invalid Identifier (Oracle RDBMS 10.2.0.1)
PL/SQL - Help - Invalid Identifier [message #529262] Sun, 30 October 2011 10:33 Go to next message
carolmarol123
Messages: 11
Registered: October 2011
Junior Member
Here's the deal. I am trying to do an update with an anonymous PL/SQL block because it has been absolutely impossible to get by the infamous "Single-row subquery returns multiple rows" Whatever.

So this code below work... Obviously, I am updating it to a constant.. OK, duh.. Of course it works, it's easy.... Now, I really need to update it to a value in another table that is in my cursor. I believe that I probably need to declare a secondary cursor.

I'm just getting back in the DBA saddle, so I'm a little rusty.. just looking for some help here...

set serveroutput on;

DECLARE

numrows NUMBER := 0;
total NUMBER := 0;

CURSOR upd_record_cur IS SELECT m.rowid, m.swcm_cycle, t.newcycle, p.aprem_no from toad.fswcmas m, toad.ttp43425_load t, toad.fciaprem p
where (p.aprem_no = m.swcm_premise_no)
and (t.acctnum + 100 = m.swcm_cust)
and (t.curroute = p.aprem_route)
and (t.curcycle = p.aprem_cycle)
and p.aprem_application=4;

upd_rec upd_record_cur%rowtype;




BEGIN
FOR upd_rec IN upd_record_cur LOOP
update toad.fswcmas sw set sw.swcm_cycle = 8888
WHERE rowid = upd_rec.rowid;

total := total + 1;
numrows := numrows + 1;

IF (numrows >= 1000) THEN
COMMIT;
numrows := 0;
dbms_output.put_line('numrows is' || numrows);
END IF;



END LOOP;
COMMIT;
DBMS_OUTPUT.PUT_LINE('Updated ' || total || ' records from TOAD.FSWCMAS.');
END;

/

Not so good here

ORA-06550: line 20, column 53:
PL/SQL: ORA-00904: "TOAD"."TTP43425_LOAD"."NEWCYCLE": invalid identifier
ORA-06550: line 20, column 10:
PL/SQL: SQL Statement ignored

Doesn't work...



BEGIN
FOR upd_rec IN upd_record_cur LOOP
update toad.fswcmas sw set sw.swcm_cycle = toad.ttp43425_load.newcycle
WHERE rowid = upd_rec.rowid;

total := total + 1;
Re: PL/SQL - Help - Invalid Identifier [message #529264 is a reply to message #529262] Sun, 30 October 2011 10:58 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
It would be helpful if you followed Posting Guidelines - http://www.orafaq.com/forum/t/88153/0/311
Re: PL/SQL - Help - Invalid Identifier [message #529265 is a reply to message #529262] Sun, 30 October 2011 11:08 Go to previous messageGo to next message
flyboy
Messages: 1903
Registered: November 2006
Senior Member
carolmarol123 wrote on Sun, 30 October 2011 16:33
Here's the deal. I am trying to do an update with an anonymous PL/SQL block because it has been absolutely impossible to get by the infamous "Single-row subquery returns multiple rows" Whatever.

Facing this error means that you have design problem - one row is updated with multiple values - so the same update on same data may lead to different correct results. Maybe it would be better to take a step back, determine the relationship of all involved tables and define rules for obtaining the only one value for update of FSWCMAS.SWCM_CYCLE column.

To your code - without any background it is quite impossible to deduce what and how are you trying to achieve. However the error is self-explanatory, is not it?
Re: PL/SQL - Help - Invalid Identifier [message #529266 is a reply to message #529262] Sun, 30 October 2011 11:09 Go to previous messageGo to next message
Michel Cadot
Messages: 68765
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator
Please read OraFAQ Forum Guide and How to use [code] tags and make your code easier to read.
Make sure that lines of code do not exceed 80 characters when you format.
Indent the code, use code tags and align the columns in result.
Use the "Preview Message" button to verify.
Also always post your Oracle version, with 4 decimals.

Use SQL*Plus and copy and paste your session, the WHOLE session.

Regards
Michel
Re: PL/SQL - Help - Invalid Identifier [message #529267 is a reply to message #529266] Sun, 30 October 2011 11:48 Go to previous messageGo to next message
carolmarol123
Messages: 11
Registered: October 2011
Junior Member
So here's the goal. I need to update a "Master" table with values received from a spreadsheet. So, I loaded the table into TTP43425_LOAD...It has columns for a "Customer #", a "premise Number", a "current cycle", a "new cycle", a "current route" and a "new route".

The master tables have to be joined in this fashion- FCIAPREM - premise information for utilities, where the current route is equal to the current route in the spreadsheet, - to the FxxCMAS (the water or sewer customer master record).. then, the tables that need to be updated are .. the FxxCMAS records, a table called FCIMONTH (I have no idea what that is), the FCICMTR records (which are meter records for the utilities-- water, sewer, drainage, and refuse).

This is a new job for me, so the data model is still a little sketchy to me-- which is of course, VERY, VERY SCARY! And the model at this company is to do "data hits" outside of applications... again, scary....not good, OK? Got it.

So I am going to attach something, that will blow your mind. I have put a LOT of work into this. And if I could just get ONE update statement that would work, I would just.. be floored!

Also, I have been able to update the records with single UPDATE statements, but this takes too long, and it's inefficient and I don't want to hang out for 8 hours doing this in production!

[Updated on: Sun, 30 October 2011 11:52]

Report message to a moderator

Re: PL/SQL - Help - Invalid Identifier [message #529268 is a reply to message #529267] Sun, 30 October 2011 11:54 Go to previous messageGo to next message
carolmarol123
Messages: 11
Registered: October 2011
Junior Member
The attachment is unreadable. Sorry. It was a Word doc, but apparently Word Docs aren't an acceptable uploaded file type. So I saved it as text and it is completely unreadable.
Re: PL/SQL - Help - Invalid Identifier [message #529269 is a reply to message #529268] Sun, 30 October 2011 11:55 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
Please realize that we don't have your tables & we don't have your data.
Therefore we can't run, test or improve your posted SQL.
It would be helpful if you provided DDL (CREATE TABLE ...) for tables involved.
It would be helpful if you provided DML (INSERT INTO ...) for test data.
It would be helpful if you followed Posting Guidelines - http://www.orafaq.com/forum/t/88153/0/311
It would be helpful if you provided expected/desired results & a detailed explanation how & why the test data gets transformed or organized.
Re: PL/SQL - Help - Invalid Identifier [message #529270 is a reply to message #529267] Sun, 30 October 2011 12:14 Go to previous messageGo to next message
flyboy
Messages: 1903
Registered: November 2006
Senior Member
carolmarol123 wrote on Sun, 30 October 2011 17:48
This is a new job for me, so the data model is still a little sketchy to me-- which is of course, VERY, VERY SCARY! And the model at this company is to do "data hits" outside of applications... again, scary....not good, OK? Got it.

No, I have no idea what you expect from this forum at all, especially as you are contradicting yourself about failure/success of single statement. There are many methods of analyzing the execution and tuning SQL statement, which are described e.g. in Performance Guide sticky: http://www.orafaq.com/forum/t/84315/96705/ Doing anything in loop will probably not be better.

The only error message you posted in your initial post is clear enough; I would believe it rather than the description in your attachment.
Re: PL/SQL - Help - Invalid Identifier [message #529271 is a reply to message #529270] Sun, 30 October 2011 12:33 Go to previous messageGo to next message
carolmarol123
Messages: 11
Registered: October 2011
Junior Member
Instead of answering a question on specific code, can you answer this general question:

You have table A and table B. You join table A and table B in your cursor, can you update table A, with values from Table B?

Or are there other requirements in regards to declaring cursors? I have been searching for simple examples in doing this, but haven't found any. Does anyone out there have anything?

This is really a more general question than trying to get anyone to debug my code.
Re: PL/SQL - Help - Invalid Identifier [message #529272 is a reply to message #529271] Sun, 30 October 2011 12:37 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
UPDATE TABLEA A
SET COL3 = (SELECT COL5 FROM TABLEB B WHERE A.ID = B.ID);

above assumes both ID columns each are supported by UNIQUE index.
Re: PL/SQL - Help - Invalid Identifier [message #529273 is a reply to message #529272] Sun, 30 October 2011 12:44 Go to previous messageGo to next message
carolmarol123
Messages: 11
Registered: October 2011
Junior Member
Hmm... that won't work. The column I am trying to update is not unique whatsoever...

Here's the deal.

For customer number xxxxx (which is unique)
update new cycle to yyyy (which is not, and is in the temp table).

I am very rusty in my SQL, and should be able to do this in a single UPDATE statement. I REALIZE that, so hence, I have gone down the path of using anonymous PL/SQL to go one record at a time.. Maybe I am just going down the wrong path.
Re: PL/SQL - Help - Invalid Identifier [message #529274 is a reply to message #529271] Sun, 30 October 2011 12:44 Go to previous messageGo to next message
flyboy
Messages: 1903
Registered: November 2006
Senior Member
Yes, it should be possible. I would maybe use FOR UPDATE OF clause in cursor and update with WHERE CURRENT OF condition, but it should not matter.

Just curious: did you try to run the CURSOR LOOP without the UPDATE statement? As the error is in the line with FOR loop iterator, it should fail there as well.
Re: PL/SQL - Help - Invalid Identifier [message #529275 is a reply to message #529274] Sun, 30 October 2011 12:48 Go to previous messageGo to next message
carolmarol123
Messages: 11
Registered: October 2011
Junior Member
OK, great. Thank you for the ideas. I am going to go and "play" with those!
Re: PL/SQL - Help - Invalid Identifier [message #529276 is a reply to message #529274] Sun, 30 October 2011 12:51 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
>Hmm... that won't work. The column I am trying to update is not unique whatsoever...
Where did I state anything about the column being changed must be UNIQUE?

>For customer number xxxxx (which is unique)
This is possibly useful to know (& use?).
>update new cycle to yyyy (which is not, and is in the temp table).
What is "new cycle"?
From where is "yyyy" obtained?
As a general rule temp tables are NOT required by Oracle.

It would be helpful if you followed Posting Guidelines - http://www.orafaq.com/forum/t/88153/0/311
Re: PL/SQL - Help - Invalid Identifier [message #529277 is a reply to message #529272] Sun, 30 October 2011 12:52 Go to previous messageGo to next message
Barbara Boehmer
Messages: 9106
Registered: November 2002
Location: California, USA
Senior Member
Yes, you can update one table by selecting from a join of that table to other tables.

You could save yourself and us a lot of time and trouble by providing what has been asked for and using a copy and paste. The code that you provide could not produce the exact error message that you provided, so you are not posting exactly what you are running, which is why we need the copy and paste.

The first error that you provided regarding the invalid identifier generally occurs when a table or column name is misspelled or in the wrong case or there are insufficient privileges to the table and/or column. This is common when all the tables and code that accesses them are not in the same user schema.

The other error that you mentioned regarding too many rows occurs when it requires one row and your query provides more than one row, such as when you attempt to use = in comparing one value to multiple values.

I have tried to piece together what you have provided, demonstrating that the code that you provided works, then showing a simpler update statement. Notice the use of IN instead of = to avoid the too many rows error. This may not be the simplest query, but you need to get it to work without error first, then focus on tuning. Please notice the copy and paste method that I have used and try to provide that in the future.

-- examples of create table statements and insert statements for sample data that you should have provided:
TOAD@orcl_11gR2> CREATE TABLE ttp43425_load (
  2   ACCTNUM		   NUMBER(12),
  3   METERNUM		   VARCHAR2(12),
  4   ERTNUM		   VARCHAR2(12),
  5   PREMNUM		   NUMBER(12),
  6   PREMADDR		   VARCHAR2(35),
  7   CURCYCLE		   NUMBER(4),
  8   CURROUTE		   NUMBER(4),
  9   NEWCYCLE		   NUMBER(4),
 10   NEWROUTE		   NUMBER(4)
 11   )
 12  /

Table created.

TOAD@orcl_11gR2> INSERT INTO ttp43425_load
  2  VALUES (1, 'A', 'B', 1, 'C', 1, 1, 1, 1)
  3  /

1 row created.

TOAD@orcl_11gR2> CREATE TABLE fciaprem (
  2   ACC_RN		   NUMBER(10) NOT NULL,
  3   APREM_COMP	   NUMBER(2) NOT NULL,
  4   APREM_NO		   NUMBER(11) NOT NULL,
  5   APREM_APPLICATION    NUMBER(2) NOT NULL,
  6   APREM_CYCLE	   NUMBER(4),
  7   APREM_ROUTE	   NUMBER(4)
  8   )
  9  /

Table created.

TOAD@orcl_11gR2> INSERT INTO fciaprem
  2  VALUES (1, 1, 1, 4, 1, 1)
  3  /

1 row created.

TOAD@orcl_11gR2> CREATE TABLE fswcmas
  2    (swcm_cycle	 NUMBER,
  3  	swcm_premise_no  NUMBER,
  4  	swcm_cust	 NUMBER)
  5  /

Table created.

TOAD@orcl_11gR2> INSERT INTO fswcmas
  2  VALUES (1, 1, 101)
  3  /

1 row created.

TOAD@orcl_11gR2> COMMIT
  2  /

Commit complete.

TOAD@orcl_11gR2> SELECT * FROM fswcmas
  2  /

SWCM_CYCLE SWCM_PREMISE_NO  SWCM_CUST
---------- --------------- ----------
         1               1        101

1 row selected.


-- code that you provided (with commits commented out):
TOAD@orcl_11gR2> DECLARE
  2    numrows NUMBER := 0;
  3    total   NUMBER := 0;
  4    CURSOR upd_record_cur IS
  5    SELECT m.rowid, m.swcm_cycle, t.newcycle, p.aprem_no
  6    from   toad.fswcmas m, toad.ttp43425_load t, toad.fciaprem p
  7    where  (p.aprem_no = m.swcm_premise_no)
  8    and    (t.acctnum + 100 = m.swcm_cust)
  9    and    (t.curroute = p.aprem_route)
 10    and    (t.curcycle = p.aprem_cycle)
 11    and    p.aprem_application=4;
 12    upd_rec upd_record_cur%rowtype;
 13  BEGIN
 14    FOR upd_rec IN upd_record_cur LOOP
 15  	 update toad.fswcmas sw
 16  	 set	sw.swcm_cycle = 8888
 17  	 WHERE	rowid = upd_rec.rowid;
 18  	 total := total + 1;
 19  	 numrows := numrows + 1;
 20  	 IF (numrows >= 1000) THEN
 21  --      COMMIT;
 22  	   numrows := 0;
 23  	   dbms_output.put_line ('numrows is' || numrows);
 24  	 END IF;
 25    END LOOP;
 26  --  COMMIT;
 27    DBMS_OUTPUT.PUT_LINE ('Updated ' || total || ' records from toad.FSWCMAS.');
 28  END;
 29  /
Updated 1 records from toad.FSWCMAS.

PL/SQL procedure successfully completed.

TOAD@orcl_11gR2> SELECT * FROM fswcmas
  2  /

SWCM_CYCLE SWCM_PREMISE_NO  SWCM_CUST
---------- --------------- ----------
      8888               1        101

1 row selected.


-- rollback data prior to next run:
TOAD@orcl_11gR2> ROLLBACK
  2  /

Rollback complete.

TOAD@orcl_11gR2> SELECT * FROM fswcmas
  2  /

SWCM_CYCLE SWCM_PREMISE_NO  SWCM_CUST
---------- --------------- ----------
         1               1        101

1 row selected.


-- simpler method:
TOAD@orcl_11gR2> UPDATE toad.fswcmas sw
  2  SET    sw.swcm_cycle = 8888
  3  WHERE  sw.rowid IN
  4  	    (SELECT m.rowid
  5  	     from   toad.fswcmas m, toad.ttp43425_load t, toad.fciaprem p
  6  	     where  (p.aprem_no = m.swcm_premise_no)
  7  	     and    (t.acctnum + 100 = m.swcm_cust)
  8  	     and    (t.curroute = p.aprem_route)
  9  	     and    (t.curcycle = p.aprem_cycle)
 10  	     and    p.aprem_application=4)
 11  /

1 row updated.

TOAD@orcl_11gR2> SELECT * FROM fswcmas
  2  /

SWCM_CYCLE SWCM_PREMISE_NO  SWCM_CUST
---------- --------------- ----------
      8888               1        101

1 row selected.

TOAD@orcl_11gR2>

Re: PL/SQL - Help - Invalid Identifier [message #529278 is a reply to message #529273] Sun, 30 October 2011 12:57 Go to previous messageGo to next message
flyboy
Messages: 1903
Registered: November 2006
Senior Member
carolmarol123 wrote on Sun, 30 October 2011 18:44
For customer number xxxxx (which is unique)
update new cycle to yyyy (which is not, and is in the temp table).

What does this mean? If there are multiple values of new cycle in the temp table for one customer number, it is a problem.
Just example: if there are cycles 5, 10, 12 for a customer 'xxxxx' in the temp table, which one should be assigned to it in updated table? Least? Greatest? Average? Anything else? Why???
Re: PL/SQL - Help - Invalid Identifier [message #529279 is a reply to message #529277] Sun, 30 October 2011 13:06 Go to previous messageGo to next message
carolmarol123
Messages: 11
Registered: October 2011
Junior Member
Thank you for your reply. My goodness, that was thorough! Yes, I can get the update to work with a constant. I realize I am not abiding by the forum rules, but I just wanted a real quick "try this", type of answer.. which I got and now I need to spend a few hours "trying" that.

Note, that I am able to successfully update these records to satisfy the business requirements... with individual UPDATE statements built with the concatenate function. I could do that in production as well, but it will take too many hours and I'd rather find a more elegant and efficient solution.

Thank you all for your help, I will post back if I actually can achieve a better solution!
Re: PL/SQL - Help - Invalid Identifier [message #529306 is a reply to message #529279] Mon, 31 October 2011 01:12 Go to previous message
Littlefoot
Messages: 21825
Registered: June 2005
Location: Croatia, Europe
Senior Member
Account Moderator
If I understood what you said, it was that you managed to do "something" using a single UPDATE statement but it lasts too long. Therefore, you switched to a PL/SQL solution, hoping that it will be faster. Generally speaking, it will not. If possible, stay with SQL, a single UPDATE statement. If it is slow, it might require tuning.

Anyway, Barbara demonstrated how to do that.

Also, this (taken from your first message):
IF (numrows >= 1000) THEN
   COMMIT;
is a bad idea which often leads to an ORA-01555 (snapshot too old) error. Don't commit in a loop. Commit once, when the job is done.
Previous Topic: how can convert this number to date
Next Topic: Comparing Date Ranges Against All Rows in Same Table
Goto Forum:
  


Current Time: Mon Aug 11 19:45:46 CDT 2025