PostgreSQL 执行动态sql

本文介绍了一种在PostgreSQL中使用PL/pgSQL语言创建动态SQL函数的方法,包括执行查询并返回记录集的函数和返回计数的函数。此外,还展示了如何使用预处理语句来调试SQL执行计划,以优化不同参数值下的SQL性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

虽然真的很鸡肋,并且性能不杂滴,但聊胜于无吧.

drop function if exists exe_dynamic_sql(bigint);
drop function if exists exe_dynamic_count(bigint);
--返回记录集
create or replace function exe_dynamic_sql(ival bigint)
    returns table(objectid bigint,name varchar(128))
as $$
	declare
	begin
		return query execute 'select objectid,name from dictionarys where parentid=$1 order by parentid,sort' using $1; 
	end;
$$ language plpgsql;

--赋值给变量
create or replace function exe_dynamic_count(ival bigint)
    returns bigint
as $$
	declare
		v_count bigint;
	begin
		execute 'select count(*) from dictionarys where parentid=$1' using $1 into v_count;
		return v_count;
	end;
$$ language plpgsql;
--测试
select * from exe_dynamic_sql(26);
select exe_dynamic_count(26);

要点:

  • returns table(objectid bigint,name varchar(128)),定义返回的字段和类型
  • using $1执行时使用过程参数;

准备一个语句用于执行,这个就比较重要了,查询参数绑定,开发利器

有朋友抱怨同一sql时快时慢,这是因为值在表中的占比不同,占比小的值就可以使用索引,值占比超过5%里sql就很慢了.此时就可以用下面的sql调式sql,可以根据不同的值来观察执行计划.

--getDictionarys仅在当前会话下有效
prepare getDictionarys (bigint) as
    select objectid,name from dictionarys where parentid=$1 order by parentid,sort;

explain (analyze,verbose,costs,buffers,timing)
execute getDictionarys(24);

explain (analyze,verbose,costs,buffers,timing)
execute getDictionarys(25);

explain (analyze,verbose,costs,buffers,timing)
execute getDictionarys(26);

--释放指定的预备语句
deallocate getDictionarys;
--释放所有预备语句
deallocate all;
您可以使用以下代码示例向PostgreSQL数据库中的表中插入多个属性和中文值: ``` #include <libpq-fe.h> #include <stdlib.h> #include <string.h> int main() { PGconn *conn = PQconnectdb("dbname=mydb user=myuser password=mypassword host=myhost port=myport"); if (PQstatus(conn) != CONNECTION_OK) { fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn)); PQfinish(conn); exit(1); } const char *sql = "INSERT INTO mytable (name, age, gender, address) VALUES ($1, $2, $3, $4)"; const char *params[4] = {"张三", "25", "男", "北京市海淀区"}; // Prepare statement PGresult *res = PQprepare(conn, "insert_stmt", sql, 4, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Prepare statement failed: %s", PQerrorMessage(conn)); PQfinish(conn); exit(1); } PQclear(res); // Execute statement with parameters const char *paramValues[4] = {params[0], params[1], params[2], params[3]}; const int paramLengths[4] = {strlen(params[0]), strlen(params[1]), strlen(params[2]), strlen(params[3])}; const int paramFormats[4] = {0, 0, 0, 0}; res = PQexecPrepared(conn, "insert_stmt", 4, paramValues, paramLengths, paramFormats, 0); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Execute statement failed: %s", PQerrorMessage(conn)); PQfinish(conn); exit(1); } PQclear(res); PQfinish(conn); return 0; } ``` 在此示例中,我们使用 `PQprepare` 函数准备了一个包含4个参数的预备语句,并将其命名为 "insert_stmt"。然后,我们使用 `PQexecPrepared` 函数执行该预备语句,并将参数以数组的形式传递给该函数。在这个例子中,我们向 "mytable" 表中插入了 "name","age","gender" 和 "address" 四个属性的值。其中,"name" 和 "address" 属性的值为中文。我们将参数的长度和格式都设置为0,表示参数为文本形式。 请注意,为了使插入的中文字符正确显示,您需要确保数据库中的编码方式和客户端代码中的编码方式相同。在本例中,我们假设数据库和客户端代码都使用UTF-8编码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kmblack1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值