【6】PostgreSQL 循环

前言

在PostgreSQL中,可以通过以下几种方法进行循环:

  1. WHILE循环:使用WHILE条件循环语句,当满足条件时执行循环体内的代码,直到条件不再满足时跳出循环。
WHILE condition LOOP
-- 循环体内的代码
END LOOP;
  1. FOR循环:使用FOR循环语句,可以遍历一个集合或者执行一定次数的循环。
FOR i IN 1..10 LOOP
-- 循环体内的代码
END LOOP;
  1. LOOP循环:使用简单的LOOP语句创建一个无限循环,在循环体内部可以通过条件语句和BREAK语句来控制循环的终止条件。
LOOP-- 循环体内的代码IF condition THENEXIT;END IF;
END LOOP;

笔记

WHILE 循环

基本结构

在PL/pgSQL中,WHILE循环的基本结构如下:

DECLAREcounter INT := 0;
BEGINWHILE counter < 10 LOOP-- 执行一些操作counter := counter + 1;END LOOP;
END;

简单示例

WHILE 循环在执行循环体之前先检查条件,如果条件为真,则执行循环体。

DO $$
DECLAREcounter INT := 0;
BEGINWHILE counter < 10 LOOPRAISE NOTICE 'Counter: %', counter;counter := counter + 1;END LOOP;
END $$;

详细示例

假设我们要实现一个函数,该函数接受一个字符串,并在每个单词前添加一个编号。我们可以使用WHILE循环来遍历字符串中的每个单词,并为每个单词添加编号。

创建示例函数
CREATE OR REPLACE FUNCTION add_number_to_words(input_str TEXT) 
RETURNS TEXT 
LANGUAGE plpgsql 
AS $$
DECLAREresult TEXT := '';        -- 用于存储结果字符串word TEXT;                -- 用于存储当前处理的单词counter INT := 1;         -- 用于编号word_array TEXT[];        -- 用于存储拆分的单词数组i INT := 1;               -- 循环计数器
BEGIN-- 使用正则表达式将输入字符串拆分为单词数组word_array := regexp_split_to_array(input_str, '\s+');-- 获取单词数组的长度WHILE i <= array_length(word_array, 1) LOOPword := word_array[i];-- 如果结果字符串不为空,则添加空格IF result <> '' THENresult := result || ' ';END IF;-- 将编号和单词添加到结果字符串中result := result || counter || '. ' || word;-- 增加编号和循环计数器counter := counter + 1;i := i + 1;END LOOP;RETURN result;
END;
$$;
解释
  1. 变量声明
  • result:用于存储最终结果字符串。
  • word:用于存储当前处理的单词。
  • counter:用于为每个单词添加编号。
  • word_array:用于存储输入字符串拆分后的单词数组。
  • i:循环计数器,用于遍历单词数组。
  1. 字符串拆分
  • regexp_split_to_array(input_str, '\s+'):使用正则表达式将输入字符串按空格拆分成单词数组。
  1. **WHILE**** 循环**:
  • WHILE i <= array_length(word_array, 1) LOOP:循环遍历单词数组。
  • 在循环体内,首先将当前单词存储到word变量中。
  • 如果result字符串不为空,则在result字符串后添加一个空格。
  • 将编号和当前单词添加到result字符串中。
  • 增加编号counter和循环计数器i
  1. 返回结果
  • 循环结束后,返回结果字符串result
调用示例函数
SELECT add_number_to_words('Hello world this is a test');
预期输出
1. Hello 2. world 3. this 4. is 5. a 6. test

在这个例子中,WHILE循环用于遍历输入字符串拆分后的单词数组,并为每个单词添加一个编号。

FOR 循环

在PL/pgSQL中,FOR循环有几种形式:

  1. Numeric FOR Loop:用于遍历一系列数值。
  2. Reverse Numeric FOR Loop:用于反向遍历一系列数值。
  3. FOREACH Loop:用于遍历数组或集合类型。

Numeric FOR Loop

用于执行一系列数值的循环。

基本结构

Numeric FOR Loop 在 PL/pgSQL 中的基本结构如下所示:

FOR 变量名 IN 开始值..结束值 LOOP-- 循环体
END LOOP;

在这个结构中:

  • 变量名:循环计数器的名称,用于迭代循环。
  • 开始值:循环计数器的起始值。
  • 结束值:循环计数器的结束值。
  • 循环体:在 LOOP 和 END LOOP 之间的部分,包含需要重复执行的代码块。

在循环的每次迭代中,变量名将从 开始值 递增(或递减)到 结束值,并在每次迭代中执行循环体中的代码。

简单示例

例如,以下是一个简单的示例,演示如何使用 Numeric FOR Loop 打印出 1 到 10 之间的所有整数:

DO $$
DECLAREi INT;
BEGINFOR i IN 1..10 LOOPRAISE NOTICE 'Value: %', i;END LOOP;
END $$;

在上面的示例中,i 是循环计数器,它的初始值是 1,结束值是 10。在每次循环中,i 的值从 1 递增到 10,并且在每次迭代中打印出当前的值。

在或者,

DO $$
BEGINFOR counter IN 0..9 LOOPRAISE NOTICE 'Counter: %', counter;END LOOP;
END $$;
详细示例

假设我们要实现一个函数,该函数接受一个整数N,并返回从1到N的所有数值的平方。我们可以使用FOR循环来实现这个功能。

创建示例函数
CREATE OR REPLACE FUNCTION generate_squares(N INT) 
RETURNS TEXT 
LANGUAGE plpgsql 
AS $$
DECLAREresult TEXT := '';  -- 用于存储结果字符串i INT;              -- 循环计数器
BEGIN-- 使用 FOR 循环遍历从 1 到 N 的数值FOR i IN 1..N LOOP-- 将当前数值的平方添加到结果字符串IF result <> '' THENresult := result || ', ';END IF;result := result || i || '^2=' || (i * i);END LOOP;RETURN result;
END;
$$;
解释
  1. 变量声明
  • result:用于存储最终结果字符串。
  • i:循环计数器,用于遍历从1到N的数值。
  1. **FOR**** 循环**:
  • FOR i IN 1..N LOOP:循环遍历从1到N的数值。
  • 在循环体内,首先检查result字符串是否为空,如果不为空,则在result字符串后添加一个逗号和空格。
  • 将当前数值的平方(格式为i^2=x)添加到result字符串中。
  1. 返回结果
  • 循环结束后,返回结果字符串result
调用示例函数
SELECT generate_squares(5);
预期输出
1^2=1, 2^2=4, 3^2=9, 4^2=16, 5^2=25

在这个例子中,FOR循环用于遍历从1到N的数值,并生成这些数值的平方。

Reverse Numeric FOR Loop

用于执行一系列数值的反向循环。

基本格式
FOR 变量名 IN REVERSE 结束值..开始值 LOOP-- 循环体
END LOOP;

在这个结构中:

  • 变量名:循环计数器的名称,用于迭代循环。
  • 结束值:循环计数器的结束值。
  • 开始值:循环计数器的起始值。
  • 循环体:在 LOOPEND LOOP 之间的部分,包含需要重复执行的代码块。

在 Reverse Numeric FOR Loop 中,循环计数器的值从 结束值 开始递减,直到达到 开始值

简单示例

例如,以下是一个简单的示例,演示如何使用 Reverse Numeric FOR Loop 打印出 10 到 1 之间的所有整数:

DO $$
DECLAREi INT;
BEGINFOR i IN REVERSE 10..1 LOOPRAISE NOTICE 'Value: %', i;END LOOP;
END $$;

在上面的示例中,i 是循环计数器,它的结束值是 10,起始值是 1。在每次循环中,i 的值从 10 递减到 1,并且在每次迭代中打印出当前的值。

在或者,

DO $$
BEGINFOR counter IN REVERSE 9..0 LOOPRAISE NOTICE 'Counter: %', counter;END LOOP;
END $$;
详细说明

假设你需要编写一个函数,该函数接受一个整数 N 作为输入,然后从 N 开始递减,直到 1,并计算每个数的阶乘。

创建函数
CREATE OR REPLACE FUNCTION calculate_factorial(N INT)
RETURNS BIGINT
LANGUAGE plpgsql
AS $$
DECLAREresult BIGINT := 1;  -- 用于存储最终结果i INT;               -- 循环计数器
BEGINFOR i IN REVERSE N..1 LOOPresult := result * i;END LOOP;RETURN result;
END;
$$;
解释

在上面的示例中,我们创建了一个名为 calculate_factorial 的函数,它接受一个整数 N 作为输入,并返回 N 的阶乘。函数内部使用 Reverse Numeric FOR Loop 来递减地遍历从 N 到 1 的整数,并计算它们的乘积。在每次迭代中,循环计数器 i 的值递减,直到达到 1。

这个函数的执行过程如下:

  • 当 N = 5 时,循环将从 5 开始递减到 1,计算 5 _ 4 _ 3 _ 2 _ 1 的乘积,即 120。

Reverse Numeric FOR Loop 是在这个示例中实现递减序列的理想选择,它提供了一种简洁而清晰的方式来处理从大到小的循环迭代。

调用函数
SELECT calculate_factorial(5);
预期输出
120

FOREACH Loop

用于遍历数组或其他集合类型。

基本结构

FOREACH Loop 在 PL/pgSQL 中的基本结构如下所示:

FOREACH 循环变量 IN ARRAY 数组变量 LOOP-- 循环体
END LOOP;

在这个结构中:

  • 循环变量:用于迭代循环的临时变量,它将依次取数组中的每个元素。
  • 数组变量:要迭代的数组。
  • 循环体:在 LOOPEND LOOP 之间的部分,包含需要重复执行的代码块。

在每次迭代中,循环变量 将依次取数组中的每个元素,并执行循环体中的代码。

简单示例

例如,以下是一个简单的示例,演示如何使用 FOREACH Loop 遍历一个整数数组并打印出每个元素的值:

DO $$
DECLAREarr INT[] := ARRAY[1, 2, 3, 4, 5];elem INT;
BEGINFOREACH elem IN ARRAY arr LOOPRAISE NOTICE 'Element: %', elem;END LOOP;
END $$;

在上面的示例中,elem 是循环变量,它依次取数组 arr 中的每个元素。在每次迭代中,elem 的值将是数组中的当前元素,并且在每次迭代中打印出当前元素的值。

在或者,

DO $$
DECLAREarr INT[] := ARRAY[1, 2, 3, 4, 5];elem INT;
BEGINFOREACH elem IN ARRAY arr LOOPRAISE NOTICE 'Element: %', elem;END LOOP;
END $$;
详细示例

假设我们要实现一个函数,该函数接受一个整数数组,并返回数组中每个元素的平方。我们可以使用FOREACH循环来实现这个功能。

创建示例函数
CREATE OR REPLACE FUNCTION square_elements(input_array INT[]) 
RETURNS INT[] 
LANGUAGE plpgsql 
AS $$
DECLAREresult_array INT[] := '{}';  -- 用于存储结果数组elem INT;                    -- 用于存储当前处理的数组元素
BEGIN-- 使用 FOREACH 循环遍历数组中的每个元素FOREACH elem IN ARRAY input_array LOOP-- 将当前元素的平方添加到结果数组result_array := array_append(result_array, elem * elem);END LOOP;RETURN result_array;
END;
$$;
调用示例函数
SELECT square_elements(ARRAY[1, 2, 3, 4, 5]);
预期输出
{1, 4, 9, 16, 25}

在这个例子中,FOREACH循环用于遍历输入数组,并生成每个元素的平方。

Loop 循环

在 PL/pgSQL 中,LOOP 循环是一种无限循环结构,它不会像 FORWHILE 循环那样有明确的退出条件。

基本结构

基本的 LOOP 循环结构如下所示:

LOOP-- 循环体
END LOOP;

在这个结构中:

  • LOOP:表示进入循环的开始标记。
  • 循环体:在 LOOPEND LOOP 之间的部分,包含需要重复执行的代码块。
  • END LOOP:表示循环的结束标记。

LOOP 循环将一直执行循环体中的代码,直到遇到 EXIT 语句才会终止循环。

退出 LOOP 循环

要从 LOOP 循环中退出,可以使用 EXIT 语句。例如:

LOOP-- 循环体IF some_condition THENEXIT; -- 退出循环END IF;
END LOOP;

在上面的示例中,如果 some_condition 条件满足,则会执行 EXIT 语句,从而终止循环。

简单示例

以下是一个简单的示例,演示如何使用 LOOP 循环输出 1 到 5 的所有整数:

DO $$
DECLAREi INT := 1;
BEGINLOOPEXIT WHEN i > 5; -- 当 i 大于 5 时退出循环RAISE NOTICE 'Value: %', i;i := i + 1;END LOOP;
END $$;

在上面的示例中,LOOP 循环将一直执行,直到 i 的值大于 5,然后通过 EXIT 语句退出循环。在每次循环中,会打印出当前 i 的值。

详细示例

假设我们要实现一个简单的倒计时器,从某个初始值开始,每秒递减并打印出当前值,直到计时器归零。

创建函数
CREATE OR REPLACE FUNCTION countdown_timer(start_value INT)
RETURNS VOID
LANGUAGE plpgsql
AS $$
DECLAREcurrent_value INT := start_value;
BEGINLOOPEXIT WHEN current_value <= 0; -- 当当前值小于等于 0 时退出循环RAISE NOTICE 'Countdown: %', current_value;PERFORM pg_sleep(1); -- 暂停 1 秒current_value := current_value - 1; -- 递减当前值END LOOP;
END;
$$;
解释

在上面的示例中,我们创建了一个名为 countdown_timer 的函数,它接受一个整数 start_value 作为输入,并使用 LOOP 循环实现了倒计时器的逻辑。函数内部的循环将一直执行,直到 current_value 小于等于 0 时才退出循环。在每次循环中,会打印出当前的倒计时值,并通过 pg_sleep(1) 函数暂停 1 秒,然后将 current_value 递减 1。

调用函数
SELECT countdown_timer(10);
预期输出
Countdown: 10
Countdown: 9
Countdown: 8
Countdown: 7
Countdown: 6
Countdown: 5
Countdown: 4
Countdown: 3
Countdown: 2
Countdown: 1

这个示例展示了如何使用 LOOP 循环创建一个简单的倒计时器。LOOP 循环提供了一种简单而灵活的方式来实现这样的循环逻辑,而不需要明确的退出条件,只需在需要时使用 EXIT 语句即可退出循环。

扩展

EXIT 和 CONTINUE 控制

你可以使用EXIT从循环中提前退出,使用CONTINUE跳过本次循环并继续下一次循环。

使用 EXIT
DO $$
BEGINFOR counter IN 0..9 LOOPRAISE NOTICE 'Counter: %', counter;IF counter = 5 THENEXIT; -- 退出循环END IF;END LOOP;
END $$;-- 输出结果:
NOTICE:  Counter: 0
NOTICE:  Counter: 1
NOTICE:  Counter: 2
NOTICE:  Counter: 3
NOTICE:  Counter: 4
NOTICE:  Counter: 5
DO
postgres=# 
使用 CONTINUE
DO $$
BEGINFOR counter IN 0..9 LOOPIF counter = 5 THENCONTINUE; -- 跳过本次循环END IF;RAISE NOTICE 'Counter: %', counter;END LOOP;
END $$;-- 输出结果:
NOTICE:  Counter: 0
NOTICE:  Counter: 1
NOTICE:  Counter: 2
NOTICE:  Counter: 3
NOTICE:  Counter: 4
NOTICE:  Counter: 6
NOTICE:  Counter: 7
NOTICE:  Counter: 8
NOTICE:  Counter: 9
DO
postgres=# 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/840254.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[C][字符串][字符串常用函数介绍]详细讲解

目录 0.前言1.gets2.strlen3.strcpy4.strncpy5.strcat - (效率低)6.strncat7.strcmp8.strncmp9.strstr10.strtok11.strerror12.perror(相对于strerror可能更好用)13.ctype.h14.memcpy15.memmove16.memcmp17.memset18.atoi 0.前言 本篇主要介绍处理字符和字符串的库函数的使用及…

【C语言】文件的编译链接和预处理

文件的编译链接和预处理 程序的翻译环境和执行环境翻译环境预处理&#xff08;预编译&#xff09;过程编译过程汇编过程链接过程 运行环境 预处理详解预处理符号预处理指令#define#define定义标识符#define定义宏#define替换规则 #与###的使用##的使用 带有副作用的宏参数宏与函…

软考之信息系统管理知识点(1)

信息系统管理知识点 计算机中的CPU主要由运算单元、控制单元、寄存器组和时序电路等组成&#xff1b; 运算单元是对数据进行加工的部件&#xff0c;主要完成算术运算和逻辑运算。控制单元主要是从主存取出指令进行分析&#xff0c;控制其他部件完成指令的功能。寄存器组既可以用…

超详细的前后端实战项目(Spring系列加上vue3)前端篇(二)(一步步实现+源码)

好了&#xff0c;兄弟们&#xff0c;继昨天的项目之后&#xff0c;开始继续敲前端代码&#xff0c;完成前端部分 昨天完成了全局页面的代码&#xff0c;和登录页面的代码&#xff0c;不过昨天的代码还有一些需要补充的&#xff0c;这里添加一下 内容补充&#xff1a;在调用登…

Spring (16)Spring Boot Starter是什么

Spring Boot Starter是Spring Boot的一个核心特性&#xff0c;它提供了一种快速、简便的方式来引入和管理项目依赖。通过Starters&#xff0c;开发者可以轻松地将必要的依赖集成到项目中&#xff0c;无需手动指定每个库的版本。Starters包含了一组自动配置的模板&#xff0c;这…

代码随想录算法训练营第36期DAY38

DAY38 435无重叠区间 昨晚很快就想出来了&#xff0c;今天相当于二刷。 class Solution {public: static bool mycmp(vector<int>&a,vector<int>&b){ return a[1]<b[1]; } int eraseOverlapIntervals(vector<vector<int>&g…

sql查询,直接返回json数组格式

文章目录 数据库查询&#xff0c;并且sql直接返回json格式 数据库查询&#xff0c;并且sql直接返回json格式 SELECTJSON_ARRAYAGG(JSON_OBJECT(groupId, g.id,groupName, g.NAME,groupColor, g.group_color,num, COALESCE(c.num, 0),type, g.type)) AS result FROMxbd_group g…

如何部署一个基本符合ERC20的智能合约

运行genache-cli 运行以下命令genache-cli下载MetaMask浏览器拓展钱包 添加账户 导入账户 输入genache-cli生成其中的密钥 选择【显示测试网络】点击【添加网络】 添加自己本地的网络 选择该测试网络&#xff0c;账号里就会有100RETH 在remix里接通这个测试帐号 …

10.2.k8s的附加组件-Metrics-server组件与hpa资源pod水平伸缩

目录 一、概述 二、安装部署Metrics-Server组件 1.下载Metrics-Server资源清单 2.编辑Metrics-Server的资源清单 3.验证Metrics-Server是否成功安装 4.使用top命令测试是否管用 三、hpa资源实现pod水平伸缩&#xff08;自动扩缩容&#xff09; 1.编写deploy资源清单 2.…

Sap Hana 数据迁移同步优化(二)

简述 CloudCanal 近期对 Hana 源端链路做了新一轮优化&#xff0c;这篇文章简要做下分享。 本轮优化主要包含: 表级别 CDC 表表级别任务位点表级别触发器 单 CDC 表的问题 CloudCanal 在实现 Hana 源端增量同步时&#xff0c;最初采用的是单 CDC 表的模式。 即所有订阅表…

【C语言】深入理解指针(一)(上)

本篇文章将讲解&#xff1a; &#xff08;1&#xff09;内存和地址 &#xff08;2&#xff09;指针变量和细致 &#xff08;3&#xff09;指针变量类型的意义 一&#xff1a;内存和地址 &#xff08;1&#xff09;内存 在讲内存和地址之前&#xff0c;我们讲一个生活中的…

Three.js 研究:1、如何让物体动起来

1、制作模型动画 2、模型动画在代码中的调用 使用这个例子进行修改&#xff0c;使他能动作webgl_animation_skinning_morph.html 制作好的模型放到如下路径 /three.js-master/examples/models/gltf/无标题.gltf修改加载模型文件的地址 修改动画名称 运行 点击动画后&…

彩虹聚合二级域名DNS管理系统源码v1.3

聚合DNS管理系统可以实现在一个网站内管理多个平台的域名解析&#xff0c; 目前已支持的域名平台有&#xff1a;阿里云、腾讯云、华为云、西部数码、CloudFlare。 本系统支持多用户&#xff0c;每个用户可分配不同的域名解析权限&#xff1b;支持API接口&#xff0c; 支持获…

Oracle 证书的重要性

随着信息技术的飞速发展&#xff0c;数据库管理已成为企业运营中不可或缺的一部分。Oracle作为全球领先的数据库管理系统提供商&#xff0c;其Oracle Certified Professional&#xff08;OCP&#xff09;认证已成为数据库管理员和开发人员追求的专业认证之一。本文将深入探讨Or…

标准化软件实施方案(直接套用即可)

软件实施方案 二、 项目介绍 三、 项目实施 四、 项目实施计划 五、 人员培训 六、 项目验收 七、 售后服务 八、 项目保障措施 软件开发全套资料获取&#xff1a;&#xff08;本文末个人名片也可直接获取&#xff09;软件开发全套资料_数字中台建设指南-CSDN博客 软件产品&am…

接口响应断言

目录 接口断言介绍接口断言方式介绍响应状态码断言 课程目标 掌握什么是接口断言。了解接口断言的多种方式。掌握如何对响应状态码完成断言。 思考 这两段代码是完整的接口自动化测试代码吗&#xff1f; …省略… when().get(“https://httpbin.ceshiren.com/get?namead&…

【LeetCode算法】第58题:最后一个单词的长度

目录 一、题目描述 二、初次解答 三、官方解法 四、总结 一、题目描述 二、初次解答 1. 思路&#xff1a;双指针法。low指向单词头&#xff0c;high指向单词后的空格&#xff0c;则high-low就是每个单词的长度。算法步骤&#xff1a;①low从头往后查找第一个非空格的字符&…

Python 将文件夹中的图片信息导入到 Excel 的表格

引言 在数据处理和管理的日常任务中&#xff0c;经常需要将文件夹中的图片文件信息&#xff08;如文件名、路径、创建日期、大小、分辨率等&#xff09;整理成一个 Excel 表格。这篇博客将介绍如何使用 Python 中的 wxPython 模块创建一个 GUI 应用&#xff0c;用户可以通过这…

display(a,b)什么意思

在Python中&#xff0c;如果你看到display(a,b)这样的代码&#xff0c;它通常意味着有人正在使用IPython.display模块中的display函数来同时显示两个对象。 IPython.display是Jupyter Notebook和JupyterLab等交互式计算环境的一部分&#xff0c;它提供了一种在笔记本中显示各种…

【Linux】用户级缓冲区

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…