Writing SQL Stored Procedures and Functions
Writing SQL Stored Procedures and Functions
SQL Procedures
(and Functions and Triggers)
Rob Bestgen
[email protected]
IBM - DB2 for i Consultant
1
1/14/2017
Supported languages
DB2 for i supports two types of procedures/functions/triggers
1. SQL
• Coded entirely with SQL following (PSM) Standard
• Allows full suite of SQL statements
2. External
• Register a high-level language program (RPG, COBOL, Java, C…) for
subsequent calls from SQL**
• may or may not use SQL within the program itself
Supported languages
DB2 for i supports two types of procedures/functions/triggers
1. SQL
• Coded entirely with SQL following (PSM) Standard
• Allows full suite of SQL statements
2. External
• Register a high-level language program (RPG, COBOL, Java, C…) for
subsequent calls from SQL**
• may or may not use SQL within the program itself
2
1/14/2017
SQL Routines
Comparison of SQL Routine types
Procedures
– Similar to high-level language program, facilitates reuse of common logic
– Usage is similar to any program
– Frequently used as the backend ‘service’ to application calls e.g. REST calls
Lessen network traffic
Secure data access
– Can also return result sets of data
Functions (user-defined)
– Returns a result each time it is invoked
– Frequently invoked from within an SQL query
SELECT myfunc1() FROM mytable WHERE myfunc2(col1)>100
Triggers
– Attached to a file/table. Invoked for data changes
– Automatically invoked by DB2 when necessary, regardless of interface
SQL Routines…
Each time an SQL Routine is created, DB2 for i uses the SQL
procedural source to generate a C program (or srvpgm) object
– Developer does not need to know C code
– C compiler purchase is not required
– Like other pgms, IBM i security model and adopted authorities apply
3
1/14/2017
Procedure
1 Create it
CREATE OR REPLACE PROCEDURE total_val (IN Member# CHAR(6),
OUT total DECIMAL(12,2))
LANGUAGE SQL
BEGIN
SELECT SUM(curr_balance) INTO total
FROM accounts
WHERE account_owner=Member# AND
account_type IN ('C','S','M');
END
Function
Two types:
1. Scalar function
– Returns a single value
– Invoked from almost any SQL statement
– Good for encapsulating complex operations or calculations
2. Table function
– Returns a set of rows with columns
• A dynamic table!
– Invoked from an SQL query or view (FROM clause)
– Good for encapsulating non-traditional data or complex operations
4
1/14/2017
Scalar Function
1 Create it (one time)
Table Function
1 Create it (one time)
5
1/14/2017
Trigger
A program called when a row(s) in a table or file change
Associated with a table (or view)
Invoked automatically by DB2 when a row changes
6
1/14/2017
A Common Language
END
ATOMIC
– All statements succeed or are rolled back
– COMMIT or ROLLBACK cannot be specified in the routine
– Must also be created with COMMIT ON RETURN YES
7
1/14/2017
Basic Constructs
DECLARE – define variable. Initialized when procedure is called
DECLARE v_midinit, v_edlevel CHAR(1);
DECLARE v_ordQuantity INT DEFAULT 0;
DECLARE v_enddate DATE DEFAULT NULL;
– Uninitialized variables set to NULL
– Single-dimension arrays
CREATE TYPE pids AS CHAR(3) ARRAY[ ];
CREATE TYPE intarray AS INTEGER ARRAY[5];
Conditional Constructs
IF statement
IF rating=1 THEN SET price=price * 0.95;
ELSEIF rating=2 THEN SET price=price * 0.90;
ELSE SET price=price * 0.80;
END IF;
CASE Expression
– First form: – Second form:
8
1/14/2017
Looping Constructs
FOR statement - execute a statement for each row of a query
Ex:
FOR loopvar AS
loopcursor CURSOR FOR
SELECT firstname, middinit, lastname FROM emptbl
DO
SET fullname=lastname||', ' || firstname||' ' || middinit;
INSERT INTO namestbl VALUES( fullname );
END FOR;
Looping Constructs
LOOP, REPEAT and WHILE statements
LOOP Example - REPEAT Example -
fetch_loop: r_loop:
LOOP REPEAT
FETCH cursor1 INTO FETCH cursor1 INTO
v_firstname, v_lastname; v_firstname, v_lastname;
IF SQLCODE <> 0 THEN …
LEAVE fetch_loop; UNTIL SQLCODE <> 0
END IF; END REPEAT;
…
END LOOP;
WHILE Example -
while_loop:
WHILE at_end=0 DO
NOTE: Though they look similar,
FETCH cursor1 INTO each example works differently!
v_firstname, v_lastname;
IF SQLCODE <> 0 THEN
SET at_end = 1;
END IF;
…
END WHILE;
18 © 2017 IBM Corporation
M
IB
9
1/14/2017
Default Parameters
SET options
SQL routine body
SET OPTION stmts
10
1/14/2017
Error Handling
and
Feedback
GET DIAGNOSTICS
SQLSTATE and SQLCODE variables
CONDITIONs and HANDLERs
SIGNAL and RESIGNAL
RETURN statement
11
1/14/2017
GET DIAGNOSTICS
– Retrieve information about last statement executed
• Row_count, return_status, error status….
– CURRENT or STACKED
• CURRENT – statement that was just executed
• STACKED – statement before error handler was entered
– Only allowed within error handler
– Example:
DECLARE update_counter INTEGER;
...
UPDATE orders SET status=‘LATE’
WHERE ship_date < CURRENT DATE;
GET DIAGNOSTICS update_counter = ROW_COUNT;
...
CONDITION
DECLARE condition name CONDITION FOR string constant;
– Allows alias for cryptic SQLSTATE
– Condition name must be unique within the Stored Procedure
HANDLER
DECLARE type HANDLER FOR condition;
– Type
•UNDO - rollback statements in compound statement (must be ATOMIC)
•CONTINUE – continue processing
•EXIT – exit compound statement
– Condition
•Defined condition (above)
•SQLSTATE ‘xxyzz’
• predefined: SQLWARNING, NOT FOUND, SQLEXCEPTION
12
1/14/2017
END
13
1/14/2017
END
14
1/14/2017
It is possible, and quite common, to mix Static SQL and Dynamic SQL in
the same procedure (or Function):
BEGIN
DECLARE NF INT DEFAULT 0;
DECLARE EOF INT DEFAULT 0;
DECLARE D_SQL VARCHAR(3000);
DECLARE D_ITEM_KEY CHAR(8);
DECLARE NOTFOUND CONDITION FOR '42704';
DECLARE CONTINUE HANDLER FOR NOTFOUND SET NF = 1;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000‘ SET EOF = 1;
SET D_SQL = 'SELECT ITEM_KEY FROM ‘ CONCAT DATALIB CONCAT ‘.’ CONCAT DATATABLE;
PREPARE ITEM_P FROM D_SQL;
BEGIN
DECLARE ITEM_CURSOR CURSOR FOR ITEM_P;
OPEN ITEM_CURSOR;
IF NF=1 THEN
...
RETURN;
END IF;
FETCH ITEM_CURSOR INTO D_ITEM_KEY;
FETCHLOOP: WHILE EOF=0
DO
…
END FETCHLOOP;
CLOSE ITEM_CURSOR;
END;
END;
15
1/14/2017
Routine Signatures
( , )
IN
data type
OUT parm name
INOUT
Note: default parameters support in v7r1+ and V7R2 makes this less heavy handed
16
1/14/2017
( , )
data type
parm name
Stored Procedure
Result Sets
17
1/14/2017
BEGIN
--Take the inputted region number, Region# and
--return the set of customers from that region
--via a result set
OPEN c1;
END;
18
1/14/2017
RETURN TO CALLER
Ex: DECLARE c1 CURSOR WITH RETURN TO CALLER FOR SELECT * FROM t1
Proc 1 Proc 1
. .
. RETURN .
RETURN . .
Proc n-1
TO
TO Proc n-1
CALLER
CLIENT
Proc n Proc n
…
DECLARE sprs1 RESULT_SET_LOCATOR VARYING;
CALL GetProjs(projdept);
ASSOCIATE LOCATOR (sprs1) WITH PROCEDURE GetProjs;
ALLOCATE mycur CURSOR FOR RESULT SET sprs1;
SET totstaff=0;
myloop: LOOP
FETCH mycur INTO prname, prstaff;
Easy
IF row_not_found=1 THEN
Integration!
LEAVE fetch_loop;
END IF;
SET totstaff= totstaff + prstaff;
IF prstaff > moststaff THEN
SET bigproj = prname; ** DESCRIBE PROCEDURE &
SET moststaff= prstaff; DESCRIBE CURSOR statements
can be used to dynamically
END IF;
determine the number and
END LOOP;
contents of a result set
CLOSE mycur;
…
38 © 2017 IBM Corporation
M
IB
19
1/14/2017
Programming considerations
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '42704'
BEGIN /* Table may or may not already exist*/
INSERT INTO error_log
VALUES(SESSION_USER, CURRENT TIMESTAMP, '42704');
END;
IF Setuplib.Create_Var='YES' THEN
DROP TABLE orders;
CREATE TABLE orders(ordID CHAR(6), ordQty INTEGER, ordCustID CHAR(5));
END IF;
END;
40 © 2017 IBM Corporation
M
IB
20
1/14/2017
21
1/14/2017
VALUES( SYSIBMADM.WRAP
(‘CREATE PROCEDURE chgSalary(IN empno CHAR(6))
LANGUAGE SQL BEGIN
UPDATE employee SET empsal = empsal*(1 + .05*empjobtype)
WHERE empid = empno; END’) );
CALL SYSIBMADM.CREATE_WRAPPED (
‘ CREATE PROCEDURE chgSalary(IN empno CHAR(6))
LANGUAGE SQL
BEGIN
UPDATE employee SET empsal = empsal*(1 + .05*empjobtype)
WHERE empid = empno; END’);
22
1/14/2017
Graphical Debuggers
– IBM i Graphical Debugger
• Not just for SQL Routines, any IBM i program
• Part of IBM Toolbox for Java
STRDBG command
23
1/14/2017
Console allows
usage of EVAL
commands
Program variables
displayed on the fly
24
1/14/2017
More Information
http://www.redbooks.ibm.com/redpieces/abstracts/sg248326.html
25
1/14/2017
Additional Information
DB2 for i Websites
– Homepage: www.ibm.com/systems/power/software/i
– Technology Updates
www.ibm.com/developerworks/ibmi/techupdates/db2
– developerWorks Zone: www.ibm.com/developerworks/data/products.html
Forums
– developerWorks:
https://ibm.com/developerworks/forums/forum.jspa?forumID=292
• RCAC
• Temporal Tables
26
1/14/2017
Thank you!
27