如果c_m%为等参 然后 关闭c_m; 如果结束; 如果c_p%等参比 然后 关闭CUP; 如果结束; DBMS_OUTPUT.put_行(SQLERRM); 结束; 无法更改表。请参阅我的更新,我使用了所有约束以避免任何硬代码和手动查找依赖表的努力。无法
如果c_m%为等参 然后 关闭c_m; 如果结束; 如果c_p%等参比 然后 关闭CUP; 如果结束; DBMS_OUTPUT.put_行(SQLERRM); 结束;如果c_m%为等参 然后 关闭c_m; 如果结束; 如果c_p%等参比 然后 关闭CUP; 如果结束; DBMS_OUTPUT.put_行(SQLERRM); 结束; 无法更改表。请参阅我的更新,我使用了所有约束以避免任何硬代码和手动查找依赖表的努力。无法,sql,oracle,plsql,cursor,Sql,Oracle,Plsql,Cursor,如果c_m%为等参 然后 关闭c_m; 如果结束; 如果c_p%等参比 然后 关闭CUP; 如果结束; DBMS_OUTPUT.put_行(SQLERRM); 结束; 无法更改表。请参阅我的更新,我使用了所有约束以避免任何硬代码和手动查找依赖表的努力。无法更改表。请参阅我的更新,我使用所有约束以避免任何硬代码和手动查找依赖表的努力。 Meeting_t : Meeting_id (PK), create_date (Date) Prog_call : prog_call_id (PK) and
无法更改表。请参阅我的更新,我使用了
所有约束
以避免任何硬代码和手动查找依赖表的努力。无法更改表。请参阅我的更新,我使用所有约束
以避免任何硬代码和手动查找依赖表的努力。
Meeting_t : Meeting_id (PK), create_date (Date)
Prog_call : prog_call_id (PK) and Meeting_id (FK)
Lock_t : lock_id (PK) and prog_call_id (FK)
PROCEDURE CleanBefore(delete_before DATE)
IS
meeting_id_v dev.prog_call.meeting_id%TYPE;
prog_call_id_v dev.prog_call.prog_call_id%TYPE;
CURSOR meeting_c IS
SELECT st.meeting_id
FROM dev.meeting_t st
WHERE TRUNC(st.logoff_datum) <= TRUNC(CleanBefore.delete_before);
CURSOR prog_call_c IS
SELECT pa.prog_call_id
FROM dev.prog_call pa
WHERE pa.meeting_id = meeting_id_v;
BEGIN
OPEN meeting_c;
LOOP
FETCH meeting_c INTO meeting_id_v;
OPEN prog_call_c;
LOOP
FETCH prog_call_c INTO prog_call_id_v;
DELETE FROM dev.lock_t lt
WHERE lt.prog_call_id = prog_call_id_v;
DELETE FROM dev.prog_call pa
WHERE pa.prog_call_id = prog_call_id_v;
END LOOP;
CLOSE prog_call_c;
DELETE FROM dev.meeting_t st
WHERE st.meeting_id = meeting_id_v;
END LOOP;
CLOSE meeting_c;
END CleanBefore;
SQL> drop table comm;
SQL> DROP TABLE EMPLOYEE;
SQL>
SQL> CREATE TABLE employee
2 (employee_id NUMBER(10) NOT NULL
3 ,employee_name VARCHAR2(500) NOT NULL
4 ,salary NUMBER(20) NOT NULL
5 ,department VARCHAR2(300) NOT NULL
6 ,CONSTRAINT employee_pk PRIMARY KEY (employee_id)
7 );
SQL>
SQL> CREATE TABLE comm
2 (emp_id NUMBER(10)
3 ,commission_percent NUMBER(20)
4 ,CONSTRAINT fk_employee
5 FOREIGN KEY (emp_id)
6 REFERENCES employee(employee_id)
7 ON DELETE CASCADE
8 );
SQL>
SQL> INSERT INTO employee
2 VALUES (101,'Emp A',10000,'Sales');
SQL>
SQL> INSERT INTO employee
2 VALUES (102,'Emp B',20000,'IT');
SQL>
SQL> INSERT INTO employee
2 VALUES (103,'Emp C',28000,'IT');
SQL>
SQL> INSERT INTO employee
2 VALUES (104,'Emp D',30000,'Support');
SQL>
SQL> INSERT INTO EMPLOYEE
2 VALUES (105,'Emp E',32000,'Sales');
SQL>
SQL> INSERT INTO comm
2 VALUES (102,20);
SQL>
SQL> INSERT INTO comm
2 VALUES (103,20);
SQL>
SQL> INSERT INTO comm
2 VALUES (104,NULL);
SQL>
SQL> INSERT INTO COMM
2 VALUES (105,10);
SQL>
SQL> SELECT *
2 FROM employee;
EMPLOYEE_ID EMPLOYEE_NAME SALARY DEPARTMENT
----------- ------------------------------ ---------- ------------------------------
101 Emp A 10000 Sales
102 Emp B 20000 IT
103 Emp C 28000 IT
104 Emp D 30000 Support
105 Emp E 32000 Sales
SQL>
SQL> SELECT *
2 FROM comm;
EMP_ID COMMISSION_PERCENT
---------- ------------------
102 20
103 20
104
105 10
SQL>
SQL> DELETE FROM EMPLOYEE
2 WHERE EMPLOYEE_ID = 105;
SQL>
SQL> SELECT *
2 FROM employee;
EMPLOYEE_ID EMPLOYEE_NAME SALARY DEPARTMENT
----------- ------------------------------ ---------- ------------------------------
101 Emp A 10000 Sales
102 Emp B 20000 IT
103 Emp C 28000 IT
104 Emp D 30000 Support
SQL>
SQL> SELECT *
2 FROM COMM;
EMP_ID COMMISSION_PERCENT
---------- ------------------
102 20
103 20
104
SQL>
SQL> SELECT *
2 FROM employee;
EMPLOYEE_ID EMPLOYEE_NAME SALARY DEPARTMENT
----------- ------------------------------ ---------- ------------------------------
101 Emp A 10000 Sales
102 Emp B 20000 IT
103 Emp C 28000 IT
104 Emp D 30000 Support
105 Emp E 32000 Sales
SQL>
SQL> SELECT *
2 FROM comm;
EMP_ID COMMISSION_PERCENT
---------- ------------------
102 20
103 20
104
105 10
SQL>
SQL> BEGIN
2 FOR i IN
3 (SELECT TABLE_NAME
4 FROM all_constraints
5 WHERE r_constraint_name IN
6 (SELECT constraint_name FROM all_constraints WHERE TABLE_NAME='EMPLOYEE'
7 )
8 )
9 LOOP
10 EXECUTE IMMEDIATE 'delete from '||i.TABLE_NAME||' where emp_id = 101';
11 END LOOP;
12 DELETE FROM EMPLOYEE WHERE EMPLOYEE_ID = 101;
13 END;
14 /
SQL>
SQL> SELECT * FROM EMPLOYEE;
EMPLOYEE_ID EMPLOYEE_NAME SALARY DEPARTMENT
----------- ------------------------------ ---------- ---------------------------
102 Emp B 20000 IT
103 Emp C 28000 IT
104 Emp D 30000 Support
SQL> SELECT * FROM COMM;
EMP_ID COMMISSION_PERCENT
---------- ------------------
102 20
103 20
104
SQL>
PROCEDURE cleanBefore( delete_before DATE )
IS
DELETE FROM lock_t l
WHERE l.prog_call_id IN
(SELECT p.prog_call_id
FROM meeting_t m
INNER JOIN prog_call p
ON (p.meeting_id = m.meeting_id)
WHERE trunc(m.logoff_datum) <= trunc(cleanBefore.delete_before);
DELETE FROM prog_call p
WHERE p.meeting_id IN
(SELECT m.meeting_id
FROM meeting_t m
WHERE trunc(m.logoff_datum) <= trunc(cleanBefore.delete_before);
DELETE FROM meeting_t m
WHERE trunc(m.logoff_datum) <= trunc(cleanBefore.delete_before);
END cleanBefore;
CREATE TABLE meeting_t
(
meeting_id NUMBER (10) ,
create_date DATE ,
CONSTRAINT meeting_pk PRIMARY KEY (meeting_id)
);
CREATE TABLE prog_call
( prog_call_id NUMBER(10) ,
meeting_id NUMBER(10),
CONSTRAINT prog_call_pk PRIMARY KEY (prog_call_id),
CONSTRAINT fk_meeting_prog
FOREIGN KEY (meeting_id)
REFERENCES meeting_t(meeting_id)
);
CREATE TABLE lock_t
( lock_id NUMBER(10) ,
prog_call_id NUMBER(10),
CONSTRAINT lock_pk PRIMARY KEY (lock_id),
CONSTRAINT fk_prog_lock
FOREIGN KEY (prog_call_id)
REFERENCES prog_call(prog_call_id)
);
CREATE INDEX meeting_crt_dt ON meeting_t(create_date);
CREATE INDEX prog_call_meeting_idx ON prog_call(meeting_id);
CREATE INDEX lock_prog_call ON lock_t(prog_call_id);
SELECT ROUND (DBMS_RANDOM.VALUE (1000, 10000))
FROM DUAL
CONNECT BY LEVEL < 10;
INSERT INTO meeting_t
SELECT object_id, created
FROM dba_objects
WHERE ROWNUM < 2000;
INSERT INTO prog_call
SELECT object_id + object_id, object_id
FROM dba_objects
WHERE object_id IN (SELECT meeting_id
FROM meeting_t) AND ROWNUM < 2000;
INSERT INTO lock_t
SELECT prog_call_id + prog_call_id, prog_call_id
FROM prog_call;
COMMIT ;
SELECT *
FROM meeting_t m, prog_call p, lock_t l
WHERE m.meeting_id = p.meeting_id AND p.prog_call_id = l.prog_call_id
/
CREATE OR REPLACE TYPE typ_num_tbl IS TABLE OF NUMBER (10);
SELECT min(create_date), max(create_date) FROM meeting_t ;
PROCEDURE cleanbefore (p_delete_before DATE)
IS
-- meeting_t m, prog_call p, lock_t l
CURSOR c_m
IS
SELECT m.meeting_id
FROM meeting_t m
WHERE m.create_date < p_delete_before;
tbl_meeting_ids typ_num_tbl := typ_num_tbl ();
CURSOR c_p
IS
SELECT p.prog_call_id
FROM prog_call p
WHERE p.meeting_id IN (SELECT COLUMN_VALUE
FROM TABLE (tbl_meeting_ids));
tbl_prog_ids typ_num_tbl := typ_num_tbl ();
n_limit NUMBER (3) := 500;
BEGIN
DBMS_OUTPUT.put_line ('Start');
OPEN c_m;
DBMS_OUTPUT.put_line ('10');
-- meetings
LOOP
EXIT WHEN c_m%NOTFOUND;
DBMS_OUTPUT.put_line ('20');
FETCH c_m
BULK COLLECT INTO tbl_meeting_ids LIMIT n_limit;
IF tbl_meeting_ids.COUNT > 0
THEN
DBMS_OUTPUT.put_line ( '30 - tbl_meeting_ids.count:'
|| tbl_meeting_ids.COUNT
);
-- programs
OPEN c_p;
DBMS_OUTPUT.put_line ('40');
LOOP
EXIT WHEN c_p%NOTFOUND;
DBMS_OUTPUT.put_line ('50');
FETCH c_p
BULK COLLECT INTO tbl_prog_ids LIMIT n_limit;
IF tbl_prog_ids.COUNT > 0
THEN
DBMS_OUTPUT.put_line ( '60 - tbl_prog_ids.count:'
|| tbl_prog_ids.COUNT
);
DELETE FROM lock_t l
WHERE l.prog_call_id IN (
SELECT COLUMN_VALUE p_id
FROM TABLE (CAST (tbl_prog_ids AS typ_num_tbl)
));
DBMS_OUTPUT.put_line ('70 Deleted:' || SQL%ROWCOUNT);
DELETE FROM prog_call p
WHERE p.meeting_id IN (
SELECT COLUMN_VALUE m_id
FROM TABLE
(CAST (tbl_meeting_ids AS typ_num_tbl)
));
DBMS_OUTPUT.put_line ('80 Deleted:' || SQL%ROWCOUNT);
DELETE FROM meeting_t m
WHERE m.meeting_id IN (
SELECT COLUMN_VALUE m_id
FROM TABLE
(CAST (tbl_meeting_ids AS typ_num_tbl)
));
DBMS_OUTPUT.put_line ('81 Deleted:' || SQL%ROWCOUNT);
END IF;
DBMS_OUTPUT.put_line ('90');
END LOOP;
DBMS_OUTPUT.put_line ('100');
-- << end loop programs >>
CLOSE c_p;
DBMS_OUTPUT.put_line ('110');
END IF;
-- COMMIT; -- COMMIT here if you dont care about ALL DELETE in ONE GO
END LOOP;
DBMS_OUTPUT.put_line ('120');
-- << end loop meetings >>
CLOSE c_m;
DBMS_OUTPUT.put_line ('130');
tbl_meeting_ids.DELETE;
tbl_prog_ids.DELETE;
COMMIT;
DBMS_OUTPUT.put_line ('End');
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
tbl_meeting_ids.DELETE;
tbl_prog_ids.DELETE;
IF c_m%ISOPEN
THEN
CLOSE c_m;
END IF;
IF c_p%ISOPEN
THEN
CLOSE c_p;
END IF;
DBMS_OUTPUT.put_line (SQLERRM);
END;