Есть несколько ограничений при использовании varrays
. Один из них - когда вы делаете DML
операции с таблицами, имеющими столбцы с типом данных varray
, как показано в вашем примере. Вы можете использовать Nested table
и выполнить свое требование, как показано ниже в моей демонстрации. Однако имейте в виду, что операции с вложенными таблицами довольно сложны для понимания. Смотрите ниже и читайте встроенные комментарии.
--Created Table emp2 with an additional column
CREATE TABLE emp2 (ename VARCHAR2(10));
--Object
CREATE OR REPLACE TYPE COMM_TYPE AS OBJECT
(COMM_MONTH VARCHAR(5),
COMM_AMOUNT NUMBER);
--Created a Table of object rather then varray.
CREATE OR REPLACE TYPE COMM_ARRAY AS TABLE OF COMM_TYPE;
--Modified table emp2. Added column commission as shown in your example
ALTER TABLE EMP2 ADD COMMISSION COMM_ARRAY NESTED TABLE COMMISSION STORE AS TBA1;
--Inserted records
INSERT INTO EMP2 VALUES('AAA',COMM_ARRAY(COMM_TYPE('NOV',100)));
INSERT INTO EMP2 VALUES('BBB',COMM_ARRAY(COMM_TYPE('DEC',200)));
--Selected Records
SQL> SELECT C.COMM_AMOUNT,C.COMM_MONTH
2 FROM EMP2 E, TABLE (E.COMMISSION) C
3 WHERE C.COMM_MONTH = 'DEC';
COMM_AMOUNT COMM_
----------- -----
200 DEC
- Блокировать обновление записей
DECLARE
CURSOR c_comm_amount_cursor IS
select c.comm_amount,c.comm_month
from emp2 e, table (e.commission) c
where c.comm_month = 'DEC'for update of c.comm_month nowait;
BEGIN
FOR emp_record IN c_comm_amount_cursor
LOOP
--With the help of table operator you can update records of a nested table but not varray.
UPDATE table( Select commission from emp2 where ename = 'BBB') e --<--Make sure to use additional column of the table to make unique record selection for update
SET e.comm_amount = e.comm_amount + 100
WHERE CURRENT OF c_comm_amount_cursor;
END LOOP;
COMMIT;
END;
/
- Вы видите, что обновление выполняется.
SQL> /
COMM_AMOUNT COMM_
----------- -----
300 DEC
Кроме того, как упоминалось в комментариях, использование цикла выглядит избыточным, и блок может быть дополнительно упрощен, как показано ниже:
BEGIN
--With the help of table operator you can update records of a nested table but not varray.
UPDATE table( Select commission from emp2 where ename = 'BBB') e --<--Make sure to use additional column of the table to make unique record selection for update
SET e.comm_amount = e.comm_amount + 100
WHERE e.comm_month ='DEC';
COMMIT;
END;
EDIT:
как я могу обновить каждого сотрудника, здесь вы выбираете только одного с именем
'BBB'. Есть ли способ?
Как уже упоминалось в моих комментариях, вы можете использовать dynamic SQL
для обновления всех сотрудников, как показано ниже:
DECLARE
v_sql varchar2(2000);
CURSOR c_enme_cursor IS
select ename
from emp2;
BEGIN
FOR emp_recd IN c_enme_cursor
LOOP
v_sql:=q'[
UPDATE table( Select commission from emp2 where ename = ']'||emp_recd.ename||q'[') e
SET e.comm_amount = e.comm_amount + 100
-- WHERE e.comm_month ='DEC'
]';
EXECUTE IMMEDIATE V_SQL;
END LOOP;
COMMIT;
END;