ice*_*fex 21 postgresql plpgsql
我目前正在尝试使用 PL/pgSQL,想知道是否有更优雅的方法来做这样的事情:
select c.data into data from doc c where c.doc_id = id and c.group_cur > group_cur order by c.id desc limit 1;
EXCEPTION
WHEN NO_DATA_FOUND THEN
select c.data into data from doc c where c.doc_id = id and c.global_cur > global_cur order by c.id desc limit 1;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
Run Code Online (Sandbox Code Playgroud)
fil*_*rem 23
异常块用于捕获错误,而不是检查条件。换句话说,如果某些条件可以在编译时处理,则不应将其捕获为错误,而是由普通程序逻辑解决。
在PL/PgSQL 文档的 Trapping Errors 部分,您可以找到这样的提示:
提示:包含 EXCEPTION 子句的块比没有 EXCEPTION 子句的块进入和退出的成本要高得多。因此,不要在不需要的情况下使用 EXCEPTION。
代替使用异常(坏)或 IF/THEN/ELSIF(更好),您可以将其重写为一个查询:
SELECT c.data into data
FROM doc c
WHERE c.doc_id = id
and (
c.group_cur > group_cur
or
c.global_cur > global_cur
)
ORDER BY
-- this will make group always preferred over global
case when c.group_cur > group_cur then 1 else 2 end ASC,
-- and this is your normal ordering
c.id DESC
limit 1;
Run Code Online (Sandbox Code Playgroud)
如果你真的想要两个查询,你可以使用特殊的 FOUND 变量来测试上一个查询是否给出了任何结果:
select c.data into data
from doc c
where c.doc_id = id and c.group_cur > group_cur
order by c.id desc limit 1;
if not found then
select c.data into data
from doc c
where c.doc_id = id and c.global_cur > global_cur
order by c.id desc limit 1;
if not found then return null; end if;
end if;
Run Code Online (Sandbox Code Playgroud)
强制性 RTFM 链接如下:-)
看到此用于描述FOUND
可变的,并且这对于IF
/THEN
块。
ale*_*exk 16
您可以检查布尔类型的特殊变量 FOUND。从文档:
FOUND 在每个 PL/pgSQL 函数调用中以 false 开始。它由以下每种类型的语句设置:
SELECT INTO 语句将 FOUND 设置为在分配了行时为真,如果没有返回行则为假。
如果 PERFORM 语句生成(并丢弃)一行或多行,则将 FOUND 设置为 true,如果没有生成行,则设置为 false。
如果至少有一行受到影响,UPDATE、INSERT 和 DELETE 语句将 FOUND 设置为 true,如果没有行受到影响,则设置为 false。
如果 FETCH 语句返回一行,则将 FOUND 设置为 true,如果没有返回行,则设置为 false。
如果 MOVE 语句成功地重新定位游标,则将 FOUND 设置为 true,否则设置为 false。
FOR 或 FOREACH 语句在迭代一次或多次时将 FOUND 设置为 true,否则设置为 false。FOUND 在循环退出时以这种方式设置;在循环执行过程中,FOUND 不会被循环语句修改,尽管它可能会被循环体内其他语句的执行所改变。
如果查询至少返回一行,则 RETURN QUERY 和 RETURN QUERY EXECUTE 语句将 FOUND 设置为 true,如果没有返回任何行,则设置为 false。
其他 PL/pgSQL 语句不会改变 FOUND 的状态。请特别注意,EXECUTE 会更改 GET DIAGNOSTICS 的输出,但不会更改 FOUND。
FOUND 是每个 PL/pgSQL 函数中的局部变量;对它的任何更改仅影响当前功能。
归档时间: |
|
查看次数: |
56138 次 |
最近记录: |