1. 创建PSM函数和过程
创建过程:
CREATE PROCEDURE 名字 (参数)
局部声明;
过程体;
创建函数:
CREATE FUNCTION 名字 (参数) RETURNS 类型
局部声明;
过程体;
过程的参数:模式-名字-类型的三元组。模式有 IN, OUT, INOUT,默认为IN
函数的参数:只能是IN。
CREATE PROCEDURE Move( IN oldAddr VARCHAR(255), IN newAddr VARCHAR(255) ) UPDATE MovieStar SET address = newAddress WHERE address = oldAddress;
2. PSM中的简单语句
2.1 调用语句:
CALL 过程名 (参数)
在宿主语言中调用形式:EXEC SQL CALL Foo(:x, 3);
作为另一个PSM中的语句
作为发送给基本SQL界面的SQL命令(不许调用函数):CALL Foo(1, 3);
2.2 返回语句:
RETURN 表达式;
只能出现在函数中,PSM的返回语句不会结束这个函数,在函数完成之前返回值都可能会改变。
2.3 局部变量声明
DECLARE 名字 类型;
2.4 赋值语句
SET 变量 = 表达式;
2.5 语句组
以分号结束,置于BEGIN和END之间
2.6 语句标号
用名字和冒号作为前缀来标识语句。
3.分支语句
IF <condition> THEN
<statement list>
ELSEIF <condition> THEN
<statement list>
ELSEIF
...
ELSE
<statement list>
END IF;
CREATE FUNCTION BandW(y INT, s CHAR(15)) RETURN BOOLEAN IF NOT EXISTS( SELECT * FROM Movies WHERE year = y AND studioName = s) THEN RETURN TRUE; ELSEIF 1 <= (SELECT COUNT(*) FROM Movies WHERE year = y AND studioName = s AND genre = 'comedy') THEN RETURN TRUE; ELSE RETURN FALSE; END IF;
4. PSM中的查询
可以有多种查询方式:
①使用子查询
②返回单一值的查询可用在赋值语句的右边
③使用单元组选择语句
CREATE PROCEDURE SomeProc(IN studioName CHAR(15)) DECLARE presNetWorth INTEGER; SELECT netWorth INTO presNetWorth FROM Studio, MovieExec WHERE presC# = cert# AND Studio.name = studioName; ...
④ 声明和使用游标
语句中不需要出现EXEC SQL
局部变量不使用冒号前缀
5.PSM中的循环
LOOP
<语句列表>
END LOOP;
中断循环: LEAVE 循环标识;
定义与SQLSTATE值相对应的条件名:
DECLARE 名字 CONDITION FOR SQLSTATE 值;
CREATE PROCEDURE MeanVar( IN s CHAR(15), OUT mean REAL, OUT variance REAL ) DECLARE Not_Found CONDITION FOR SQLSTATE '02000'; DECLARE MovieCursor CURSOR FOR SELECT length FROM Movies WHERE studioName = s; DECLARE newLength INTEGER; DECLARE movieCount INTEGER; BEGIN SET mean = 0.0; SET variance = 0.0; SET movieCount = 0; OPEN MovieCursor; movieLoop: LOOP FETCH FROM MovieCursor INTO newLength; IF Not_Found THEN LEAVE movieLoop END IF; SET movieCount = movieCount + 1; SET mean = mean + newLength; SET variance = variance + newLength * newLength; END LOOP; SET mean = mean / movieCount; SET variance = variance / movieCount - mean * mean; CLOSE MovieCursor; END;
6.循环
FOR循环
FOR <loop name> AS <cursor name> CURSOR FOR <query>
DO
<statement list>
END FOR;
WHILE循环:
WHILE <条件> DO
<语句列表>
END WHILE;
REPEAT循环:
REPEAT
<语句列表>
UNTIL <条件>
END REPEAT
CREATE PROCEDURE MeanVar( IN s CHAR(15), OUT mean REAL, OUT variance REAL ) DECLARE movieCount INTEGER; BEGIN SET mean = 0.0; SET variance = 0.0; SET movieCount = 0; FOR movieLoop AS MovieCursor CURSOR FOR SELECT length FROM Movies WHERE studioName = s; DO SET movieCount = movieCount + 1; SET mean = mean + length; SET variance = variance + length * length; END FOR; SET mean = mean / movieCount; SET variance = variance / movieCount - mean * mean; END;
注意,在FOR循环中,用属性名表示查询结果!
7. PSM中的异常处理
DECLARE <下一步到哪里> HANDLER FOR <条件列表>
<语句>
转移的方式有下面三种:
CONTINUE:表示执行异常处理语句后,继续执行产生异常语句之后的语句
EXIT:表示执行异常处理语句后,离开异常处理的BEGIN END块,下一步执行该代码块之后的语句。
UNDO:与EXIT差不多,但是撤销已执行的该块语句对数据库和局部变化的影响。
CREATE FUNCTION GetYear(t VARCHAR(255)) RETURN INTEGER DECLARE Not_Found CONDITION FOR SQLSTATE '02000'; DECLARE Too_Many CONDITION FOR SQLSTATE '21000'; BEGIN DECLARE EXIT HANDLER FOR Not_Found, Too_Many RETURN NULL; RETURN (SELECT year FROM Movies WHERE title = t); END;
8.使用PSM函数和过程
可以像下面这样使用
INSERT INTO StarsIn(movieTitle, movieYear, starName) VALUES('Remember the Titans', GetYear('Remember the Titans'), 'Denzel Washington');