首页 > 数据库 >POSTGRESQL 存储过程--如何写出新版本PG的存储过程的小案例

POSTGRESQL 存储过程--如何写出新版本PG的存储过程的小案例

时间:2023-06-22 13:01:41浏览次数:45  
标签:insert 存储 POSTGRESQL name -- data 过程 id


POSTGRESQL  存储过程--如何写出新版本PG的存储过程的小案例_存储过程

随着问问题的同学越来越多,公众号内部私信回答问题已经很困难了,所以建立了一个群,关于各种数据库的问题都可以,目前主要是 POSTGRESQL, MYSQL ,MONGODB ,POLARDB ,REDIS,SQL SERVER 等,期待你的加入,

最近在开始研究POSTGRESQL 的存储过程,主要的原因有以下几个

1 因为要开发适合目前公司中的基于POSTGRESQL 的运行维护产品,同时基于POSTGRESQL 的数据库有云数据库,基于程序的安全性和部署的便利性,一部分维护的程序应该以存储过程的方式,被部署在数据库中,方便外部程序调用。

2  基于POSTGRESQL 大部分的存储过程的教学内容还是在create function部分 ,在POSTGRESQL  11 后的版本的数据库的存储过程已经不再使用create function,而采用 create procedure 的方式撰写,功能和扩展性提高了

所以需要针对POSTGRESQL 的存储过程进行一个详细的研究,看看怎么更好的为以后的工作服务。

CREATE [ OR REPLACE ] PROCEDURE
    name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
  { LANGUAGE lang_name
    | TRANSFORM { FOR TYPE type_name } [, ... ]
    | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
    | SET configuration_parameter { TO value | = value | FROM CURRENT }
    | AS 'definition'
    | AS 'obj_file', 'link_symbol'
    | sql_body

} ...

这是官方的procedure 的固定语法这里需要注意第一个地方

1  POSTGRESQL 的存储过程和函数可以是一个名字,只要后面的给定的参数不一致即可,也就是有一部分可能性存储过程和函数的名字是一样的。但我们强烈建议不要这样做。

2   存储过程中的 argmode 部分可以选择的参数有 in ,out, inout 或者  variadic 默认是in, 后面我们通过一些案例来看看如何进行这些模式的使用。

3  argname  argtype  这是存储过程中的参数名和参数的类型设置的

4  SECURITY INVOKER 为设置执行存储过程的用户的权限来调用存储过程

案例  1  

POSTGRESQL  存储过程--如何写出新版本PG的存储过程的小案例_存储过程_02

create or replace procedure dba_insert_data("id" int,"name" varchar(20))
language sql 
as $$
insert into public.insert_d (id,name) values ("id","name"); 
$$;


call dba_insert_data(1,'pop');

select * from insert_d;

存储过程中将参数输入的部分,很简单,默认就是输入,将输入的参数和参数的类型标注即可,并且注意参数用双引号标志即可。

案例2

带有输出参数的信息和如何将信息展示在存储过程运行期间,如何将输入的参数在进行输出

POSTGRESQL  存储过程--如何写出新版本PG的存储过程的小案例_存储过程_03

create or replace procedure dba_insert_data("id" int,"name" varchar(20),INOUT msg text)
language plpgsql 
as $$
BEGIN
insert into public.insert_d (id,name) values ("id","name");

RAISE NOTICE 'insert data process is done:%',msg;
END;
$$;


call dba_insert_data(1,'pop');

这里语法 RAISE NOTICE 是输出消息的语句 ,而通过百分号 % 来代表输入变量,然后在输出时标名变量即可。

案例 3

将存储过程中的表的字段值输出到存储过程的外部,这就需要在定义存储过程中先定义这个表的这个字段。

create or replace procedure dba_insert_data("id_in" int,"name" varchar(20))
language plpgsql 
as $$

declare exid "insert_d"."id"%type;

BEGIN
insert into public.insert_d (id,name) values ("id_in","name");

select id into exid from public.insert_d ;

RAISE NOTICE 'insert data id is:%',exid;

END;
$$;

truncate table insert_d;

call dba_insert_data(1,'pop');

POSTGRESQL  存储过程--如何写出新版本PG的存储过程的小案例_数据库_04

在这个案例中,我们定义了接受表中字段值的变量 exid ,同时将这个值输出到 message中。这里需要注意几个地方

1  请不要将变量名和字段名一致,否则会报无法定位的问题

2   查询的值必须是一个值,如果出现多行值也会报错,无法赋值的问题

案例 4  需要将表中的查询的多个值进行展示

这个问题与上面的问题类似,上面的第三个案例只能展示一行值,并且出现多行结果,会报错,而大概率的情况下,怎么处理多行值的问题就在第四个案例中展示。

POSTGRESQL  存储过程--如何写出新版本PG的存储过程的小案例_存储过程_05

create or replace procedure dba_insert_data("id_in" int,"name_in" varchar(20))
language plpgsql 
as $$

declare table_record record;

BEGIN
insert into public.insert_d (id,name) values ("id_in","name_in");
     
     for table_record in (select id,name from public.insert_d)
         
         loop 
             RAISE INFO 'insert data id is:%,%',table_record."id",table_record."name";
             
         end loop;

END;
$$;

案例 5  权限问题,一般在建立存储过程的时候,创建者都拥有操作这个存储过程中的OBJECT 的权限,而执行者一般不见得有所有这个存储过程中需要的OBJECT的权限,就会产生一个问题,执行者执行存储过程无法通过。所以我们就需要通过  security definer 来指定拥有存储过程的特权用户来操作这个存储过程。

下面我们通过两个不同的security 方式来进行测试

1  使用security definer 这里是采用建立这个存储过程的用户的权限来调用这个存储过程,而不会使用执行者的权限来操作这个存储过程。

POSTGRESQL  存储过程--如何写出新版本PG的存储过程的小案例_oracle_06

而如果我们通过其  security invoker 的方式来定义存储过程,并且使用一个没有权限操作存储过程中OBJECT 的权限的用户来操作存储过程,则问题就会像下面的结果一样报错,并告知没有相关的权限来操作存储过程。

POSTGRESQL  存储过程--如何写出新版本PG的存储过程的小案例_oracle_07

POSTGRESQL  存储过程--如何写出新版本PG的存储过程的小案例_字段_08

以上仅仅是一些简单的例子和一些比较常见的存储过程的用法,其实有点好笑的是,在现在云原生和分布式数据库爆发的年代,我们还在继续使用存储过程来操作数据库,好像也没有什么错。

POSTGRESQL  存储过程--如何写出新版本PG的存储过程的小案例_字段_09

以上

标签:insert,存储,POSTGRESQL,name,--,data,过程,id
From: https://blog.51cto.com/u_14150796/6534693

相关文章

  • MYSQL performance_schema 不显示信息 和调整 performance_schema 的配置
    随着问问题的同学越来越多,公众号内部私信回答问题已经很困难了,所以建立了一个群,关于各种数据库的问题都可以,目前主要是POSTGRESQL,MYSQL,MONGODB,POLARDB,REDIS等,最近在某云使用了MYSQLRDS产品,说实话不怎么满意,和他家的其他产品比较我到时更原因使用PG的产品和云原生产品......
  • MYSQL POLARDB 学习系列之 拆解 POLARDB 7 (终结) 失败恢复与可靠性
    随着问问题的同学越来越多,公众号内部私信回答问题已经很困难了,所以建立了一个群,关于各种数据库的问题都可以,目前主要是POSTGRESQL,MYSQL,MONGODB,POLARDB,REDIS,SQLSERVER等,期待你的加入,学习POLARDB已经有3-4个月的时间了,当然大部分还是在理论方面,实际上POLARDB在实际的操......
  • POSTGRESQL 提高POSTGRESQL性能的一些习惯 (3)
    随着问问题的同学越来越多,公众号内部私信回答问题已经很困难了,所以建立了一个群,关于各种数据库的问题都可以,目前主要是POSTGRESQL,MYSQL,MONGODB,POLARDB,REDIS,SQLSERVER等,期待你的加入这个系列写到第三期了,实际上POSTGRESQL的优化和一个核心之一,这就是VACUUM,一个弄不清vac......
  • 数据库上云就可以 解雇 DBA ,来说说数据库上云那些 “有意思” 的事情
    随着问问题的同学越来越多,公众号内部私信回答问题已经很困难了,所以建立了一个群,关于各种数据库的问题都可以,目前主要是POSTGRESQL,MYSQL,MONGODB,POLARDB,REDIS等,期待你的加入,另外针对云的问题,我们可以多多交流互相学习————————————————————————正文......
  • Linux Nacos2.2.0版本集群搭建,常见报错问题解决
    准备:服务器,nacos,mysql,nginx,java,mavenNacos官网:https://nacos.io下载地址github:https://github.com/alibaba/nacos相关版本问题,见nacos官网手册查看集群配置图:官方的: 本次搭建集群配置图:开始搭建:修改nacos的配置文件“application.properties,cluster.conf.ex......
  • transformers库的使用【一】——pipeline的简单使用
    transformers库的使用使用pipelineAPI来快速使用一些预训练模型使用预训练模型最简单的方法就是使用pipeline(),transformers提供了一些任务:1、情感分析(Sentmentanalysis):分析文本是正面的还是负面的2、文本生成(inEnglish):提供一个语句,模型将生成这条语句的下一句3、命名实体识......
  • Huggingface Transformers库学习笔记(一):入门(Get started)
    前言Huggingface的Transformers库是一个很棒的项目,该库提供了用于自然语言理解(NLU)任务(如分析文本的情感)和自然语言生成(NLG)任务(如用新文本完成提示或用另一种语言翻译)的预先训练的模型。其收录了在100多种语言上超过32种预训练模型。这些先进的模型通过这个库可以非常轻松......
  • unicode 转 utf16
    1functiontoUtf16(text){2if(text.length===1)returntext.charCodeAt(0).toString(16);3constpoint=text.codePointAt(0);4consthighBits=0xd800,5lowBits=0xdc00,6bmp=0x10000;7constrest=(point-bmp).toString(2......
  • 添加一段代码,让你的网站在微信QQ提示使用浏览器访问
    <script>//跳转提示if(is_weixn_qq()){;window.location.href='https://c.pc.qq.com/middle.html?pfurl='+window.location.href;}functionis_weixn_qq(){//判断当前是否微信/QQ浏览器varua=navigator.userAgent;varisWeixin=!!/MicroMessenger/i.test......
  • 操作系统计算题
    假设有4个进程需要在单CPU上运行,它们的执行时间如下表所示:进程ID执行时间P1 8P2 5P3 2P4 4现在我们需要按照抢占式优先级调度算法来安排这些进程的执行顺序。其中,进程的优先级执行时间越短,优先级越高。如果两个进程的优先级相同,则按照它们进入就绪队列的先后顺序来决定谁先......