我正在嵌套表格
create or replace type comm_type as object
(comm_month varchar(5),
comm_amount number);
create or replace TYPE comm_array AS VARRAY(12) OF comm_type;
alter table emp2 add commission comm_array
现在的问题是如何使用光标更新comm_amount
列?
现在,有了这个,但是我无法访问子表(委托,有什么建议吗?
DECLARE
CURSOR c_comm_amount_cursor IS
select c.comm_amount
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
UPDATE emp2
SET emp2.commission.comm_amount = emp2.commission.comm_amount + 100
WHERE CURRENT OF c_emp_cursor;
END LOOP;
END;
/
编辑
这是我的桌子的桌子:
Name Null? Type
---------- -------- ------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
BONUS NUMBER
COMMISSION COMM_ARRAY
comm_array->12*times(comm_month, comm_amount)
我要在特定月份更新comm_amount。
解决方案
DECLARE
CURSOR c_comm_amount_cursor IS
select c.comm_amount,c.comm_month, e.empno
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
UPDATE table(Select commission from emp2 where empno = emp_record.empno) e
SET e.comm_amount = e.comm_amount + 100
WHERE CURRENT OF c_comm_amount_cursor;
END LOOP;
END;
/
答案 0 :(得分:1)
使用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;
编辑:
我该如何更新每位员工,在这里您只选择一位带姓名的员工 '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;
答案 1 :(得分:0)
您好,最快的答案是:
DECLARE
CURSOR C_COMM_AMOUNT_CURSOR
IS
SELECT ROWID ROW_ID
FROM EMP2 E
WHERE E.COMM_MONTH = 'DEC';
BEGIN
FOR EMP_RECORD IN C_COMM_AMOUNT_CURSOR
LOOP
UPDATE TABLE (
SELECT COMMISSION
FROM EMP2
WHERE ROWID = ROW_ID
)
SET COMM_AMOUNT = COMM_AMOUNT + 100
WHERE ;--your where clause condition
END LOOP;
END;
您应该知道在使用嵌套表时,必须在SQL脚本中的嵌套表周围使用 TABLE(),在PL / SQL中,它有点复杂,您必须创建一个嵌套对象运行时,并用您的数据填充它并进行操作,然后将其保存到您的表中,这太离谱了,我遇到了这个问题,并且使用 ROWID 更具可读性。