-- Oracle PL/SQL example by Sandeep Desai (http://www.thedesai.net) -- type show errors to show compilation errors set serverout on -- Have to drop table before dropping type DROP TABLE emp2; -- Custom Type DROP TYPE address_ty; CREATE TYPE address_ty AS OBJECT ( street VARCHAR(60), zip NUMBER ); / -- Variable Array which can be column in table e.g array of strings CREATE OR REPLACE TYPE emp_va as object (name VARCHAR2(10), zip NUMBER); / CREATE TABLE emp2 (empno INTEGER, empname VARCHAR2(10), address address_ty, CONSTRAINT emp_pk PRIMARY KEY (empno)); DESC emp2; CREATE OR REPLACE PACKAGE MYEMP AS -- parameters are IN, OUT or IN OUT PROCEDURE addEmployee(p_empno IN INTEGER, p_empname IN VARCHAR2); PROCEDURE updateEmployee(p_empno IN INTEGER, p_empname IN VARCHAR2); FUNCTION isEmpCreated(p_empname IN VARCHAR2) RETURN INTEGER; END MYEMP; / CREATE OR REPLACE PACKAGE BODY MYEMP AS PROCEDURE addEmployee(p_empno IN INTEGER, p_empname IN VARCHAR2) AS BEGIN INSERT INTO emp2 (empno, empname) values (p_empno, p_empname); COMMIT; -- will release all locks held END addEmployee; PROCEDURE updateEmployee(p_empno IN INTEGER, p_empname IN VARCHAR2) AS v_count INTEGER; e_employeeNotFound EXCEPTION; BEGIN -- SELECT and LOCK ROW SELECT COUNT(empno) INTO v_count FROM emp2 WHERE empno = p_empno; IF v_count = 0 THEN RAISE e_employeeNotFound; END IF; UPDATE emp2 set empname = p_empname WHERE empno = p_empno; COMMIT; -- will release all locks held END updateEmployee; FUNCTION isEmpCreated(p_empname IN VARCHAR2) RETURN INTEGER IS v_ecount INTEGER; v_returnValue INTEGER; BEGIN SELECT COUNT(empname) INTO v_ecount FROM emp2 WHERE empname = p_empname; IF (v_ecount > 0) THEN v_returnValue := 1; ELSE v_returnValue := 0; END IF; RETURN v_returnValue; END isEmpCreated; END MYEMP; / CREATE OR REPLACE PROCEDURE updateTest AS e_employeeNotFound EXCEPTION; BEGIN myemp.updateEmployee(456, 'bar'); EXCEPTION --WHEN e_employeeNotFound THEN -- DBMS_OUTPUT.PUT_LINE('caught not found exception'); WHEN OTHERS THEN ROLLBACK; END updateTest; / CREATE OR REPLACE PROCEDURE myemplist(p_empname IN VARCHAR2) AS v_empname emp2.empname%TYPE; -- %TYPE or %ROWTYPE -- EXPLICIT CURSOR (STATIC CURSOR) CURSOR c_emps IS SELECT empname FROM emp2 WHERE empname LIKE p_empname; -- DYNAMIC CURSOR TYPE t_empRef IS REF CURSOR RETURN emp2%ROWTYPE; v_empCV t_empRef; -- COLLECTION TYPE t_empTab IS TABLE of emp2%ROWTYPE; v_emps t_empTab; BEGIN OPEN c_emps; LOOP FETCH c_emps INTO v_empname; EXIT WHEN c_emps%NOTFOUND; -- %FOUND, %NOTFOUND, %ISOPEN, %ROWCOUNT DBMS_OUTPUT.PUT_LINE('LOOP--' || v_empname); -- || is string concat END LOOP; CLOSE c_emps; FOR v_emp IN c_emps LOOP DBMS_OUTPUT.PUT_LINE('FOR--' || v_emp.empname); END LOOP; OPEN v_empCV FOR SELECT * FROM emp2; -- SELECT list should match t_empRef -- IF v_empCV IS NULL will return true v_emps := t_empTab(); --v_emps(1) := t_empTab(789, 'zyx'); OPEN c_emps; -- LOOP -- FETCH c_emps INTO v_emps; -- EXIT WHEN c_emps%NOTFOUND; -- END LOOP; END myemplist; / -- WHILE ... LOOP .. END LOOP -- CASE WHEN x = 3 THEN .. WHEN x = 4 THEN ... ELSE .. END CASE -- PREDEFINED EXCEPTIONS -- ORA-0001 DUP_VAL_ON_INDEX -- ORA-0051 TIMEOUT_ON_RESOURCE -- ORA-0061 TRANSACTION_BACKED_OUT rolled back due to deadlock -- ORA-1001 INVALID_CURSOR -- ORA-1012 NOT_LOGGED_ON -- ORA-1017 LOGIN_DENIED -- ORA-1403 NO_DATA_FOUND -- ORA-1422 TOO_MANY_ROWS -- More errors such as ZERO_DIVIDE INSERT INTO emp2 (empno, empname, address) values (111, 'fb', address_ty('123 lane', 98765)); EXECUTE myemp.addEmployee(123, 'foo'); SELECT myemp.isEmpCreated('foo') FROM DUAL; EXECUTE DBMS_OUTPUT.PUT_LINE(myemp.isEmpCreated('foo')); EXECUTE myemplist('fo%'); EXECUTE updateTest(); SELECT * FROM emp2;