zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

《PostgreSQL服务器编程》一一3.3 条件表达式

postgresql服务器编程 条件 表达式 一一 3.3
2023-09-11 14:19:16 时间

本节书摘来自华章计算机《PostgreSQL服务器编程》一书中的第3章,第3.3节,作者:(美)Hannu Krosing, Jim Mlodgenski, Kirk Roybal 著
,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.3 条件表达式

条件表达式允许开发者通过明确的标准来控制函数的动作。下面这个例子使用了CASE语句,通过值来控制字符串的处理。如果该值为空,或者包含一个零长度字符串,则视为空。
image
image
image
image
image

这里的设想是,当全名中的任何一个元素缺失时,周边的标点符号和空格也应同时缺失。这个函数会返回一个美国人的全名,且希望名称的各个部分尽可能的完整。当运行这个函数时,我们会看到以下内容:
image
image

条件表达式的另外一种使用方法是使用IF/THEN/ELSE块。以下是相同的函数,但使用了IF语句而不是CASE语句。
image
image

PostgreSQL的PL/pgSQL里提供了这些条件表达式更多的语法变种。这里介绍了一些最常用的表达方式。你可以访问链接http://www.postgresql.org/docs/current/static/functions-conditional.html,查看更完整的讨论。
3.3.1 通过计数器循环
PL/ pgSQL语言为各元素之间的循环提供了一种简单的方法。以下函数将返回第n个斐波那契(Fibonacci)序列号:
image
image

以上代码的输出结果为3。
在这个函数中,我们可以计算出最高的斐波那契(Fibonacci)数是4785。如果参数的一个值比这个值大,结果就不符合我们所声明的长度为1000的小数。
仅作备忘,在斐波那契(Fibonacci)序列中每个元素都是序列中前2个元素的累加。因此,序列中前面几个元素应该是0,1,1,2,3,5,8,13,21,34,... 互联网上也提供了一些PostgreSQL斐波那契(Fibonacci)序列函数,但它们均使用了可怕的递归方法。对于我们这种情况,递归是一件非常糟糕的事情。
在这个函数中,我们在声明部分也介绍了变量的默认值。一旦调用函数,这些变量就会被设成默认值。
同时让我们快速看一下语句SELECT b,a+b INTO a,b,该语句同时进行2个?变量赋值。在执行a与b的过程中,它避免了第三个变量的引入。
你可以通过访问链接http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html,查看PostgreSQL文档页,来获取其他循环语法。
3.3.2 对查询结果进行循环
在我们开始对查询结果进行循环之前,我觉得有必要提醒你,如果你正在使用这个方法,你可能做错了。它是属于PostgreSQL中处理器与内存密集型的其中一种操作。我们基本无理由在数据库服务器上进行结果集的循环。我建议你进行一次深入思考,如何使用一个函数、查询中的值列表、临时表和永久表来实现同样的想法,或者采用任何可能的方法预先计算这个值,从而避免这种操作。因此,你仍然认为你有非常充分的理由来使用这项技术?好吧,请继续往下读。
以下是一个简单的版本:
image
image

上面的这个例子展示了任务队列中消息处理的基本策略格局。通过这个技术,表中的行包含了需要处理的任务。
我们在这里也介绍一下EXECUTE语句。SELECT语句是一个字符串值。通过EXECUTE,我们可以以字符串的形式动态构建PL / pgSQL命令,然后作为数据库的语句来调用它们。这个技术非常方便,特别是当我们准备改变表名称或者其他SQL关键字,来补充语句的时候。这些SQL语句部分不能存储在变量中,而且通常情况下不可变。借助EXECUTE,我们可以改变语句中的任何部分。
以下是来自PostgreSQL文档的一个例子,该例子展示了在循环内部运行的动态命令:
image

以上这个循环的例子显示了一个更复杂的函数,该函数刷新一些临时表中的数据。由于数据实际上是物理传输到临时表中,因此这些临时表被认为是“物化视图”。为了降低相同数据的查询执行开销,我们可以采取这种常见的方法。在这种情况下,相对于重复查询相同数据导致的持续开销,循环的低效率似乎又不值得一提。
3.3.3 PERFORM与SELECT
你可能在之前的例子中已经注意到一个我们并未介绍过的语句。PERFORM是一个命令。当想要放弃一个语句结果的时候,可以使用该命令。如果上面的例子改成:
image

查询引擎将返回No destination for result data。
我们可以将结果转换成变量,进而忽略变量,但这样有点不合我味。通过PERFORM语句,我们已经表明,忽略结果不是偶然的。我们很高兴看到这样一个事实,日志被盲目地叠加,但如果不是这样,我们可能由于日志条目问题而无法继续执行。