当前位置: 首页 > news >正文

创建简单的 PL/pgSQL 存储过程

文章目录

    • 创建简单的 PL/pgSQL 存储过程
        • CREATE OR REPLACE FUNCTION
        • add_two_numbers(a integer, b integer)
        • RETURNS integer
        • AS`$$ ... $$`
        • 函数体
        • LANGUAGE plpgsql
    • 创建带有 IN 和 OUT 参数的存储过程
    • 创建修改数据的存储过程
    • 创建带有异常处理的复杂存储过程

在 PostgreSQL 中,创建存储过程可以通过使用 CREATE FUNCTION 语句来实现。PostgreSQL 支持多种语言编写存储过程,包括 SQL、PL/pgSQL(Procedural Language/PostgreSQL)、PL/Python、PL/Perl 等。其中,PL/pgSQL 是最常用的内置过程语言。

创建简单的 PL/pgSQL 存储过程

假设我们想要创建一个存储过程,它接受两个整数作为输入参数,并返回它们的和。

-- 创建存储过程
CREATE OR REPLACE FUNCTION add_two_numbers(a integer, b integer)
RETURNS integer AS $$
BEGINRETURN a + b;
END;
$$ LANGUAGE plpgsql;-- 调用存储过程
SELECT add_two_numbers(3, 5);
CREATE OR REPLACE FUNCTION
  • CREATE:这是用来创建新对象的关键字。
  • OR REPLACE:如果已经存在同名的函数,OR REPLACE 会先删除旧的函数再创建新的。这在修改已有函数时非常有用,因为它避免了需要手动删除再创建的麻烦,并且可以在不中断服务的情况下更新函数逻辑。
add_two_numbers(a integer, b integer)
  • add_two_numbers:这是你给函数起的名字。你可以根据函数的功能为它取任何合法的名字。
  • (a integer, b integer):这部分定义了函数的参数列表。在这个例子中,函数有两个参数,分别是 a 和 b,并且它们的数据类型都是 integer(整数)。
RETURNS integer
  • RETURNS:指定函数将返回的数据类型。在这个例子中,函数返回的是一个 integer 类型的结果,即两个输入整数相加后的结果。
AS$$ ... $$
  • AS $$ 和后面的 $$:这两个符号标志着函数体的开始和结束。使用双美元符号($$)作为分隔符可以避免与 SQL 语句中的单引号冲突。当然,你也可以使用其他字符或字符串作为分隔符,例如 $$$BODY$ 等。
函数体
BEGINRETURN a + b;
END;
  • BEGIN ... END;:这一对关键字包围着 PL/pgSQL 代码块。PL/pgSQL 是 PostgreSQL 的过程化语言,允许你在数据库中编写更复杂的逻辑。
  • RETURN a + b;:这是函数体内的一条语句,表示返回两个参数 a 和 b 相加的结果。
LANGUAGE plpgsql

LANGUAGE:指定函数使用的编程语言。在这个例子中,plpgsql 表示使用的是 PostgreSQL 的内置过程化语言 PL/pgSQL。如果你使用的是另一种语言(如 SQL、PL/Python、PL/Perl),则应相应地更改这里的值。

创建带有 IN 和 OUT 参数的存储过程

如果你需要一个存储过程能够输出多个值,可以使用 OUT 参数。

-- 创建存储过程
CREATE OR REPLACE FUNCTION get_min_max(in_nums integer[])
RETURNS TABLE(min_val integer, max_val integer) AS $$
BEGINRETURN QUERY SELECT MIN(val), MAX(val) FROM unnest(in_nums) AS val;
END;
$$ LANGUAGE plpgsql;-- 调用存储过程
SELECT * FROM get_min_max(ARRAY[1, 2, 3, 4, 5]);

创建修改数据的存储过程

这里展示如何创建一个存储过程,该过程插入一条记录到表中。

-- 假设有一个名为 users 的表
CREATE TABLE IF NOT EXISTS users (id serial PRIMARY KEY,name text NOT NULL,age integer NOT NULL
);-- 创建存储过程
CREATE OR REPLACE PROCEDURE insert_user(user_name text, user_age integer)
LANGUAGE plpgsql
AS $$
BEGININSERT INTO users (name, age) VALUES (user_name, user_age);
END;
$$;-- 调用存储过程
CALL insert_user('Alice', 30);

请注意,从 PostgreSQL 11 开始,正式支持了 CREATE PROCEDURE 语法,用于创建不返回结果集的过程。在此之前版本中,你只能使用 CREATE FUNCTION 来创建过程,即使这些函数实际上并不返回任何有意义的值。

创建带有异常处理的复杂存储过程

对于更复杂的逻辑,你可以添加异常处理来增强程序的健壮性。

-- 创建存储过程
CREATE OR REPLACE PROCEDURE update_user(id integer, new_name text, new_age integer)
LANGUAGE plpgsql
AS $$
BEGINUPDATE usersSET name = new_name, age = new_ageWHERE users.id = id;IF NOT FOUND THENRAISE EXCEPTION 'User with ID % not found.', id;END IF;EXCEPTIONWHEN others THENRAISE NOTICE 'An error occurred: %', SQLERRM;-- 可以选择在此处记录日志或采取其他措施
END;
$$;-- 调用存储过程
CALL update_user(1, 'Bob', 28);

注意事项

  • 权限:确保创建存储过程的用户有足够的权限。
  • 事务管理:存储过程中的所有操作都在同一个事务中执行。如果过程中有任何错误发生,整个事务将被回滚。
  • 调试:可以在存储过程中使用 RAISE NOTICE 或 RAISE WARNING 来输出调试信息。
  • 性能考虑:尽量避免在存储过程中进行大量的行级操作,因为这可能会导致性能问题。

相关文章:

创建简单的 PL/pgSQL 存储过程

文章目录 创建简单的 PL/pgSQL 存储过程CREATE OR REPLACE FUNCTIONadd_two_numbers(a integer, b integer)RETURNS integerAS$$ ... $$函数体LANGUAGE plpgsql 创建带有 IN 和 OUT 参数的存储过程创建修改数据的存储过程创建带有异常处理的复杂存储过程 在 PostgreSQL 中&…...

Java项目实战II基于微信小程序的无中介租房系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 随着城市化进程的加速,租房市场日益繁荣&a…...

Node.js实现WebSocket教程

Node.js实现WebSocket教程 1. WebSocket简介 WebSocket是一种在单个TCP连接上提供全双工通信的协议,允许服务器和客户端之间进行实时、双向通信。本教程将详细讲解如何在Node.js中实现WebSocket。 2. 技术选型 我们将使用ws库来实现WebSocket服务器,…...

Docker Compose实战一( 轻松部署 Nginx)

通过过前面的文章(Docker Compose基础语法)你已经掌握基本语法和常用指令认识到Docker Compose作为一款强大工具的重要性,它极大地简化了多容器Docker应用程序的部署与管理流程。本文将详细介绍如何使用 Docker Compose 部署 Nginx&#xff0…...

hive分区分桶、数据倾斜总结

一、hive的基本概念 hive是一个构建在hadoop上的数据仓库工具,可以将结构化的数据文件映射为一张数据库表并提供数据查询功能 二、hive的特点 (1)数据是存储在hdfs上 (2)底层是将sql转换为MapReduce任务进行计算 …...

unity打包到安卓帧率降低

这个问题遇到过很多次了我的做法就是直接设置Application.targetFrameRate60 参考...

【Python3】装饰器 自动更新缓存

自动更新缓存的需求场景 在某些应用中,我们可能需要定期从外部数据源(如 Redis 或者远程接口)拉取数据,并将其缓存在内存中。当有其他代码需要访问这些数据时,可以立刻从内存获取最新数据,而无需每次都进行…...

通过EPEL 仓库,在 CentOS 7 上安装 OpenResty

通过EPEL 仓库,在 CentOS 7 上安装 OpenResty 通过EPEL 仓库,在 CentOS 7 上安装 OpenResty步骤 1: 安装 EPEL 仓库步骤 2: 安装 OpenResty步骤 3: 启动 OpenResty步骤 4: 设置开机自启步骤 5: 验证安装说明 通过EPEL 仓库,在 CentOS 7 上安装…...

[RabbitMQ] RabbitMQ常见应用问题

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...

每日速记10道java面试题13-MySQL篇

其他资料 每日速记10道java面试题01-CSDN博客 每日速记10道java面试题02-CSDN博客 每日速记10道java面试题03-CSDN博客 每日速记10道java面试题04-CSDN博客 每日速记10道java面试题05-CSDN博客 每日速记10道java面试题06-CSDN博客 每日速记10道java面试题07-CSDN博客 每…...

乐鑫科技嵌入式面试题及参考答案(3万字长文)

嵌入式开发为什么用 C 语言,而不用 C++ 语言? 在嵌入式开发中,C 语言被广泛使用而 C++ 相对少用有以下一些原因。 首先,C 语言具有更高的效率。嵌入式系统通常资源受限,包括处理器速度、内存容量等。C 语言的代码生成效率高,能够生成紧凑的机器码,占用较少的内存空间和处…...

Leetcode 每日一题 56.合并区间

目录 问题描述 示例 示例 1 示例 2 问题分析 算法设计 步骤 1:排序 步骤 2:合并区间 步骤 3:返回结果 过题图片 代码实现 复杂度分析 题目链接 结语 问题描述 给定一个区间数组 intervals,其中每个区间由两个整数 s…...

【Vue】v-model、ref获取DOM

目录 v-moel v-model的原理 v-model用在组件标签上 方式 defineModel()简写 ref属性 获取原生DOM 获取组件实例 nextTick() v-moel v-model:双向数据绑定指令 数据变了,视图跟着变(数据驱动视图)视图变了,数…...

Python 类的设计(以植物大战僵尸为例)

关于类的设计——以植物大战僵尸为例 一、设计类需满足的三要素1. 类名2. 属性和方法 二、以植物大战僵尸的为例的类的设计1. 尝试分类2. 创建对象调用类的属性和方法*【代码二】*3. 僵尸的继承 三、代码实现 一、设计类需满足的三要素 1. 类名 类名:某类事物的名…...

python中权重剪枝,低秩分解,量化技术 代码

目录 python中权重剪枝,低秩分解,量化技术 代码 权重剪枝 低秩分解 scipy 量化技术 python中权重剪枝,低秩分解,量化技术 代码 权重剪枝 权重剪枝可以通过PyTorch的torch.nn.utils.prune模块实现。以下是一个简单的例子: import torch import torch.nn as nn impor…...

调用matlab用户自定义的function函数时,有多个输出变量只输出第一个变量

很多朋友在使用matlab时,会使用或自己编辑多个function函数,来满足自己对任务处理的要求,但是在调用function函数时,会出现这个问题:调用matlab用户自定义的function函数时,有多个输出变量只输出第一个变量…...

RabbitMQ七种工作模式之简单模式, 工作队列模式, 发布订阅模式, 路由模式, 通配符模式

文章目录 一. Simple(简单模式)公共代码:生产者:消费者: 二. Work Queue(工作队列模式)公共代码:生产者:消费者1, 消费者2(代码相同): 三. Publish/Subscribe(发布/订阅模式)公共代码:生产者:消费者: 四. Routing(路由模式)公共代码:消费者: 五. Topics(通配符模式)公共代码:生…...

Win10安装kafka并用C#调用

kafka安装 jdk、kafka版本如下,zookeeper使用kafka自带版本 安装包下载位置:https://download.csdn.net/download/henreash/90087368 (赚点csdn下载资源分) 安装jdk后,解压kafka压缩包,修改配置文件: kafka_2.13-3.9.0\config\…...

高级架构二 Git基础到高级

一 Git仓库的基本概念和流程 什么是版本库?版本库又名仓库,英文名repository,你可以简单的理解一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改,删除,Git都能跟踪,以便任何…...

深入解析二叉树算法

引言 二叉树(Binary Tree)作为数据结构中的一种重要形式,在计算机科学的诸多领域中得到了广泛应用。从文件系统到表达式解析,再到搜索和排序,二叉树都扮演着关键角色。本文将从二叉树的基础概念出发,详细探讨其各种算法及其应用,并提供相关代码示例,旨在为读者建立扎实…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

基于服务器使用 apt 安装、配置 Nginx

🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

【Oracle】分区表

个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

CSS | transition 和 transform的用处和区别

省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...