Stored Procedures and SQL PL
Stored Procedures and SQL PL
1
The SQL Procedure Language
A SQL PL Header
CREATE PROCEDURE SPA80 (IN P_DNO CHAR(3)
,OUT P_CNT SMALLINT
Parameters
,OUT P_SUMSAL DECIMAL(11,2)
,OUT P_RETCODE INTEGER )
VERSION V1
• Procedure Name
• 128 byte max length
• Unique within Schema / Collection
• Schema / Collection ID will be supplied when create is deployed
• Parameters
• 128 byte max length
• Can be IN bound, OUT bound or INOUT (both directions)
• Used to pass data between procedure and caller
• Cannot specify a default value
• Versioning
• 64 EBCDIC bytes max length
• If using versioning do not use the default V1 naming convention
A SQL PL Body
The body consists of 5 parts:
• SQL variable declarations
• Condition names
• Cursors
• Condition Handlers
• Code…
2
The SQL Procedure Language
A SQL PL Body
…
… Clear your
P1: BEGIN outbound
SET P_CNT = 0;
SET P_SUMSAL = 0; Assign Values
parms
SET P_RETCODE = 0;
3
The SQL Procedure Language
Assignment Statement
Assigns a value to an output parameter or to an SQL variable
4
The SQL Procedure Language
SET V2 = 1000;
SET V3 = 500.00;
.
.
.
END P1
IF Statement
DECLARE v_grade CHAR(1);
DECLARE v_a_count INTEGER;
DECLARE v_b_count INTEGER;
DECLARE v_invalid_count INTEGER;
...
UPDATE STUDENT SET GRADE = v_grade Watch
WHERE STUDENT_NO = var1; Your
IF v_grade = 'A' THEN Punctuation!
set v_a_count = v_a_count + 1;
ELSEIF v_grade = 'B' THEN
set v_b_count = v_b_count + 1;
ELSEIF . . . THEN . . .
ELSE
Set v_invalid_count = v_invalid_count + 1;
END IF;
5
The SQL Procedure Language
IF Statement
IF v_grade = 'A' THEN
set v_a_count = v_a_count + 1;
set v_counter = v_counter + 1;
ELSEIF v_grade = 'B' THEN
set v_b_count = v_b_count + 1;
set v_counter = v_counter + 1;
ELSEIF . . . THEN . . .
ELSE
Set v_invalid_count = v_invalid_count + 1;
END IF;
CASE Statement
1. Simple CASE: Testing for value of variable
CASE v_grade
WHEN 'A' THEN set v_a_count = v_a_count + 1;
set v_counter = v_counter + 1;
WHEN 'B' THEN set b_count = b_count + 1;
set v_counter = v_counter + 1;
ELSE set v_invalid_count = v_invalid_count + 1 ;
END CASE;
6
The SQL Procedure Language
REPEAT
FETCH CURSOR1 INTO VAR1, VAR2, VAR3;
IF SQLCODE = 100 THEN SET V_EOF = ‘Y’;
ELSE
<process values returned by cursor>
END IF;
UNTIL V_EOF = ‘Y’
END REPEAT;
WHILE Statement
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE V_EOF CHAR(1) DEFAULT ‘N’;
…
WHILE (V_EOF = ‘N’) DO
FETCH CURSOR1 INTO VAR1, VAR2, VAR3;
IF SQLCODE = 100 THEN
SET V_EOF = ‘Y’;
ELSE
<process a row> . . . ;
END IF;
END WHILE;
7
The SQL Procedure Language
FOR Statement
FOR FOR_ROUTINE AS
CURSOR1 CURSOR FOR
SELECT EMPNO, FIRSTNME, LASTNAME, SALARY
FROM EMP
WHERE DEPTNO = p_deptno
ORDER BY SALARY DESC
DO
SET v_numrows = v_numrows + 1;
SET v_salarytotal = v_salarytotal + SALARY;
END FOR;
Column from
Variables
CURSOR1
Native Only!
GOTO Statement
The GOTO transfers control to a labeled statement. The labeled statement
and the GOTO statement must be in the same scope.
8
The SQL Procedure Language
ITERATE Statement
The ITERATE statement causes the flow of control to return
to the beginning of a labeled loop.
WHILE_ROUTINE :
WHILE (MORE_RESULT = 0) DO
FETCH CURSOR1 INTO VAR1, VAR2, VAR3;
SET MORE_RESULT = SQLCODE;
IF VAR3 < 0 THEN
ITERATE WHILE_ROUTINE;
END IF ;
. . . ;
. . . ;
END WHILE;
Compound Statement
label:
BEGIN { NOT ATOMIC or ATOMIC }
[ SQL-variable-declaration ; …. ]
[ Declare Cursor statement ; …. ]
[ condition-declaration ; ………. ]
[ return-code-declaration ; …….. ]
[ handler-declaration ; …………. ]
SQL-procedure-statement; …
END { label }
9
The SQL Procedure Language
Compound Statement
P1 :
BEGIN
DECLARE SQLCODE INTEGER ;
DECLARE C1 CURSOR WITH RETURN ……..;
INSERT INTO AUDIT VALUES( PARMX, PARMY, PARMZ);
IF (SQLCODE = -803) THEN
…;
ELSE
…;
END IF;
INSERT …;
END P1;
SQL Statements
10
The SQL Procedure Language
P1: BEGIN
DECLARE SQLCODE INTEGER DEFAULT 0;
OPEN CURSOR1;
SET P_RETCODE = SQLCODE;
END P1
11
The SQL Procedure Language
Processing a Cursor
P1: BEGIN
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE V_EOC CHAR(1) DEFAULT 'N';
DECLARE V_SAL DECIMAL(9,2);
DECLARE C1 CURSOR FOR
SELECT SALARY FROM EMP
WHERE DEPTNO = P_DEPTNO;
OPEN C1;
SET P_SUM = 0;
REPEAT
FETCH C1 INTO V_SAL;
IF SQLCODE = 100 THEN
SET V_EOC = 'Y';
END IF;
SET P_SUM = P_SUM + V_SAL;
UNTIL V_EOC = 'Y'
END REPEAT;
CLOSE C1;
END P1
...
FETCH CURSOR1 INTO V1, V2;
IF SQLCODE = 100 THEN
SET EOF = 'Y';
12
The SQL Procedure Language
Unhandled Errors
CREATE PROCEDURE SPERR (OUT P_RETCODE INTEGER)
VERSION VERSION1
P1: BEGIN
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE V1 DATE;
SET P_RETCODE = 0;
SELECT DATE('2016-12-32')
INTO V1
FROM SYSIBM.SYSDUMMY1;
Execution Stops Here!!
SET P_RETCODE = SQLCODE;
END P1
Handlers
SQLEXCEPTION
EXIT SQLWARNING
DECLARE CONTINUE HANDLER FOR
NOT FOUND
SQLSTATE ‘value’
13
The SQL Procedure Language
14