Lecture 4 PL/SQL language PL/SQL language • PL/SQL – procedural SQL • Allows combining procedural and SQL code • PL/SQL code is compiled, including SQL commands • PL/SQL code is executed: • on the server (procedures, packages, triggers) • can be executed on the client (e.g. Oracle Forms applications) Example Java code Connection conn = getDbConnection(); PreparedStatement pstm; Pstm = conn.prepareStatement( "DELETE FROM some_table WHERE ID = ?"); pstm.setInt(1, 100); pstm.executeUpdate(); • SQL code is: • included as text • interpreted at run-time Example PL/SQL procedure CREATE PROCEDURE update_salary(val number) IS BEGIN FOR e IN (SELECT * FROM emp) LOOP IF e.hire_date + 60 < SYSDATE THEN UPDATE emp SET salary = salary + val WHERE id = e.id; END IF; END LOOP; COMMIT; END; Trigger definition example CREATE OR REPLACE TRIGGER emp_id_trg BEFORE INSERT ON emp FOR EACH ROW BEGIN IF :new.id IS NULL THEN SELECT emp_seq.NEXTVAL INTO :new.id FROM DUAL; END IF; END; Function definition example CREATE OR REPLACE FUNCTION count_rows RETURN NUMBER IS cnt NUMBER; BEGIN SELECT count(*) INTO cnt FROM some_table; RETURN cnt; END; PL/SQL blocks [DECLARE var1 INTEGER; var2 VARCHAR2(10000); ] BEGIN ... [EXCEPTION -- exception handlers] END; PL/SQL language • PL/SQL language is case insensitive (as well as SQL in Oracle) DECLARE var1 INTEGER; BEGIN VAR1 := 3; -- the following two statements -- are identical SELECT count(*) INTO var1 FROM tab1; select COUNT(*) into VAR1 FROM TAB1; END; Variables • Variables are defined in PASCAL convention: name of the variable, then type • Variable types: • all SQL types and more: • VARCHAR2 up to VARCHAR2(32767) • BINARY_INTEGER • PLS_INTEGER • BOOLEAN Assignments • := operator is used for PL/SQL assignments • in SQL UPDATE statement normal = is used: DECLARE i NUMBER; BEGIN i := 0; UPDATE some_table t SET t.col = i where t.id = i; END; Assignments • Functions and procedures are treated differently • Function returns result, which must be used CREATE FUNCTION f1 RETURN NUMBER ...; DECLARE res NUMBER; BEGIN f1; -- incorrect res := f1; -- correct SELECT f1 INTO res FROM DUAL; -- correct END; PL/SQL • Operators •=,<=, >=, != (comparisons) •:= assignments •LIKE, IN can be used in PL/SQL • -- starts one line comment (like // in C++) • /* multi line comment, like in C */ Conditional statements IF condition THEN statements; END IF; IF condition THEN statements; ELSIF condition THEN statements; ELSE statements; END IF; Conditional statements CASE expression WHEN value1 THEN statement; WHEN value2 THEN statement; ELSE statement; END CASE; Simple loop LOOP statement; IF ... THEN EXIT; -- exit loop END IF; statement -- or EXIT WHEN condition; END LOOP; WHILE loop WHILE condition LOOP ... /* statements */ ... END LOOP; WHILE condition LOOP ... EXIT WHEN condition; ... END LOOP; FOR loop FOR i IN 1..10 LOOP /* will execute 10 times */ .... END LOOP; FOR i IN REVERSE 1..10 LOOP -- starts from 10 -- will execute 10 times ... END LOOP; SQL statements in PL/SQL • SELECT, UPDATE, INSERT, DELETE statements can be used directly in PL/SQL • UPDATE, INSERT, DELETE can be used as in SQLPlus • SELECT statement returns results: • SELECT INTO can be used for statements that return one row • FOR loop can be used to iterate through the results • CURSOR can be used to fetch SELECT statement results SQL statements in PL/SQL • SELECT, UPDATE, INSERT, DELETE statements can be used directly in PL/SQL – UPDATE, INSERT, DELETE can be used as in SQLPlus – SELECT statement returns results: • SELECT INTO can be used for statements that return one row • FOR loop can be used to iterate through the results • CURSOR can be used to fetch SELECT statement results SQL statements in PL/SQL • COMMIT, ROLLBACK, SAVEPOINT can be used in PL/SQL • DDL statements cannot be used in PL/SQL directly • PL/SQL variables can be used in SQL statements: DECLARE cnt NUMBER; BEGIN SELECT count(*) INTO cnt FROM table1; UPDATE table2 SET col1 = cnt WHERE id = 3; END; SQL statements in PL/SQL • Oracle compiles PL/SQL code. • Tables used in PL/SQL statements must exist when the code is compiled • Table, column names are fixed when the code is compiled. It is not possible to use dynamic table name like that: DECLARE tab_name VARCHAR2(30) := 'TABLE1'; BEGIN UPDATE tab_name SET col1 = 0; -- error SQL statements in PL/SQL • In the following statement: UPDATE tab1 SET value = value1 • tab1 is a name of existing database table, to which current user must have access to. If the table does not exist, compilation error is reported • value is a name of a column in table tab1 • value1 can be a name of PL/SQL variable or name of a column in table tab1 Illegal PL/SQL code • The following code is illegal CREATE FUNCTION count_rows (table_name IN VARCHAR2) RETURN NUMBER IS cnt NUMBER; BEGIN SELECT count(*) INTO cnt FROM table_name; RETURN cnt; END; SELECT statement in PL/SQL • SELECT INTO: SELECT x, y, z INTO var1, var2, var3 FROM ...; • x, y, z are table column names • var1, var2, var3 are PL/SQL variables • Statement must return exactly one row: • when no rows are returned NO_DATA_FOUND exception is thrown • when more than one row is returned TOO_MANY_ROWS exception is thrown SELECT statement in PL/SQL • SELECT INTO example: BEGIN BEGIN SELECT col1 INTO val1 FROM table1; EXCEPTION WHEN NO_DATA_FOUND THEN val1 := NULL; END; ... END; SELECT statement in PL/SQL FOR rec IN (SELECT * FROM TABLE1) LOOP IF rec.id > 100 THEN EXIT; END IF; END LOOP; • SQL statement must be in brackets • FOR LOOP variable is of type record. It has all the columns from the SELECT statement • The loop is executed for each row returned from the SELECT statement • SELECT statement can return any number of rows (also 0) CURSORS DECLARE CURSOR c1 IS SELECT ename, job FROM emp WHERE sal < 3000; ... BEGIN OPEN c1; FETCH c1 INTO var1, var2; IF c1%NOTFOUND THEN ... END IF; CLOSE c1; END; CURSOR with parameter DECLARE CURSOR c1(v NUMBER) IS SELECT ename, job FROM emp WHERE sal < v; value1 NUMBER; BEGIN OPEN c1(value1); LOOP FETCH c1 INTO var1, var2; EXIT WHEN c1%NOTFOUND; END LOOP; CLOSE c1; END; CURSOR for loop DECLARE CURSOR c1(v NUMBER) IS SELECT ename, job FROM emp WHERE sal < v; BEGIN FOR c1_rec in c1(10) LOOP ... END LOOP; END; Anonymous blocks [DECLARE -- variable declarations] BEGIN -- statements END; • Anonymous blocks can be used • in SQLPlus • in Java and other languages • as sub-block of larger PL/SQL block • DECLARE part is optional, must be used if variables are declared in anonymous block Anonymous block example SQLPLUS=> BEGIN FOR i IN 1 .. 1000 LOOP INSERT INTO tab1 VALUES(i); END LOOP; END; / Note: • "/" at the end is not part of the PL/SQL language, it is just a signal to PL/SQL that block code is finished and should be executed. Anonymous block example Connection conn = getDbConnection(); PreparedStatement pstm=conn.prepareStatement( "BEGIN proc1; END;"); pstm.executeUpdate(); -- executes procedure proc1 Note: • There is no "/" at the end of a block called from Java or other languages Anonymous sub-block • Anonymous blocks: ... -- large PL/SQL block IF condition THEN DECLARE local_variable ...; BEGIN statements; END; END IF; ... -- large block continues Procedures • Procedure (as in Pascal) – function without result CREATE PROCEDURE procedureName (param1 IN NUMBER, param2 INTEGER, -- default is IN param3 IN OUT VARCHAR2, param4 OUT DATE) IS localVar INTEGER; localVar1 VARCHAR2(100); BEGIN statements; END; / Procedures • Local variable declarations follow after IS without DECLARE keyword • The procedure ends with the "END;" • The final "/" is used to signal to SQLPlus that the function body is finished. After the "/" SQLPlus will create the procedure Parameter types • Parameter types are IN, IN OUT and OUT: • IN – caller passes input parameter to the procedure. Parameter value can be changed in the procedure, but caller will not see these changes • IN OUT – input/output parameter, caller will see changes to parameter value • OUT – output parameter, value is returned to the caller • Default parameter type is IN Default parameter values • Procedure and function parameters can have default values • Parameter with default value does not have to be specified by the caller: CREATE PROCEDURE proc( p1 IN NUMBER DEFAULT 0) IS BEGIN ... END; / BEGIN proc(1); -- p1 = 1 proc; -- p1 = 0 Passing parameters • Parameters can be passed using three methods: • positional – parameters are specified in the same order as they are declared in the procedure: proc1(1, 2, 'text value'); • named – parameter name is specified along with its value. proc1(p1 => 1, p2 => 2, p3 => 'text value'); • mixed – first parameters using positional notation, the remaining using named notation: proc1(1, p3 => 'text value'); Functions CREATE FUNCTION functionName (param1 IN NUMBER) RETURN VARCHAR2 IS localVar INTEGER; localVar1 VARCHAR2(100); BEGIN statements; RETURN localVar1; END; /
© Copyright 2026 Paperzz