携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天
说明:
服务器编程接口(SPI)给予用户定义C函数编写者在其函数内运行SQL命令的能力。SPI是一组接口函数,它们可以简化对解析器、规划器和执行器的访问。SPI也做一些内存管理。我们可以使用这些SPI来编写C函数来实现运行SQL的功能。
例子:
1、首先,我们在数据库中创建测试表并插入数据
bill=# create table test(id int,info text,crt_time timestamp);
CREATE TABLE
bill=# insert into test select generate_series(1,10),md5(random()::text),clock_timestamp();
INSERT 0 10
2、然后编写C文件
vi myupdate.c
代码如下:
#include "postgres.h"
#include "executor/spi.h"
#include "utils/builtins.h"
#include "fmgr.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(myupdate);
Datum
myupdate(PG_FUNCTION_ARGS)
{
char command[128]; //将SQL命令存储在大小合适的数组
int ret;
int proc; //对表数据操作的行数
/* 将命令赋值到command */
sprintf(command, "update test set info = 'bill' where id = %d; ", PG_GETARG_INT32(0));
SPI_connect(); //创建连接
ret = SPI_exec( command, 0); //执行操作
proc = SPI_processed; //为行数赋值
SPI_finish(); //中断连接
return (proc); //将操作行数作为返回结果
}
其中SPI_connect、SPI_exec等都是PostgreSQL中提供的SPI函数,详细的说明参考:
www.postgresql.org/docs/13/spi…
3、编译
pg11@oracle-> gcc -fpic -I/home/itm_pg/pgsql11.1/include/server -shared -o myupdate.so myupdate.c
4、将so文件复制到lib目录下
pg11@oracle-> cp myupdate.so /home/itm_pg/pgsql11.1/lib
5、加载到数据库服务器中
bill=# load 'myupdate';
LOAD
6、创建函数
bill=# create function myupdate(integer) returns integer as '$libdir/myupdate.so','myupdate' language c strict;
CREATE FUNCTION
7、使用测试
bill=# select myupdate(1);
myupdate
----------
1
(1 row)
bill=# select myupdate(2);
myupdate
----------
1
(1 row)
bill=# select * from test where id in(1,2);
id | info | crt_time
----+------+----------------------------
1 | bill | 2020-06-05 15:32:43.91827
2 | bill | 2020-06-05 15:32:43.918443
(2 rows)