For Update Cursor
Hi ,
Can you let me know what happen in this cursoe when we use for update?
CURSOR TRAN_CUR
IS
SELECT TRANSACTION_ID
,YEAR_MONTH_DT
,SOURCE_CD
,INVOICE
FROM
TRANSACTION_CONTROL
WHERE
NEXT_PROCESS = 'MAP'
FOR
UPDATE;
Thanks in advance,
Assuming that the cursor is written correctly SQL will lock each row as it is selected. The lock will remain until you do a COMMIT or a ROLLBACK. Normally Oracle will lock rows when you perform DML on them but FOR UPDATE causes the row to be locked when the select occurs.
FOR UPDATE also has the happy side effect of allowing use of the CURRENT OF predicate in select loops simplifying where clauses; when you say "WHERE CURRENT OF cursor_name" for a FOR UPDATE cursor you will only operate on the current row.
Now for the unhappy side effects. FOR UPDATE cursors run more slowly than normal cursors because it takes time and effort to lock the rows. Second (and worse) you are locked into one transaction for the entire cursor execution because performing a SELECT after a commit or rollback results in the FETCH OUT OF SEQUENCE error (this is not usually a problem but could result in running out of rollback segments or undo space for newer databases. Its unlikely these days but can happen). Finally, performing DML in one statement (as in insert into/select from) is often faster than performing the select loops with DML inside them anyway.
I wouldn't use FOR UPDATE unless I really needed the rows locked because of the performance hit.
Similar Messages
-
FOR UPDATE cursor is causing Blocking/ Dead Locking issues
Hi,
I am facing one of the complex issues regarding blocking / dead locking issues. Please find below the details and help / suggest me the best approach to ahead with that.
Its core Investment Banking Domain, in Our Day to day Business we are using many transaction table for processing trades and placing the order. In specific there are two main transaction table
1) Transaction table 1
2) Transaction table 2
These both the tables are having huge amount of data. In one of our application to maintain data integrity (During this process we do not want other users to change these rows), we have placed SELECT …………….. FOR UPDATE CURSOR on these two table and we have locked all the rows during the process. And we have batch jobs (shell scripts ) , calling this procedure , we will be running 9 times per day 1 hrs each start at 7:15AM in the morn finish it up in the eve 5PM . Let’s say. The reason we run the same procedure multiple times is, our business wants to know the voucher before its finalized. Because there is a possibility that order can be placed and will be updated/cancelled several times in a single day. So at the end of the day , we will be sending the finalized update to our client.
20 07 * * 1-5 home/bin/app_process_prc.sh >> home/bin/app1/process.out
20 08 * * 1-5 home/bin/app_process_prc.sh >> home/bin/app1/process.out
20 09 * * 1-5 home/bin/app_process_prc.sh >> home/bin/app1/process.out
20 10 * * 1-5 home/bin/app_process_prc.sh >> home/bin/app1/process.out
20 11 * * 1-5 home/bin/app_process_prc.sh >> home/bin/app1/process.out
20 12 * * 1-5 home/bin/app_process_prc.sh >> home/bin/app1/process.out
20 13 * * 1-5 home/bin/app_process_prc.sh >> home/bin/app1/process.out
20 14 * * 1-5 home/bin/app_process_prc.sh >> home/bin/app1/process.out
20 15 * * 1-5 home/bin/app_process_prc.sh >> home/bin/app1/process.out
20 16 * * 1-5 home/bin/app_process_prc.sh >> home/bin/app1/process.out
20 17 * * 1-5 home/bin/app_process_prc.sh >> home/bin/app1/process.out
Current Program will look like:
App_Prc_1
BEGIN
/***** taking the order details (source) and will be populate into the table ****/
CURSOR Cursor_Upload IS
SELECT col1, col2 … FROM Transaction table1 t 1, Source table 1 s
WHERE t1.id_no = t2.id_no
AND t1.id_flag = ‘N’
FOR UPDATE OF t1.id_flag;
/************* used for inserting the another entry , if theres any updates happened on the source table , for the records inserted using 1st cursor. **************/
CURSOR cursor_update IS
SELECT col1, col2 … FROM transaction table2 t2 , transaction table t1
WHERE t1.id_no = t2.id_no
AND t1.id_flag = ‘Y’
AND t1.DML_ACTION = ‘U’,’D’ -- will retrieve the records which are updated and deleted recently for the inserted records in transaction table 1 for that particular INSERT..
FOR UPDATE OF t1.id_no,t1.id_flag;
BLOCK 1
BEGIN
FOR v_upload IN Cursor_Upload;
LOOP
INSERT INTO transaction table2 ( id_no , dml_action , …. ) VALUES (v_upload.id_no , ‘I’ , … ) RETURNING v_upload.id_no INTO v_no -- I specify for INSERT
/********* Updating the Flag in the source table after the population ( N into Y ) N order is not placed yet , Y order is processed first time )
UPDATE transaction table1
SET id_FLAG = ‘Y’
WHERE id_no = v_no;
END LOOP;
EXCEPTION WHEN OTHER THEN
DBMS_OUTPUT.PUT_LINE( );
END ;
BLOCK 2
BEGIN -- block 2 starts
FOR v_update IN Cursor_Update;
LOOP;
INSERT INTO transaction table2 ( id_no ,id_prev_no, dml_action , …. ) VALUES (v_id_seq_no, v_upload.id_no ,, … ) RETURNING v_upload.id_no INTO v_no
UPDATE transaction table1
SET id_FLAG = ‘Y’
WHERE id_no = v_no;
END LOOP;
EXCEPTION WHEN OTHER THEN
DBMS_OUTPUT.PUT_LINE( );
END; -- block2 end
END app_proc; -- Main block end
Sample output in Transaction table1 :
Id_no | Tax_amt | re_emburse_amt | Activ_DT | Id_Flag | DML_ACTION
01 1,835 4300 12/JUN/2009 N I ( these DML Action will be triggered when ever if theres in any DML operation occurs in this table )
02 1,675 3300 12/JUN/2009 Y U
03 4475 6500 12/JUN/2009 N D
Sample output in Transaction table2 :
Id_no | Prev_id_no Tax_amt | re_emburse_amt | Activ_DT
001 01 1,835 4300 12/JUN/2009 11:34 AM ( 2nd cursor will populate this value , bcoz there s an update happened for the below records , this is 2nd voucher
01 0 1,235 6300 12/JUN/2009 09:15 AM ( 1st cursor will populate this record when job run first time )
02 0 1,675 3300 12/JUN/2009 8:15AM
003 03 4475 6500 12/JUN/2009 11:30 AM
03 0 1,235 4300 12/JUN/2009 10:30 AM
Now the issues is :
When these Process runs, our other application jobs failing, because it also uses these main 2 tranaction table. So dead lock is detecting in these applications.
Solutin Needed :
Can anyone suggest me , like how can rectify this blocking /Locking / Dead lock issues. I wants my other application also will use this tables during these process.
Regards,
Maranhmmm.... this leads to a warning:
SQL> ALTER SESSION SET PLSQL_WARNINGS='ENABLE:ALL';
Session altered.
CREATE OR REPLACE PROCEDURE MYPROCEDURE
AS
MYCOL VARCHAR(10);
BEGIN
SELECT col2
INTO MYCOL
FROM MYTABLE
WHERE col1 = 'ORACLE';
EXCEPTION
WHEN PIERRE THEN
NULL;
END;
SP2-0804: Procedure created with compilation warnings
SQL> show errors
Errors for PROCEDURE MYPROCEDURE:
LINE/COL ERROR
12/9 PLW-06009: procedure “MYPROCEDURE” PIERRE handler does not end in RAISE or RAISE_APPLICATION_ERROR
:) -
I have a 'for update' cursor defined with 'NOWAIT'. When soem of teh records that are supposed to be fetched by teh cursor are locked by another user for update..teh pl?SQL script returns
"ORA-00054: resource busy and acquire with NOWAIT specified" error.
If I declare teh cursor with out 'FOR UPDATE' or did NOT put 'NOWAIT' clause, teh script hangs waiting for teh records to be unlocked.
If the user opens a record in the front end (web app) and does not close it.. i can not run the script. Is theer any way to ignore those records that are locked by other users and query only ones that are available as part of the select statement in the cursor.Optimistic locking implies, essentailly, that you never lock the row. Instead, if you want to update the row, you check all the other columns of the row to see whether they have changed. In other words, you'd do a straight SELECT here and then when you went to UPDATE the data, you'd do
UPDATE <<change some column>>
WHERE col1=<<old col1 value>>
AND col2=<<old col2 value>>
AND ...If the update changed 1 row, you're set. If it changed 0 rows, someone had changed the underlying row since you SELECTED it, so you'd have to handle that condition. If it returned an error indicating that someone else had locked the row, you could handle that situation as well. If you just continue on, however, be sure that you know how to identify that this row wasn't updated so you can try to do the update the next time (assuming that makes sense).
If all your applications take the optimistic locking approach, you're pretty much guaranteed that no one else will have teh row locked, so you don't have to handle that state nearly as robustly.
Justin
Distributed Database Consulting, Inc.
www.ddbcinc.com -
How to update data when primary key is set through for update cursor
Dear friends,
I have tried to update data in the table through forms using cursor for update and i have given the plsql i have used please help me where i do mistake.
DECLARE CURSOR EMP IS
SELECT EMPNO,EMPNAME,FATHERNAME,COMMUNITY,SEX,BILLUNIT,BIRTHDATE,RLYJOINDATE,RETIREMENTDATE
FROM PRMAEMP WHERE BILLUNIT=:CTRL.BILLUNIT AND SERVICESTATUS='SR'ORDER BY DESIGCODE,SCALECODE
FOR UPDATE;
BEGIN
GO_BLOCK('EMP_DETAILS');
SYNCHRONIZE;
FOR I IN EMP
LOOP
I.BILLUNIT:=:EMP_DETAILS.BILLUNIT;
I.EMPNO:=:EMPNO;
I.EMPNAME:=:EMPNAME;
I.FATHERNAME:=:FATHERNAME;
I.COMMUNITY:=:COMMUNITY;
I.SEX:=:SEX;
I.BIRTHDATE:=:BIRTHDATE;
I.RLYJOINDATE:=:RLYJOINDATE;
I.RETIREMENTDATE:=:RETIREMENTDATE;
DOWN;
END LOOP;
COMMIT;
END;
your help is needed immediatelyDECLARE CURSOR ABC IS
SELECT EMPNO,
EMPNAME,
FATHERNAME,
COMMUNITY,
SEX,
BILLUNIT,
BIRTHDATE,
RLYJOINDATE,
RETIREMENTDATE
FROM PRMAEMP
WHERE BILLUNIT=:CTRL.BILLUNIT
AND SERVICESTATUS='SR'
ORDER BY DESIGCODE,SCALECODE
FOR UPDATE OF COMMUNITY;
V_EMPNO PRMAEMP.EMPNO%TYPE;
V_EMPNAME PRMAEMP.EMPNAME%TYPE;
V_FATHERNAME PRMAEMP.FATHERNAME%TYPE;
V_COMMUNITY PRMAEMP.COMMUNITY%TYPE;
V_SEX PRMAEMP.SEX%TYPE;
V_BILLUNIT PRMAEMP.BILLUNIT%TYPE;
V_BIRTHDATE PRMAEMP.BIRTHDATE%TYPE;
V_RLYJOINDATE PRMAEMP.RLYJOINDATE%TYPE;
V_RETIREMENTDATE PRMAEMP.RETIREMENTDATE%TYPE;
BEGIN
GO_BLOCK('EMP');
SYNCHRONIZE;
OPEN ABC;
LOOP
FETCH ABC INTO .... /*yOU NEED TO MENTION YOUR VARIABLES HERE*/;
UPDATE PRMAEMP
SET BILLUNIT= :EMP.BILLUNIT,
EMPNO= :EMPNO,
EMPNAME= :EMPNAME,
FATHERNAME= :FATHERNAME,
COMMUNITY= :COMMUNITY,
SEX= :SEX,
BIRTHDATE= :BIRTHDATE,
RLYJOINDATE= :RLYJOINDATE,
RETIREMENTDATE= :RETIREMENTDATE
WHERE CURRENT OF ABC;
EXIT WHEN ABC%NOTFOUND;
END LOOP;
CLOSE ABC;
END;
COMMIT;
END;Cheers
Sarma. -
Hi all,
Can any one please tell me,what is main use of for update cursor.in which case we are using this clause.with simple example can any one please explain.
Thanks,
K.venkata Sanjeeva Rao.user13483989 wrote:
Can any one please tell me,what is main use of for update cursor.in which case we are using this clause.with simple example can any one please explain.Where you are looping through data for some reason and want to update the current row.
Simple example...
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17-DEC-1980 00:00:00 800 20
7499 ALLEN SALESMAN 7698 20-FEB-1981 00:00:00 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-1981 00:00:00 1250 500 30
7566 JONES MANAGER 7839 02-APR-1981 00:00:00 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-1981 00:00:00 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-1981 00:00:00 2850 30
7782 CLARK MANAGER 7839 09-JUN-1981 00:00:00 2450 10
7788 SCOTT ANALYST 7566 19-APR-1987 00:00:00 3000 20
7839 KING PRESIDENT 17-NOV-1981 00:00:00 5000 10
7844 TURNER SALESMAN 7698 08-SEP-1981 00:00:00 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-1987 00:00:00 1100 20
7900 JAMES CLERK 7698 03-DEC-1981 00:00:00 950 30
7902 FORD ANALYST 7566 03-DEC-1981 00:00:00 3000 20
7934 MILLER CLERK 7782 23-JAN-1982 00:00:00 1300 10
14 rows selected.
SQL> ed
Wrote file afiedt.buf
1 declare
2 cursor cur_emp is
3 select empno, ename, comm
4 from emp
5 for update;
6 begin
7 for e in cur_emp
8 loop
9 dbms_output.put_line('('||e.empno||') '||e.ename);
10 if e.comm is null then
11 update emp
12 set comm = 0
13 where current of cur_emp;
14 dbms_output.put_line('-- Commission reset to 0');
15 else
16 dbms_output.put_line('-- Commission: '||e.comm);
17 end if;
18 end loop;
19* end;
SQL> /
(7369) SMITH
-- Commission reset to 0
(7499) ALLEN
-- Commission: 300
(7521) WARD
-- Commission: 500
(7566) JONES
-- Commission reset to 0
(7654) MARTIN
-- Commission: 1400
(7698) BLAKE
-- Commission reset to 0
(7782) CLARK
-- Commission reset to 0
(7788) SCOTT
-- Commission reset to 0
(7839) KING
-- Commission reset to 0
(7844) TURNER
-- Commission: 0
(7876) ADAMS
-- Commission reset to 0
(7900) JAMES
-- Commission reset to 0
(7902) FORD
-- Commission reset to 0
(7934) MILLER
-- Commission reset to 0
PL/SQL procedure successfully completed.
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17-DEC-1980 00:00:00 800 0 20
7499 ALLEN SALESMAN 7698 20-FEB-1981 00:00:00 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-1981 00:00:00 1250 500 30
7566 JONES MANAGER 7839 02-APR-1981 00:00:00 2975 0 20
7654 MARTIN SALESMAN 7698 28-SEP-1981 00:00:00 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-1981 00:00:00 2850 0 30
7782 CLARK MANAGER 7839 09-JUN-1981 00:00:00 2450 0 10
7788 SCOTT ANALYST 7566 19-APR-1987 00:00:00 3000 0 20
7839 KING PRESIDENT 17-NOV-1981 00:00:00 5000 0 10
7844 TURNER SALESMAN 7698 08-SEP-1981 00:00:00 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-1987 00:00:00 1100 0 20
7900 JAMES CLERK 7698 03-DEC-1981 00:00:00 950 0 30
7902 FORD ANALYST 7566 03-DEC-1981 00:00:00 3000 0 20
7934 MILLER CLERK 7782 23-JAN-1982 00:00:00 1300 0 10
14 rows selected.Though, of course this is a pointless example as a simple single update would achieve the same. It's more useful if there are 'other things' you need to do with the data that would exceed the capabilities of just using SQL. Personally I've had little need to use this sort of construct. -
For Update Query with Wait Clause from ORACLE Forms
Hi
We are using Oracle Forms 10g running with 10g database 10.2.0.1.0. We happend to see a query which is getting generated in AWR report like Select rowid, all_columns from TableName for Update of C1 Nowait. But no such query is really written in forms and we are aware that, Any query prefixed with rowid is definitely executing from Forms. But how the ForUpdate and Nowait clause is appended to the query.
We have checked the following properties in the database Block
*1) Locking Mode is set to Automatic*
*2) Update Changed Columns only is set to YES*
*3) Query all records is set to No (Though this particular property may not be relevant to the issue)*
What is the property or setting which might trigger such a query from ORACLE Forms with ForUpdate and Nowait clause.
Any ideas/suggestions on why such behaviour. Please have a healthy discussion on this. Thanks in advance.Why have you started another thread on the same thing?
FOR UPDATE cursor is causing Blocking/ Dead Locking issues
Just use one thread to avoid confusion.
The fact that nobody has answered on the other thread for a couple of days could be to do with it being the weekend and most people are not at work.
Either be patient or, if it's more "urgent" than that, raise a SR/Tar with Oracle metalink. -
Hi All,
Whenever i am compiling the form in 10g builder it is giving the following error.
error 1705 table specified by a cursor not updatable if cursor specification has union or order_by
For ex i am writing like this
declare
cursor c1 is select * from emp
union all
select * from dept
for update of sal;
begin
for i in c1
loop
update emp
set sal = sal*2
where current of c1;
end loop;
end;
Thanks and regards
Nagaraj TeliThe error message explains the situation.
One of the nicer side-effects of using a FOR UPDATE cursor is that it allows you to use the WHERE CURRENT OF clause in DML statements to avoid coding a WHERE clause. Because WHERE CURRENT OF is probably supported through ROWID use, you can't use multiple tables in the query since the ROWID could come from a different table.
Try eliminating the FOR UPDATE clause and using keys to control the update. You won't get the row locking, but the operation should be faster and should still work. -
I'm trying to issue a SELECT ... FROM ... FOR UPDATE, and under specific verified conditions runs an UPDATE (where the current is positioned!).
The error code I get is:
ORA-01002: Fetch out of sequence.
Here you are my code:
/////////////////////START
import java.sql.*;
import oracle.jdbc.*;
import oracle.sql.*;
public class SelForUpdDin{
static{
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
catch(Exception e){e.printStackTrace();}
// Queries and cursor name
public static void main (java.lang.String[] args){
String cursorName = null;
int codice = 0;
String cognome = null;
String job = null;
int manager = 0;
java.sql.Date dataAss = null;
int salario = 0;
int commissioni = 0;
int reparto = 0;
String rowid = null;
String sqlSelect = "SELECT empno, ename, "+
"job, mgr, hiredate, sal, comm, deptno, ROWID "+
"FROM scott.emp FOR UPDATE";
String sqlUpdate = "UPDATE scott.emp SET comm = ? WHERE ROWID = ? ";
try {
Connection con = DriverManager.getConnection("jdbc:Oracle:oci8:@","system","manager");
// Esecuzione della SELECT e produzione del RESULT SET
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sqlSelect);
PreparedStatement ps = con.prepareStatement(sqlUpdate);
while (rs.next()) {
codice = rs.getInt(1);
cognome = rs.getString(2);
job = rs.getString(3);
manager = rs.getInt(4);
dataAss = rs.getDate(5);
salario = rs.getInt(6);
commissioni = rs.getInt(7);
reparto = rs.getInt(8);
rowid = rs.getString(9);
// Applicazione della business logic
if (reparto == 30)
{ System.out.println (cognome + " in dept= "+ reparto +
" with salary=" + salario + " has a commission= " +
commissioni);
int newcomm = 5555;
ps.setInt(1,newcomm);
ps.setString(2,rowid);
ps.executeUpdate();
else
{ System.out.println (cognome + " in dept= "+ reparto +
" with salary=" + salario + " has a commission= " + commissioni);
} // if - else
} // end while
rs.close();
ps.close();
stmt.close();
catch(Exception e)
e.printStackTrace();
} // end main()
} // end class
//PS.
//Many thanks to Bachar and Elangovan that ansewerd me to my previous posting and addressed me towards the right solutionHi
The documentation gives following explanation for the error :
ORA-01002 fetch out of sequence
Cause: In a host language program, a FETCH call was issued out of sequence. A successful parse-and-execute call must be issued before a fetch. This can occur if an attempt was made to FETCH from an active set after all records have been fetched. This may be caused by fetching from a SELECT FOR UPDATE cursor after a commit. A PL/SQL cursor loop implicitly does fetches and may also cause this error.
Action: Parse and execute a SQL statement before attempting to fetch the data.
In your program you should set auto commit to false as follows :
con.setAutoCommit(false);
Do this before executing the SELECT FOR UPDATE sql query.
At the end of program you can commit to save the updations as follows:
con.commit();
This should solve the problem.
Chandar -
Performance of using a Select For Update vs a correlated subquery
I was wondering wether or not it is more effecient to use the
Select ... For Update (with a cursor etc.) versus a correlated
subquery.
I can accomplish the same thing with either however performance
at our site is an issue.Use select for update cursor as that is faster as it updates
based on the rowid. One thing to keep in mind is that rowid is
session specific and the rows to be updated get locked so that
nobody else can update them till the lock is released. I have
had very good performance results with these cursors.
Good luck !
Sudha -
FOR LOOP cursor that updates table A based on a value in table B
Hi,
I need a FOR LOOP cursor that scans and updates all pro-rata column in table EMPLOYEE(child) based on what pay classification all employees are on in the CLASSIFICATION(parent) table.
DECLARE
BEGIN
IF employee.emp_type = 'FT' THEN
UPDATE employee
SET employee.pro_rata = ((classification.yearly_pay/52)*52)
WHERE employee.empid = v_empid AND classification.class_id = employee.class_id;
END IF;
IF employee.emp_type = 'PT1' THEN
UPDATE employee
SET employee.pro_rata = ((classification.yearly_pay/39)*52)
WHERE employee.empid = v_empid AND classification.class_id = employee.class_id;
END IF;
IF employee.emp_type = 'PT2' THEN
UPDATE employee
SET employee.pro_rata = ((classification.yearly_pay/21)*52)
WHERE employee.empid = v_empid AND classification.class_id = employee.class_id;
END IF;
END;
How do I create a cursor that cuts across these two table
See tables and data
CREATE TABLE CLASSIFICATION(
CLASS_ID VARCHAR2(6) NOT NULL,
CLASS_TYPE VARCHAR2(10),
DESCRIPTION VARCHAR2(30) NOT NULL,
YEARLY_PAY NUMBER(8),
HOURLY_RATE NUMBER,
WEEKDAY_OVER_TIME NUMBER,
WEEKEND_OVER_TIME NUMBER,
CONSTRAINT PK_CLASS_ID PRIMARY KEY (CLASS_ID));
INSERT INTO CLASSIFICATION VALUES('PR1','PERMANENT','MANAGER',45000,'','',NULL);
INSERT INTO CLASSIFICATION VALUES('PR2','PERMANENT','ADMIN ASSISTANT',22000,'',1.5,NULL);
INSERT INTO CLASSIFICATION VALUES('PR3','PERMANENT','CONTROLLER',32000,'',1.5,NULL);
INSERT INTO CLASSIFICATION VALUES('PR4','PERMANENT','CASH OFFICER',22000,'',1.5,NULL);
INSERT INTO CLASSIFICATION VALUES('PR5','PERMANENT','CLEANERS',16000,'',1.5,NULL);
INSERT INTO CLASSIFICATION VALUES('PR6','PERMANENT','ADMIN OFFICER',22000,'',1.5,NULL);
INSERT INTO CLASSIFICATION VALUES('PR7','PERMANENT','WAREHOUSE ATTENDANT',20000,'',1.5,NULL);
INSERT INTO CLASSIFICATION VALUES('PR8','PERMANENT','WINDOWS DRESSER',22000,'',1.5,NULL);
INSERT INTO CLASSIFICATION VALUES('PR9','PERMANENT','DIRECTOR',60000,'','',NULL);
INSERT INTO CLASSIFICATION VALUES('PR10','PERMANENT','DEPUTY DIRECTOR',52000,'','',NULL);
INSERT INTO CLASSIFICATION VALUES('PR11','PERMANENT','SALES ASSISTANT',21000,'',1.5,NULL);
INSERT INTO CLASSIFICATION VALUES('TEMP2','TEMP STAFF','ADMIN ASSISTANT','',16.50,'',NULL);
INSERT INTO CLASSIFICATION VALUES('TEMP3','TEMP STAFF','CONTROLLER','',29.00,'',NULL);
INSERT INTO CLASSIFICATION VALUES('TEMP4','TEMP STAFF','CASH OFFICER','',19.00,'',NULL);
INSERT INTO CLASSIFICATION VALUES('TEMP5','TEMP STAFF','CLEANERS','',10.00,'',NULL);
INSERT INTO CLASSIFICATION VALUES('TEMP6','TEMP STAFF','ADMIN OFFICER','',20.00,'',NULL);
INSERT INTO CLASSIFICATION VALUES('TEMP7','TEMP STAFF','WAREHOUSE ATTENDANT','',18.00,'',NULL);
INSERT INTO CLASSIFICATION VALUES('TEMP8','TEMP STAFF','WINDOWS DRESSER','',18.50,'',NULL);
INSERT INTO CLASSIFICATION VALUES('TEMP11','TEMP STAFF','SALES ASSISTANT','',16.00,'',NULL);
CREATE TABLE EMPLOYEE(
EMPID NUMBER(5) NOT NULL,
SURNAME VARCHAR2(30) NOT NULL,
FNAME VARCHAR2(30) NOT NULL,
GENDER CHAR(1) NOT NULL,
DOB DATE NOT NULL,
EMP_TYPE VARCHAR2(20) NOT NULL,
ANNUAL_WEEKS_REQD NUMBER(2),
PRO_RATA_WAGES NUMBER(7,2),
HOLIDAY_ENTLMENT NUMBER(2),
SICK_LEAVE_ENTLMENT NUMBER(2),
HIRE_DATE DATE NOT NULL,
END_DATE DATE,
ACCNO NUMBER(8) NOT NULL,
BANKNAME VARCHAR2(20) NOT NULL,
BRANCH VARCHAR2(20) NOT NULL,
ACCOUNTNAME VARCHAR2(20),
CLASS_ID VARCHAR2(6),
CONSTRAINT CK_HIRE_END CHECK (HIRE_DATE < END_DATE),
CONSTRAINT CK_HIRE_DOB CHECK (HIRE_DATE >= ADD_MONTHS(DOB, 12 * 18)),
CONSTRAINT CK_EMP_TYPE CHECK (EMP_TYPE IN ('FT','PT1','PT2','PT3','HOURLY')),
CONSTRAINT CK_EMP_GENDER CHECK (GENDER IN ('M','F')),
CONSTRAINT FK_EMP_CLASS FOREIGN KEY (CLASS_ID) REFERENCES CLASSIFICATION(CLASS_ID),
CONSTRAINT PK_EMP PRIMARY KEY (EMPID));
CREATE SEQUENCE SEQ_EMPID START WITH 1;
INSERT INTO EMPLOYEE VALUES(
SEQ_EMPID.NEXTVAL,'RICHARD','BRANDON','M','25-DEC-1966','FT',52,22000.00,28,14,'10-JAN-2005',NULL,90823227,'NATWEST','BROMLEY','DEPOSIT','PR2');
INSERT INTO EMPLOYEE VALUES(
SEQ_EMPID.NEXTVAL,'BOYCE','CODD','M','15-JAN-1972','PT1','','','','','12-JAN-2005',NULL,72444091,'LLOYDS','KENT','CURRENT','PR8');
INSERT INTO EMPLOYEE VALUES(
SEQ_EMPID.NEXTVAL,'ALHAJA','BROWN','F','20-MAY-1970','HOURLY','','','','','21-JUN-2000',NULL,09081900,'ABBEY','ESSEX','CURRENT','TEMP2');
INSERT INTO EMPLOYEE VALUES(
SEQ_EMPID.NEXTVAL,'RON','ATKINSON','M','10-AUG-1955','PT3','','','','','12-JAN-2005','26-MAR-2006',01009921,'HALIFAX','KENT','SAVINGS','PR6');
INSERT INTO EMPLOYEE VALUES(
SEQ_EMPID.NEXTVAL,'CHAMPI','KANE','F','01-JAN-1965','PT2','','','','','12-JAN-2004',NULL,98120989,'HSBC','ILFORD','CURRENT','PR4');
INSERT INTO EMPLOYEE VALUES(
SEQ_EMPID.NEXTVAL,'NED','VED','M','15-JAN-1980','HOURLY','','','','','29-DEC-2005',NULL,90812300,'WOOLWICH','LEWISHAM','CURRENT','TEMP6');
INSERT INTO EMPLOYEE VALUES(
SEQ_EMPID.NEXTVAL,'JILL','SANDER','F','22-MAR-1971','FT','','','','','30-NOV-2003',NULL,23230099,'BARCLAYS','PENGE','DEPOSIT','PR1');
Any contribution would be appreciated
many thanks
Cube60Hi,
I have triede this cursor procedure but I get an compilation error.
See first post for tables and data..
Can someone help me out please.
SQL> CREATE OR REPLACE PROCEDURE update_employee(
2 p_empid employee.empid%type,
3 p_emp_type employee.emp_type%type)
4 IS
5 CURSOR c1 is
6 select e.empid, e.emp_type, c.yearly_pay from employee e, classification c where
7 c.class_id = e.class_id;
8 BEGIN
9 OPEN c1
10 LOOP
11 FETCH c1 INTO p_empid, p_emp_type;
12 exit when c1%notfound;
13
14 IF v_emp_type ='PT1' THEN
15 UPDATE employee SET annual_weeks_reqd = 39, pro_rata_wages = ((v_yearly_pay/52)*39), holiday_en
tlment=21, sick_leave_entlment = 10.5 WHERE c.class_id = e.class_id;
16 END IF;
17 END;
18 /
Warning: Procedure created with compilation errors.
SQL> SHOW ERR;
Errors for PROCEDURE UPDATE_EMPLOYEE:
LINE/COL ERROR
10/1 PLS-00103: Encountered the symbol "LOOP" when expecting one of
the following:
. ( % ; for
The symbol "; was inserted before "LOOP" to continue.
Many thanks -
Using two cursors, one for updating salary values in the emp table
Using COPIES of the employee and department tables provided by Oracle or using similar taples that provide employee, salary, job and dept in one table and dept number and department name in another table, write the following program. Use the dept table to step through sequentially and bring up the records with the same department from the employee table. Using an IF statement calcuate a new salary based on the job (you decide on the criteria). Update each record on the employee file (this is why you should use copies) with the new salary. In addition, calculate the total salary for each department and create a new table with the department number, the department name and the salary.
I'm able to update the salary values, but I'm not sure how to insert those updated values into an empty table the way this problem is asking me to.
Here's my script so far: any help would be greatly appreciated: )
declare
v_deptno emp.deptno%type;
v_job emp.job%type;
v_sal emp.sal%type;
v_dname dept.dname%type;
v_deptsal totalsal.deptsal%type;
cursor salup_c is
select job,sal
from emp,dept
where emp.deptno = dept.deptno
for update of sal;
cursor totdeptsal_c is
select dname,sal
from emp,dept
where emp.deptno = dept.deptno;
Begin
open salup_c;
loop
fetch salup_c into v_job,v_sal;
exit when salup_c%notfound;
if v_job = 'CLERK' then
v_sal := v_sal + 10;
else
if v_job = 'ANALYST' then
v_sal := v_sal + 20;
else
if v_job = 'MANAGER' then
v_sal := v_sal + 30;
else
if v_job = 'PRESIDENT' then
v_sal := v_sal + 40;
else v_sal := v_sal + 50;
end if;
end if;
end if;
end if;
update emp
set sal = v_sal
where current of salup_c;
open totdeptsal_c;
v_deptsal := 0;
loop
fetch totdeptsal_c into v_dname, v_deptsal;
exit when totdeptsal_c%notfound;
v_deptsal := v_deptsal + v_sal;
insert into totalsal
values(v_deptno,v_dname,v_deptsal);
end loop;
close totdeptsal_c;
end loop;
close salup_c;
end;
/The script is actually inserting some values into the new table but look at what I'm getting
Here it is: i only want the dept number ,the dept name, and total salary for each department.
SQL> @ sndprob;
PL/SQL procedure successfully completed.
SQL> select * from totalsal;
DEPTNO DNAME DEPTSAL
RESEARCH 1620
SALES 2410
SALES 2060
RESEARCH 3785
SALES 2060
SALES 3660
ACCOUNTING 3260
RESEARCH 3810
ACCOUNTING 5810
SALES 2310
RESEARCH 1910
DEPTNO DNAME DEPTSAL
SALES 1760
RESEARCH 3810
ACCOUNTING 2110
RESEARCH 2460
SALES 3300
SALES 2900
RESEARCH 4625
SALES 2900
SALES 4500
ACCOUNTING 4100
RESEARCH 4650
DEPTNO DNAME DEPTSAL
ACCOUNTING 6650
SALES 3150
RESEARCH 2750
SALES 2600
RESEARCH 4650
ACCOUNTING 2950
RESEARCH 2110
SALES 2950
SALES 2600
RESEARCH 4275
SALES 2550
DEPTNO DNAME DEPTSAL
SALES 4150
ACCOUNTING 3750
RESEARCH 4300
ACCOUNTING 6300
SALES 2800
RESEARCH 2400
SALES 2250
RESEARCH 4300
ACCOUNTING 2600
RESEARCH 3815
SALES 4655
DEPTNO DNAME DEPTSAL
SALES 4305
RESEARCH 6010
SALES 4255
SALES 5855
ACCOUNTING 5455
RESEARCH 6005
ACCOUNTING 8005
SALES 4505
RESEARCH 4105
SALES 3955
RESEARCH 6005
DEPTNO DNAME DEPTSAL
ACCOUNTING 4305
RESEARCH 2110
SALES 2950
SALES 2600
RESEARCH 4305
SALES 2600
SALES 4150
ACCOUNTING 3750
RESEARCH 4300
ACCOUNTING 6300
SALES 2800
DEPTNO DNAME DEPTSAL
RESEARCH 2400
SALES 2250
RESEARCH 4300
ACCOUNTING 2600
RESEARCH 3690
SALES 4530
SALES 4180
RESEARCH 5885
SALES 4180
SALES 5760
ACCOUNTING 5330
DEPTNO DNAME DEPTSAL
RESEARCH 5880
ACCOUNTING 7880
SALES 4380
RESEARCH 3980
SALES 3830
RESEARCH 5880
ACCOUNTING 4180
RESEARCH 3290
SALES 4130
SALES 3780
RESEARCH 5485
DEPTNO DNAME DEPTSAL
SALES 3780
SALES 5360
ACCOUNTING 4960
RESEARCH 5480
ACCOUNTING 7480
SALES 3980
RESEARCH 3580
SALES 3430
RESEARCH 5480
ACCOUNTING 3780
RESEARCH 3830
DEPTNO DNAME DEPTSAL
SALES 4670
SALES 4320
RESEARCH 6025
SALES 4320
SALES 5900
ACCOUNTING 5500
RESEARCH 6040
ACCOUNTING 8020
SALES 4520
RESEARCH 4120
SALES 3970
DEPTNO DNAME DEPTSAL
RESEARCH 6020
ACCOUNTING 4320
RESEARCH 5850
SALES 6690
SALES 6340
RESEARCH 8045
SALES 6340
SALES 7920
ACCOUNTING 7520
RESEARCH 8060
ACCOUNTING 10080
DEPTNO DNAME DEPTSAL
SALES 6540
RESEARCH 6140
SALES 5990
RESEARCH 8040
ACCOUNTING 6340
RESEARCH 2360
SALES 3200
SALES 2850
RESEARCH 4555
SALES 2850
SALES 4430
DEPTNO DNAME DEPTSAL
ACCOUNTING 4030
RESEARCH 4570
ACCOUNTING 6590
SALES 3100
RESEARCH 2650
SALES 2500
RESEARCH 4550
ACCOUNTING 2850
RESEARCH 1920
SALES 2760
SALES 2410
DEPTNO DNAME DEPTSAL
RESEARCH 4115
SALES 2410
SALES 3990
ACCOUNTING 3590
RESEARCH 4130
ACCOUNTING 6150
SALES 2660
RESEARCH 2220
SALES 2060
RESEARCH 4110
ACCOUNTING 2410
DEPTNO DNAME DEPTSAL
RESEARCH 1770
SALES 2610
SALES 2260
RESEARCH 3965
SALES 2260
SALES 3840
ACCOUNTING 3440
RESEARCH 3980
ACCOUNTING 6000
SALES 2510
RESEARCH 2070
DEPTNO DNAME DEPTSAL
SALES 1920
RESEARCH 3960
ACCOUNTING 2260
RESEARCH 3830
SALES 4670
SALES 4320
RESEARCH 6025
SALES 4320
SALES 5900
ACCOUNTING 5500
RESEARCH 6040
DEPTNO DNAME DEPTSAL
ACCOUNTING 8060
SALES 4570
RESEARCH 4130
SALES 3980
RESEARCH 6040
ACCOUNTING 4320
RESEARCH 2120
SALES 2960
SALES 2610
RESEARCH 4315
SALES 2610
DEPTNO DNAME DEPTSAL
SALES 4190
ACCOUNTING 3790
RESEARCH 4330
ACCOUNTING 6350
SALES 2860
RESEARCH 2420
SALES 2270
RESEARCH 4330
ACCOUNTING 2620
196 rows selected. -
FOR UPDATE on scrollable cursor and error: ORA-00907: missing right parenthesis
If change my query to have a FOR UPDATE and make it an updatable scrollable cursor I get an error on the updateRow() command saying "ORA-00907: missing right parenthesis"
If I remove the FOR UPDATE it works OK.
The problem I have is trying to update a CLOB from a ResultSet. If I do not upate any other column I get the error saying that the error"
"ORA-22920: row containing the LOB value is not locked"
I can get around this by adding FOR UPDATE. But if I add FOR UPDATE and try to update any non-CLOB column I get the 00907 error above.
Hmmmm. So here is what I can and cannot do:
- I CAN update the CLOB IF I update another column 1st and NO FOR UPDATE clause.
- I CAN update the CLOB only if I have FOR UPDATE clause.
- I CANNOT update just the CLOB without FOR UPDATE.
- I CANNOT update any non-CLOB column with FOR UPDATE.
What a pain in the ***! How am I to provide generic access to the applications being built on my DB layer. This is crazy!<BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by Andrew Edgar ([email protected]):
I have this same problem!
The error occurs when performing updateRow.
The turning off of auto commit only gets the query to work but not the actual update.
Will this be fixed in the next version of the Driver?<HR></BLOCKQUOTE>
Here is the stack Trace I recieved:
java.sql.SQLException: ORA-00907: missing right parenthesis
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:168)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:208)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:543)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1405)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:822)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:1446)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1371)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1900)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:363)
at oracle.jdbc.driver.UpdatableResultSet.execute_updateRow(UpdatableResultSet.java:2135)
at oracle.jdbc.driver.UpdatableResultSet.updateRow(UpdatableResultSet.java:1322) -
cursor t_c is
select a.f1, b.f2, c.f3
from A, B, C
where A.id = B.id
and A.id = C.id
for update B.f5, B.f6, B.f7, C.f8, C.f9;
for item in t_c
loop
update B
set f5 = something,
f6 = something,
f7 = something;
where current of t_c;
update C
set f8 = something,
f9 = something;
where current of t_c;
end loop;
my selection statement is fine.
but the update statement is not working, as i end
up with the original values.
when i take out the update statement for table C
(including the 'for update' section), the update
for table B works fine.
i can't see any mistakes from my script.
could anyone please point out?
thanks ...have you tried to rewrite the cursor to not use a for update of,
but to use the rownum instead?
cursor t_c is
select a.f1, b.f2, c.f3
from A, B, C
where A.id = B.id
and A.id = C.id
for update B.f5, B.f6, B.f7, C.f8, C.f9;
for item in t_c
loop
update B
set f5 = something,
f6 = something,
f7 = something;
where current of t_c;
update C
set f8 = something,
f9 = something;
where current of t_c;
end loop;
my selection statement is fine.
but the update statement is not working, as i end
up with the original values.
when i take out the update statement for table C
(including the 'for update' section), the update
for table B works fine.
i can't see any mistakes from my script.
could anyone please point out?
thanks ... -
For update & where current of in cursor
Hi,
Please explain any For Update with WHERE CURRENT OF clause in cursor.
DiwakarHi,
I am getting meaning of FOR UPDATE CLAUSE but Right now i am not getting WHERE CURRENT OFF clause.
Basically For Update clause in PL/SQL cursor used for locking the Row which is extracted by the query. But what is the use of WERE CURRENT OF Clause. When we use WERE CURRENT OF clause at that time cursor must should have FOR UPDATE CLAUSE in cursor declaration.
Thank you Diwakar
Here is link in documentation:
http://download-uk.oracle.com/docs/cd/B14117_01/server
.101/b10759/statements_10002.htm#i2126016
Peter D.
It's link to SELECT FOR UPDATE statement.
Message was edited by:
Peter D. -
Cursor with for update clause problem
Hi all,
We are having this problem with Oracle 8.1.7 where in we have a cursor with for update clause. The PL/SQL script used to work fine with Oracle 8.0.5 but is causing problems with Oracle 8.1.7. What the script is ending up doing in 8.1.7 is that it updates only one record instead of updating close to 60000 which it used to do in Oracle 8.0.5
The script just hangs after updating one record. We have replicated the same problem.
Has anyone seen this error before and attained resolution?
ThanksHello ,
I have found the same / very close to the same problem. I tried the code below in Oracle 10.2.0.1 and got the following error after the first loop.
ORA-01002: fetch out of sequence
ORA-06512: at "DEMO_TEST_RESEARCH_PKG", line 18
ORA-06512: at line 7
After trying to debug it , i thought i would try it in Oracle 9.0.2.0.7.0 , and to my suprise it worked fine.
Am i missing something ? Thanks in advance , ...
I have included the code i was running ...
PROCEDURE WhereCurrentOf(Param1 IN NUMBER) IS
v_title_eng ISSUES.TITLE_ENG%TYPE;
v_issue_id ISSUES.ISSUE_ID%TYPE;
CURSOR issues_cur
IS
SELECT issue_id,title_eng
FROM issues
WHERE title_eng IS NULL
FOR UPDATE OF title_eng;
BEGIN
FOR i IN issues_cur
LOOP
FETCH issues_cur INTO v_issue_id,v_title_eng;
EXIT WHEN issues_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_issue_id||' This was the english title before : '||v_title_eng);
v_title_eng := 'This is my title';
UPDATE issues
SET title_eng = v_title_eng
WHERE CURRENT OF issues_cur;
DBMS_OUTPUT.PUT_LINE(v_issue_id||' This is the english title after : '||v_title_eng);
END LOOP;
END WhereCurrentOf;
Maybe you are looking for
-
Separate security for both of two distinct parties - 1 the data owner - 2 the application owner
I have written a web application in .net that runs on a shared server using Sql Server 2012. My program is only useful if I partner with certain data owners. I need to protect my program; they need to protect their data. I am assuming they at least r
-
Local Storage on IPad and Iphone is missing IOS7
Hi, I have a Jquery Mobile app working fine in IOS6, upgrading to IO7 on the Ipad and Iphone the app is crashing when returning lists of data that previously worked. Our app works exclusivley with the local storage code in all modern browers allowing
-
Hello everyone. I am having USB issues on my HP dv6t-7000. I was using my USB keyboard/mouse and the USB was working fine. I then plug in a flash drive and ALL USB PORTS STOP WORKING. So I tried the usual fix of reloading xhci_hcd. rmmod xhci_hcd
-
Hi: I am using RMAN to clone EBS R12. After the clone I checked the log file against the /staging/.../PROD (data files) and found last three files are not in the log file that mean they are not copied. We use "SET UNTIL SEQUENCE 80426 THREAD 1". Is t
-
Hi all, I did some code like when invalid combinations....then need to raise a request,at that time it showing the error message, but after that error message...when press enter....that work order starts genrating(means start processing).So i need to