Create local copy of HR.EMPLOYEES
DECLARE
c_schema_name CONSTANT VARCHAR2 (100) := 'HR';
c_table_name CONSTANT VARCHAR2 (100) := 'EMPLOYEES';
e_no_such_table EXCEPTION;
PRAGMA EXCEPTION_INIT (e_no_such_table, -942);
BEGIN
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || c_table_name;
EXCEPTION
WHEN e_no_such_table
THEN
NULL;
END;
EXECUTE IMMEDIATE
'CREATE TABLE '
|| c_table_name
|| ' AS SELECT * FROM '
|| c_schema_name
|| '.'
|| c_table_name;
END;
Statement processed.
Who's got a big fat $10000 salary now?
SELECT *
FROM employees
WHERE salary = 10000
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | PHONE_NUMBER | HIRE_DATE | JOB_ID | SALARY | COMMISSION_PCT | MANAGER_ID | DEPARTMENT_ID | 150 | Peter | Tucker | PTUCKER | 011.44.1344.129268 | 30-JAN-05 | SA_REP | 10000 | .3 | 145 | 80 | 156 | Janette | King | JKING | 011.44.1345.429268 | 30-JAN-04 | SA_REP | 10000 | .35 | 146 | 80 | 169 | Harrison | Bloom | HBLOOM | 011.44.1343.829268 | 23-MAR-06 | SA_REP | 10000 | .2 | 148 | 80 | 204 | Hermann | Baer | HBAER | 515.123.8888 | 07-JUN-02 | PR_REP | 10000 | - | 101 | 70 |
---|
INDICES OF Example: Bind array used in clause
DECLARE
TYPE employee_aat IS TABLE OF employees.employee_id%TYPE
INDEX BY PLS_INTEGER;
l_employees employee_aat;
BEGIN
l_employees (1) := 137;
l_employees (100) := 126;
l_employees (500) := 147;
FORALL l_index IN INDICES OF l_employees
UPDATE employees
SET salary = 10000
WHERE employee_id = l_employees (l_index);
DBMS_OUTPUT.put_line (SQL%ROWCOUNT);
END;
Statement processed.
3
Now how many employees have this salary?
SELECT *
FROM employees
WHERE salary = 10000
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | PHONE_NUMBER | HIRE_DATE | JOB_ID | SALARY | COMMISSION_PCT | MANAGER_ID | DEPARTMENT_ID | 126 | Irene | Mikkilineni | IMIKKILI | 650.124.1224 | 28-SEP-06 | ST_CLERK | 10000 | - | 120 | 50 | 137 | Renske | Ladwig | RLADWIG | 650.121.1234 | 14-JUL-03 | ST_CLERK | 10000 | - | 123 | 50 | 147 | Alberto | Errazuriz | AERRAZUR | 011.44.1344.429278 | 10-MAR-05 | SA_MAN | 10000 | .3 | 100 | 80 | 150 | Peter | Tucker | PTUCKER | 011.44.1344.129268 | 30-JAN-05 | SA_REP | 10000 | .3 | 145 | 80 | 156 | Janette | King | JKING | 011.44.1345.429268 | 30-JAN-04 | SA_REP | 10000 | .35 | 146 | 80 | 169 | Harrison | Bloom | HBLOOM | 011.44.1343.829268 | 23-MAR-06 | SA_REP | 10000 | .2 | 148 | 80 | 204 | Hermann | Baer | HBAER | 515.123.8888 | 07-JUN-02 | PR_REP | 10000 | - | 101 | 70 |
---|
Recreate Table for Next Example
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE employees';
EXECUTE IMMEDIATE 'CREATE TABLE employees AS SELECT * FROM hr.employees';
END;
Statement processed.
INDICES OF Example: Non-bind array used in clause
DECLARE
TYPE employee_aat IS TABLE OF employees.employee_id%TYPE
INDEX BY PLS_INTEGER;
l_employees employee_aat;
TYPE boolean_aat IS TABLE OF BOOLEAN
INDEX BY PLS_INTEGER;
l_employee_indices boolean_aat;
BEGIN
l_employees (1) := 137;
l_employees (100) := 126;
l_employees (500) := 147;
--
l_employee_indices (1) := FALSE;
l_employee_indices (500) := TRUE;
l_employee_indices (799) := NULL;
FORALL l_index IN INDICES OF l_employee_indices
BETWEEN 1 AND 600
UPDATE employees
SET salary = 10000
WHERE employee_id = l_employees (l_index);
DBMS_OUTPUT.PUT_LINE (SQL%ROWCOUNT);
END;
Statement processed.
2
And now how many employees have a salary of 10000?
SELECT *
FROM employees
WHERE salary = 10000
EMPLOYEE_ID | FIRST_NAME | LAST_NAME | PHONE_NUMBER | HIRE_DATE | JOB_ID | SALARY | COMMISSION_PCT | MANAGER_ID | DEPARTMENT_ID | 137 | Renske | Ladwig | RLADWIG | 650.121.1234 | 14-JUL-03 | ST_CLERK | 10000 | - | 123 | 50 | 147 | Alberto | Errazuriz | AERRAZUR | 011.44.1344.429278 | 10-MAR-05 | SA_MAN | 10000 | .3 | 100 | 80 | 150 | Peter | Tucker | PTUCKER | 011.44.1344.129268 | 30-JAN-05 | SA_REP | 10000 | .3 | 145 | 80 | 156 | Janette | King | JKING | 011.44.1345.429268 | 30-JAN-04 | SA_REP | 10000 | .35 | 146 | 80 | 169 | Harrison | Bloom | HBLOOM | 011.44.1343.829268 | 23-MAR-06 | SA_REP | 10000 | .2 | 148 | 80 | 204 | Hermann | Baer | HBAER | 515.123.8888 | 07-JUN-02 | PR_REP | 10000 | - | 101 | 70 |
---|
Impact on BULK%ROWCOUNT
DECLARE
TYPE employee_aat IS TABLE OF employees.employee_id%TYPE
INDEX BY PLS_INTEGER;
l_employees employee_aat;
TYPE boolean_aat IS TABLE OF BOOLEAN
INDEX BY PLS_INTEGER;
l_employee_indices boolean_aat;
BEGIN
l_employees (1) := 137;
l_employees (100) := 126;
l_employees (500) := 147;
--
l_employee_indices (1) := FALSE;
l_employee_indices (500) := TRUE;
l_employee_indices (799) := NULL;
FORALL indx IN INDICES OF l_employee_indices BETWEEN 1 AND 600
UPDATE employees
SET salary = 10000
WHERE employee_id = l_employees (indx);
DBMS_OUTPUT.put_line ('Updated: ' || SQL%ROWCOUNT);
FOR indx IN 1 .. l_employees.COUNT
LOOP
BEGIN
DBMS_OUTPUT.put_line ('Index ' || indx || ' updated: ' || SQL%BULK_ROWCOUNT (indx));
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('Index ' || indx || ' failure: ' || SQLERRM);
END;
END LOOP;
FOR indx IN 1 .. 500
LOOP
BEGIN
DBMS_OUTPUT.put_line ('Index ' || indx || ' updated: ' || SQL%BULK_ROWCOUNT (indx));
EXCEPTION
WHEN OTHERS
THEN
NULL; -- DBMS_OUTPUT.put_line ('Index ' || indx || ' failure: ' || SQLERRM);
END;
END LOOP;
END;
Statement processed.
Updated: 2
Index 1 updated: 1
Index 2 failure: ORA-06532: Subscript outside of limit
Index 3 failure: ORA-06532: Subscript outside of limit
Index 1 updated: 1
Index 500 updated: 1