PostgreSQL ECPG 开发 DEMO

本文涉及的产品
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介: ECPG 是在C中嵌套SQL的一种用法。写好pgc文件后,需要使用ecpg程序将pgc编程成C文件来使用。 详细的用法请参考https://www.postgresql.org/docs/9.5/static/ecpg.html ecpg的用法, 以EXEC SQL开头表示后面是SQL写法

ECPG 是在C中嵌套SQL的一种用法。
写好pgc文件后,需要使用ecpg程序将pgc编程成C文件来使用。
1
详细的用法请参考
https://www.postgresql.org/docs/9.5/static/ecpg.html

ecpg的用法, 以EXEC SQL开头表示后面是SQL写法

一些简单的用法
大小写敏感.
.1. 连接数据库

EXEC SQL CONNECT TO target [AS connection-name] [USER user-name];

target : 
dbname[@hostname][:port]
tcp:postgresql://hostname[:port][/dbname][?options]
unix:postgresql://hostname[:port][/dbname][?options]

例子
EXEC SQL CONNECT TO mydb@sql.mydomain.com;

EXEC SQL CONNECT TO unix:postgresql://sql.mydomain.com/mydb AS myconnection USER john;

EXEC SQL BEGIN DECLARE SECTION;
const char *target = "mydb@sql.mydomain.com";
const char *user = "john";
const char *passwd = "secret";
EXEC SQL END DECLARE SECTION;
 ...
EXEC SQL CONNECT TO :target USER :user USING :passwd;
/* or EXEC SQL CONNECT TO :target USER :user/:passwd; */

.2. 定义ecpg变量
PostgreSQL数据类型与ecpg使用的类型的映射关系
https://www.postgresql.org/docs/9.5/static/ecpg-variables.html#ECPG-VARIABLES-TYPE-MAPPING
有些类型没有一一对应的关系,需要使用ecpg的函数来转换。



下面是一个DEMO
首先需要编写pgc文件。

$ vi t.pgc
#include <stdio.h>
#include <stdlib.h>
#include <pgtypes_numeric.h>

EXEC SQL WHENEVER SQLERROR STOP;

int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
    numeric *num;
    numeric *num2;
    decimal *dec;
EXEC SQL END DECLARE SECTION;

    EXEC SQL CONNECT TO tcp:postgresql://xxxcs.com:3433/postgres AS db_digoal USER digoal USING digoal;

    num = PGTYPESnumeric_new();
    dec = PGTYPESdecimal_new();

    EXEC SQL SELECT 12.345::numeric(4,2), 23.456::decimal(4,2) INTO :num, :dec;

    printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 0));
    printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 1));
    printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 2));

    /* Convert decimal to numeric to show a decimal value. */
    num2 = PGTYPESnumeric_new();
    PGTYPESnumeric_from_decimal(dec, num2);

    printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 0));
    printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 1));
    printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 2));

    PGTYPESnumeric_free(num2);
    PGTYPESdecimal_free(dec);
    PGTYPESnumeric_free(num);

    EXEC SQL COMMIT;
    EXEC SQL DISCONNECT ALL;
    return 0;
}

本地环境中需要有依赖的头文件和库.
编译.pgc
-t 表示使用自动提交

ecpg -t -c -I/home/digoal/pgsql9.6/include -o t.c t.pgc

查看编译后的.c

/* Processed by ecpg (4.12.0) */
/* These include files are added by the preprocessor */
#include <ecpglib.h>
#include <ecpgerrno.h>
#include <sqlca.h>
/* End of automatic include section */

#line 1 "t.pgc"
#include <stdio.h>
#include <stdlib.h>
#include <pgtypes_numeric.h>

/* exec sql whenever sqlerror  stop ; */
#line 5 "t.pgc"


int
main(void)
{
/* exec sql begin declare section */
     
     
     

#line 11 "t.pgc"
 numeric * num ;
 
#line 12 "t.pgc"
 numeric * num2 ;
 
#line 13 "t.pgc"
 decimal * dec ;
/* exec sql end declare section */
#line 14 "t.pgc"


    { ECPGconnect(__LINE__, 0, "tcp:postgresql://rdsqm2ffv0wjxnxk5nbsi.pg.rds.aliyuncs.com:3433/postgres" , "digoal" , "digoal" , "db_digoal", 1); 
#line 16 "t.pgc"

if (sqlca.sqlcode < 0) exit (1);}
#line 16 "t.pgc"


    num = PGTYPESnumeric_new();
    dec = PGTYPESdecimal_new();

    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select 12.345 :: numeric ( 4 , 2 ) , 23.456 :: decimal ( 4 , 2 )", ECPGt_EOIT, 
        ECPGt_numeric,&(num),(long)1,(long)0,sizeof(numeric), 
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
        ECPGt_decimal,&(dec),(long)1,(long)0,sizeof(decimal), 
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 21 "t.pgc"

if (sqlca.sqlcode < 0) exit (1);}
#line 21 "t.pgc"


    printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 0));
    printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 1));
    printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 2));

    /* Convert decimal to numeric to show a decimal value. */
    num2 = PGTYPESnumeric_new();
    PGTYPESnumeric_from_decimal(dec, num2);

    printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 0));
    printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 1));
    printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 2));

    PGTYPESnumeric_free(num2);
    PGTYPESdecimal_free(dec);
    PGTYPESnumeric_free(num);

    { ECPGtrans(__LINE__, NULL, "commit");
#line 39 "t.pgc"

if (sqlca.sqlcode < 0) exit (1);}
#line 39 "t.pgc"

    { ECPGdisconnect(__LINE__, "ALL");
#line 40 "t.pgc"

if (sqlca.sqlcode < 0) exit (1);}
#line 40 "t.pgc"

    return 0;
}

编译,链接 .c

gcc -I/home/digoal/pgsql9.6/include  -Wall -g  t.c  -L/home/digoal/pgsql9.6/lib -lecpg -lpq -lpgtypes -o t

也可以写成Makefile如下 :
$ vi Makefile
注意需要TAB键.

ECPG = ecpg
CC = gcc

INCLUDES = -I$(shell pg_config --includedir)
LIBPATH = -L$(shell pg_config --libdir)
CFLAGS += $(INCLUDES)
LDFLAGS += -Wall -g
LDLIBS += $(LIBPATH) -lecpg -lpq -lpgtypes

%.c: %.pgc
        $(ECPG) -t -c $(INCLUDES) -o $@ $<

%: %.o
        $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ $<

TESTS = t t.c

default: $(TESTS)

clean:
        rm -f *.o *.so t t.c

使用时注意把pg_config弄进PATH

$ export PATH=/home/digoal/pgsql9.6/bin:$PATH
$ make

使用编译好的t :

./t 
numeric = 12
numeric = 12.4
numeric = 12.35
decimal = 23
decimal = 23.5
decimal = 23.46
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
关系型数据库 数据库 C语言
PostgreSQL服务端开发学习 -- Datum
在使用C语言开发PostgreSQL后端、客户端应用时,Datum无处不在,所以必须要对Datum有很清楚的了解。
|
关系型数据库 开发工具 C语言
PostgreSQL libpq开发入门
简单入门C语言开发基于PostgreSQL libpq应用
|
关系型数据库 C语言 PostgreSQL
PostgreSQL服务端开发学习 --- 常用结构及宏定义1
本篇主要讲解使用C语言开发PostgreSQL服务端应用(libpq、自定义函数、扩展)常用到的结构及宏定义。
|
3月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
371 0
|
关系型数据库 C语言 PostgreSQL
PostgreSQL服务端开发学习 -- fmgr.h
fmgr按官方的解释就是Postgres函数管理器和函数调用接口,在使用C语言开发PostgreSQL后端应用时,所以与backend交互时必须遵循fmgr.h中定义的一些规范。
|
存储 SQL 缓存
PostgreSQL DirectIO开发实践
在数据库开源的背景下,基于PG的DirectIO的研发方案分享。
PostgreSQL DirectIO开发实践
|
存储 网络协议 Java
PostgreSQL JDBC 开发指导
Java Database Connectivity (JDBC) 是一个应用程序编程接口 (API),用于 编程语言 Java,它定义了客户端如何访问数据库。 它是Java标准版平台的一部分,提供查询和 更新数据库中的数据,并面向关系数据库。 PostgreSQL JDBC驱动程序(简称pgJDBC)允许Java程序连接到PostgreSQL®® 数据库使用标准的、独立于数据库的 Java 代码。是一个开源的JDBC驱动程序 用纯Java(类型4)编写,并使用PostgreSQL®本机网络协议进行通信。 因此,驱动程序独立于平台;编译后,驱动程序 可以在任何系统上使用。
161 0
|
6月前
|
Cloud Native 关系型数据库 OLAP
从0~1,基于DMS面向AnalyticDB PostgreSQL的数据ETL链路开发
在传统数仓中,往往采用资源预购的方式,缺少面向业务的资源调整灵活性。 在数据分析这种存在明显业务波峰波谷或分时请求的场景下,实例无法按需使用,造成了大量成本浪费。云原生数仓AnalyticDB PostgreSQL产品自2022年2月正式发布了Serverless版之后,依托于内核强大的资源管理能力...
|
关系型数据库 MySQL 数据挖掘
阿里云PostgreSQL_开发实践_5 | 学习笔记
简介:快速学习阿里云PostgreSQL_开发实践_5
358 0
阿里云PostgreSQL_开发实践_5 | 学习笔记
|
存储 SQL 监控
阿里云 PostgreSQL_开发实践_4 | 学习笔记
简介:快速学习阿里云 PostgreSQL_开发实践_4
160 0
阿里云 PostgreSQL_开发实践_4 | 学习笔记

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版