PL/pgSQL
- plpgsql
- declarations
- %TYPE
- %ROWTYPE
- declarations
- raise
- DEBUG, LOG, INFO, NOTICE, WARNING, EXCEPTION
- 默认 EXCEPTION
caution
- 尽量避免 EXCEPTION - 过多影响性能
tip
- 不想要结果使用 PERFORM
- 内部逻辑对比
IF expression THEN ...
->SELECT expression
IF x < y THEN ...
->PREPARE statement_name(integer, integer) AS SELECT $1 < $2
- 语句
- SELECT, INSERT, UPDATE, DELETE + INTO
- PERFORM - 执行不返回结果语句
- EXECUTE - 执行动态构建的语句
GET [ CURRENT ] DIAGNOSTICS variable { = | := } item [ , ... ]
获取结果状态- ROW_COUNT
- PG_CONTEXT
- NULL - noop
- COMMIT
- ROLLBACK
- RAISE
- ASSERT
- 控制流
- RETURN
- RETURN NEXT, RETURN QUERY, RETURN QUERY EXECUTE
- 定义返回结果,还需要执行 RETURN 才会返回
- 返回前结果会全部存储 - 因此不要返回大量的数据
EXIT [ label ] [ WHEN boolean-expression ]
- 跳出 BLOCK - 类似 break
CONTINUE [ label ] [ WHEN boolean-expression ]
- IF/THEN/ELSE/ELSIF/END IF
- CASE/WHEN/ELSE/END CASE
- LOOP/END LOOP
- WHILE/LOOP/END LOOP
- FOR/IN/LOOP/END LOOP - 便利结果、数字
- FOREACH/IN ARRYAY/LOOP/END LOOP - 便利数组
- EXCEPTION/WHEN/THEN
GET STACKED DIAGNOSTICS variable { = | := } item [ , ... ]
- 获取异常信息
- cursor
- 定义
refcursor
CURSOR FOR SELECT * FROM tenk1
CURSOR (key integer) FOR SELECT * FROM tenk1 WHERE unique1 = key
- OPEN/FOR
- OPEN/FOR EXECUTE
- FETCH/INTO
- MOVE - 类似 FETCH 但不返回结果
UPDATE table SET ... WHERE CURRENT OF cursor
- 要求 cursor 没有 聚合
- 建议添加 FOR UPDATE
DELETE FROM table WHERE CURRENT OF cursor
- CLOSE
- FOR/IN/LOOP/END LOOP
- 定义
- trigger
整体结构
[ <<label>> ]
[ DECLARE
declarations ]
BEGIN
statements
END [ label ];
print_strict_params 辅助调试
CREATE FUNCTION get_userid(username text) RETURNS int
AS $$
#print_strict_params on
DECLARE
userid int;
BEGIN
SELECT users.userid INTO STRICT userid
FROM users WHERE users.username = get_userid.username;
RETURN userid;
END;
$$ LANGUAGE plpgsql;
FOR 支持 REVERSE 和 BY
FOR i IN REVERSE 10..1 BY 2 LOOP
-- i will take on the values 10,8,6,4,2 within the loop
END LOOP;
- 函数隐含最外层 block - label 为函数名字
- 包含 DIAGNOSTICS 信息
- 隐含 FOUND 变量 - 当语句有值时会设置
- SELECT INTO
- PERFORM
- UPDATE, INSERT, DELETE
- FETCH
- MOVE
- FOR, FOREACH
- RETURN QUERY, RETURN QUERY EXECUTE
使用隐含的 FOUND 变量
SELECT * INTO STRICT myrec FROM emp WHERE empname = myname;
IF NOT FOUND THEN
RAISE EXCEPTION 'employee % not found', myname;
END IF;
- select into STRICT 单个 record 可能的异常 code
- NO_DATA_FOUND
- TOO_MANY_ROWS
- 没有 STRICT 直接返回第一条,没有则是 NULL
-- strict_multi_assignment
-- too_many_rows
SET plpgsql.extra_warnings TO 'shadowed_variables';
#variable_conflict error
#variable_conflict use_variable
#variable_conflict use_column