PostgreSQL如何自定义函数并且调用

news/2024/11/17 18:48:16/

PostgreSQL如何自定义函数

  • 一、背景
  • 二、函数语法
    • 说明
  • 三、异常处理语法
  • 四、自定义函数示例
    • 1、format函数
    • 2、使用default参数
    • 3、根据输入的数字,返回两个数的商,若除数为0,则抛出自定义异常
    • 4、多个OUT或者INOUT参数时,返回是一个元组;可以通过将函数调用放在 FROM 子句中来返回元组的各个成员
  • 五、动态执行语句
    • 1、数据准备
    • 2、示例:动态查询某张表的记录数
    • 3、动态创建表

一、背景

在PostgreSQL关系型数据库中,我们经常是调用系统默认的函数,例如lower() ,arry_to_string()等等,但有时候特殊的需求,默认的函数无法实现转换,那么就需要通过自定义函数,并且调用我们自定义的函数实现数据的转换。

二、函数语法


CREATE [OR REPLACE] FUNCTION function_name (arguments)
RETURNS return_datatype AS $variable_name$  DECLARE  declaration;  [...]  BEGIN  < function_body >  [...]  RETURN { variable_name | value }  END;  $variable_name$ LANGUAGE plpgsql;

说明

function_name:指定函数的名称。
[OR REPLACE]:是可选的,它允许您修改/替换现有函数。
arguments:函数参数[[argmode]argname argtype [default value],[[argmode]argname argtype],[…]];argmode参数的模式有IN、OUT或则INOUT,缺省值是IN。argname参数名字。argtype参数的数据类型。default默认参数。
RETURNS:它指定要从函数返回的数据类型。它可以是基础,复合或域类型,或者也可以引用表列的类型,比如return int、varchar,返回结果集时就需要setof来表示,无返回值使用void。如果存在OUT或则INOUT参数,则可以省略RETURNS子句。
return_datatype:表示返回值类型。
function_body:function_body包含可执行部分。
LANGUAGE:它指定实现该函数的语言的名称。

三、异常处理语法

在PostgreSQL中可以利用RAISE语句报告信息和抛出错误,其声明形式为:


RAISE LEVEL 'format' [,expression,[...]]

说明:
LEVEL:包含的级别有DEBUG(向服务器日志写信息)、LOG(向服务器日志写信息,优先级更高)、INFO、NOTICE和WARNING(把信息写到服务器日志以及转发到客户端应用,优先级逐步升高)和EXCEPTION抛出一个错误(通常退出当前事务)。某个优先级别的信息是报告给客户端还是写到服务器日志,还是两个均有,是由log_min_messages和client_min_messages这两个系统初始化参数控制的。

四、自定义函数示例

1、format函数

用于根据格式字符串设置参数的FORMAT()函数格式:

FORMAT(format_string [, format_arg [, ...] ])

示例:

SELECT FORMAT('Hello, %s', 'world!!');

执行结果:Hello, world!!

2、使用default参数

create or replace function ftest(in fname VARCHAR default '编程语言', cname VARCHAR DEFAULT 'java')
RETURNS VARCHAR as $$
beginreturn format('%s_%s',fname,cname);
end; $$ LANGUAGE plpgsql;

调用方式:

select ftest('语言');  --语言_java
select ftest(cname=>'java'); --编程语言_java

3、根据输入的数字,返回两个数的商,若除数为0,则抛出自定义异常

CREATE OR REPLACE FUNCTION testdivision ( js1 INT, js2 INT ) RETURNS INT AS $$ DECLAREv_re INT;
BEGINraise notice'% 除以 %',js1,js2;IFjs2 = 0 THENraise EXCEPTION '不能除0';ELSE v_re := js1 / js2;RETURN v_re;END IF;EXCEPTION --捕获异常WHEN OTHERS THENRETURN 0;END;
$$ LANGUAGE plpgsql;

调用方式:

select testdivision(8,4);--2
select testdivision(3,0);--0

4、多个OUT或者INOUT参数时,返回是一个元组;可以通过将函数调用放在 FROM 子句中来返回元组的各个成员

create or replace FUNCTION test1(in js1 int,inout res1 int,out res2 int) as
$$
beginres1:=js1*2;res2:=res1*3;
end;
$$
LANGUAGE plpgsql;

调用方式:

select test1(3,2); --test1--(6,18)select * from test1(3,2);--res1|res2--   6|  18

五、动态执行语句

1、数据准备

create table tmp(bsm VARCHAR(100),name VARCHAR(100),num int
);
insert into tmp(bsm,name,num) VALUES('a','苹果',21);
insert into tmp(bsm,name,num) VALUES('b','香蕉',11);

2、示例:动态查询某张表的记录数


create or replace function getsum(in talename VARCHAR)
RETURNS int as $$
DECLAREstmt VARCHAR;count int;
beginstmt:=format('select count(1) from %s', talename);raise notice '%',stmt;EXECUTE stmt into count;return count;EXCEPTION --捕获异常WHEN OTHERS THENRETURN 0;
end; $$ LANGUAGE plpgsql;

调用方式:

select getsum('tmp');--2

3、动态创建表

create or replace function copytable(tablename varchar,times int)
RETURNS INT as $$
DECLAREstmt VARCHAR='create table %s_%s (like tmp including all);';--
beginfor i in 1..times loopraise notice 'd当前次数%',i;raise notice '%',format(stmt,tablename,i,tablename);EXECUTE format('drop table if EXISTS %s_%s;',tablename,i) ;EXECUTE format(stmt,tablename,i,tablename) ;end loop;return 0;			
END; $$  LANGUAGE plpgsql;

调用方式:


select copytable('tmp',2);即复制tmp表2

http://www.ppmy.cn/news/440033.html

相关文章

测试金士顿固态硬盘软件,借装机之名测试SSD:金士顿的当红两款固态究竟如何?...

借装机之名测试SSD&#xff1a;金士顿的当红两款固态究竟如何&#xff1f; 2019-12-15 14:46:03 3点赞 7收藏 11评论 创作立场声明&#xff1a;产品都是自己购买&#xff0c;算是花样SHOW双12晒单 在刚刚过去的双十二&#xff0c;相信很多小伙伴和双十一样&#xff0c;剁手了许…

前端vue入门(纯代码)09

【09.vue中组件的自定义事件】 自定义组件链接 在vue中用的click【点击】、keyup【按键】……等事件&#xff0c;这些属于内置事件&#xff0c;也就是js自带的事件。 问题一&#xff1a;什么是组件自定义事件呢&#xff1f; 【内置事件】:是给html元素用的&#xff0c;比如s…

机械硬盘vs固态硬盘

提示&#xff1a;本文撰写的一部分内容借鉴了联想公众号【小黑干货】 文章目录 前言什么是机械硬盘不同颜色硬盘的区别优点缺点 什么是固态硬盘优点缺点 什么是双硬盘固态硬盘机械硬盘优点缺点 双固态硬盘优点缺点 总结&#xff1a; 前言 提示&#xff1a;这里可以添加本文要记…

Servlet (上篇)

哥几个来学 Servlet 啦 ~~ 目录 &#x1f332;一、什么是 Servlet &#x1f333;二、第一个 Servlet 程序 &#x1f347;1. 创建项目 &#x1f348;2. 引入依赖 &#x1f349;3. 创建目录 &#x1f34a;4. 编写代码 &#x1f34b;5. 打包程序 &#x1f96d;6. 部署程序…

限购解决方案

我需要大单量可是一个账号限购得厉害

借名买房规避限购政策的,合同应认定为无效

1.借名人与出名人为规避国家限购政策签订的《房产代持协议》因违背公序良俗应认定无效&#xff0c;借名人依据规避国家限购政策的借名买房合同关系&#xff0c;不能排除人民法院对该房屋的执行。 2.在借名买房并不违反公序良俗原则、不存在无效事由的情况下&#xff0c;借名人…

青岛市两化融合的政策

在本市行政区域内注册并经营一年以上&#xff0c;具有独立法人资格的制造业企业;项目竣工并投入使用&#xff0c;且近两年内信息化硬件、软件、网络、系统集成等完成投资100万元以上都可以申报两化融合。 申报材料 青岛市“两化融合”项目补助资金申报表;(2)企业营业执照、组…

青岛如何线上提取青岛公积金

如何线上提取青岛公积金&#xff1f; 如何想提更大额度&#xff0c;可白du嗖“青岛公积金代办”&#xff01;&#xff01;您可以在线开通青岛市住房公积金管理中心&#xff0c;进入支取。使用您的身份证号码和公积金号码的最后六位数字作为密码登录。单击公积金提取&#xff0c…