PostgreSQL ECPG 开发 DEMO

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
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值