Skip to content

Commit 18901f7

Browse files
committed
new doc
1 parent 9a62ba3 commit 18901f7

File tree

6 files changed

+470
-0
lines changed

6 files changed

+470
-0
lines changed

201605/20160529_03.md

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
## PostgreSQL ECPG 开发 DEMO
2+
3+
### 作者
4+
digoal
5+
6+
### 日期
7+
2016-05-29
8+
9+
### 标签
10+
PostgreSQL , ECPG
11+
12+
----
13+
14+
## 背景
15+
ECPG 是在C中嵌套SQL的一种用法。
16+
17+
写好pgc文件后,需要使用ecpg程序将pgc编程成C文件来使用。
18+
19+
![1](20160529_03_pic_001.png)
20+
21+
详细的用法请参考
22+
23+
https://www.postgresql.org/docs/9.5/static/ecpg.html
24+
25+
ecpg的用法, 以EXEC SQL开头表示后面是SQL写法
26+
27+
一些简单的用法
28+
29+
大小写敏感.
30+
31+
1\. 连接数据库
32+
33+
```
34+
EXEC SQL CONNECT TO target [AS connection-name] [USER user-name];
35+
36+
target :
37+
dbname[@hostname][:port]
38+
tcp:postgresql://hostname[:port][/dbname][?options]
39+
unix:postgresql://hostname[:port][/dbname][?options]
40+
41+
例子
42+
EXEC SQL CONNECT TO [email protected];
43+
44+
EXEC SQL CONNECT TO unix:postgresql://sql.mydomain.com/mydb AS myconnection USER john;
45+
46+
EXEC SQL BEGIN DECLARE SECTION;
47+
const char *target = "[email protected]";
48+
const char *user = "john";
49+
const char *passwd = "secret";
50+
EXEC SQL END DECLARE SECTION;
51+
...
52+
EXEC SQL CONNECT TO :target USER :user USING :passwd;
53+
/* or EXEC SQL CONNECT TO :target USER :user/:passwd; */
54+
```
55+
56+
2\. 定义ecpg变量
57+
58+
PostgreSQL数据类型与ecpg使用的类型的映射关系
59+
60+
https://www.postgresql.org/docs/9.5/static/ecpg-variables.html#ECPG-VARIABLES-TYPE-MAPPING
61+
62+
有些类型没有一一对应的关系,需要使用ecpg的函数来转换。
63+
64+
下面是一个DEMO
65+
66+
首先需要编写pgc文件。
67+
68+
```
69+
$ vi t.pgc
70+
#include <stdio.h>
71+
#include <stdlib.h>
72+
#include <pgtypes_numeric.h>
73+
74+
EXEC SQL WHENEVER SQLERROR STOP;
75+
76+
int
77+
main(void)
78+
{
79+
EXEC SQL BEGIN DECLARE SECTION;
80+
numeric *num;
81+
numeric *num2;
82+
decimal *dec;
83+
EXEC SQL END DECLARE SECTION;
84+
85+
EXEC SQL CONNECT TO tcp:postgresql://xxxcs.com:3433/postgres AS db_digoal USER digoal USING digoal;
86+
87+
num = PGTYPESnumeric_new();
88+
dec = PGTYPESdecimal_new();
89+
90+
EXEC SQL SELECT 12.345::numeric(4,2), 23.456::decimal(4,2) INTO :num, :dec;
91+
92+
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 0));
93+
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 1));
94+
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 2));
95+
96+
/* Convert decimal to numeric to show a decimal value. */
97+
num2 = PGTYPESnumeric_new();
98+
PGTYPESnumeric_from_decimal(dec, num2);
99+
100+
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 0));
101+
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 1));
102+
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 2));
103+
104+
PGTYPESnumeric_free(num2);
105+
PGTYPESdecimal_free(dec);
106+
PGTYPESnumeric_free(num);
107+
108+
EXEC SQL COMMIT;
109+
EXEC SQL DISCONNECT ALL;
110+
return 0;
111+
}
112+
```
113+
114+
本地环境中需要有依赖的头文件和库.
115+
116+
编译.pgc
117+
118+
-t 表示使用自动提交
119+
120+
```
121+
ecpg -t -c -I/home/digoal/pgsql9.6/include -o t.c t.pgc
122+
```
123+
124+
查看编译后的.c
125+
126+
```
127+
/* Processed by ecpg (4.12.0) */
128+
/* These include files are added by the preprocessor */
129+
#include <ecpglib.h>
130+
#include <ecpgerrno.h>
131+
#include <sqlca.h>
132+
/* End of automatic include section */
133+
134+
#line 1 "t.pgc"
135+
#include <stdio.h>
136+
#include <stdlib.h>
137+
#include <pgtypes_numeric.h>
138+
139+
/* exec sql whenever sqlerror stop ; */
140+
#line 5 "t.pgc"
141+
142+
143+
int
144+
main(void)
145+
{
146+
/* exec sql begin declare section */
147+
148+
149+
150+
151+
#line 11 "t.pgc"
152+
numeric * num ;
153+
154+
#line 12 "t.pgc"
155+
numeric * num2 ;
156+
157+
#line 13 "t.pgc"
158+
decimal * dec ;
159+
/* exec sql end declare section */
160+
#line 14 "t.pgc"
161+
162+
163+
{ ECPGconnect(__LINE__, 0, "tcp:postgresql://rdsqm2ffv0wjxnxk5nbsi.pg.rds.aliyuncs.com:3433/postgres" , "digoal" , "digoal" , "db_digoal", 1);
164+
#line 16 "t.pgc"
165+
166+
if (sqlca.sqlcode < 0) exit (1);}
167+
#line 16 "t.pgc"
168+
169+
170+
num = PGTYPESnumeric_new();
171+
dec = PGTYPESdecimal_new();
172+
173+
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select 12.345 :: numeric ( 4 , 2 ) , 23.456 :: decimal ( 4 , 2 )", ECPGt_EOIT,
174+
ECPGt_numeric,&(num),(long)1,(long)0,sizeof(numeric),
175+
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
176+
ECPGt_decimal,&(dec),(long)1,(long)0,sizeof(decimal),
177+
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
178+
#line 21 "t.pgc"
179+
180+
if (sqlca.sqlcode < 0) exit (1);}
181+
#line 21 "t.pgc"
182+
183+
184+
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 0));
185+
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 1));
186+
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 2));
187+
188+
/* Convert decimal to numeric to show a decimal value. */
189+
num2 = PGTYPESnumeric_new();
190+
PGTYPESnumeric_from_decimal(dec, num2);
191+
192+
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 0));
193+
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 1));
194+
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 2));
195+
196+
PGTYPESnumeric_free(num2);
197+
PGTYPESdecimal_free(dec);
198+
PGTYPESnumeric_free(num);
199+
200+
{ ECPGtrans(__LINE__, NULL, "commit");
201+
#line 39 "t.pgc"
202+
203+
if (sqlca.sqlcode < 0) exit (1);}
204+
#line 39 "t.pgc"
205+
206+
{ ECPGdisconnect(__LINE__, "ALL");
207+
#line 40 "t.pgc"
208+
209+
if (sqlca.sqlcode < 0) exit (1);}
210+
#line 40 "t.pgc"
211+
212+
return 0;
213+
}
214+
```
215+
216+
编译,链接 .c
217+
218+
```
219+
gcc -I/home/digoal/pgsql9.6/include -Wall -g t.c -L/home/digoal/pgsql9.6/lib -lecpg -lpq -lpgtypes -o t
220+
```
221+
222+
也可以写成Makefile如下 :
223+
224+
```
225+
$ vi Makefile
226+
```
227+
228+
注意行首缩进的地方需要TAB键输入.
229+
230+
```
231+
ECPG = ecpg
232+
CC = gcc
233+
234+
INCLUDES = -I$(shell pg_config --includedir)
235+
LIBPATH = -L$(shell pg_config --libdir)
236+
CFLAGS += $(INCLUDES)
237+
LDFLAGS += -Wall -g
238+
LDLIBS += $(LIBPATH) -lecpg -lpq -lpgtypes
239+
240+
%.c: %.pgc
241+
$(ECPG) -t -c $(INCLUDES) -o $@ $<
242+
243+
%: %.o
244+
$(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ $<
245+
246+
TESTS = t t.c
247+
248+
default: $(TESTS)
249+
250+
clean:
251+
rm -f *.o *.so t t.c
252+
```
253+
254+
使用时注意把pg_config弄进PATH
255+
256+
```
257+
$ export PATH=/home/digoal/pgsql9.6/bin:$PATH
258+
$ make
259+
```
260+
261+
使用编译好的t :
262+
263+
```
264+
./t
265+
numeric = 12
266+
numeric = 12.4
267+
numeric = 12.35
268+
decimal = 23
269+
decimal = 23.5
270+
decimal = 23.46
271+
```
272+
273+
<a rel="nofollow" href="http://info.flagcounter.com/h9V1" ><img src="http://s03.flagcounter.com/count/h9V1/bg_FFFFFF/txt_000000/border_CCCCCC/columns_2/maxflags_12/viewers_0/labels_0/pageviews_0/flags_0/" alt="Flag Counter" border="0" ></a>
274+

201605/20160529_03_pic_001.png

168 KB
Loading

201605/readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
### 文章列表
44
----
55
##### 20160531_01.md [《PostgreSQL 函数稳定性与constraint_excluded分区表逻辑推理过滤的CASE》](20160531_01.md)
6+
##### 20160529_03.md [《PostgreSQL ECPG 开发 DEMO》](20160529_03.md)
67
##### 20160529_02.md [《EDB PPAS的"坑" 不兼容PostgreSQL一例》](20160529_02.md)
78
##### 20160529_01.md [《PostgreSQL 批量权限 管理方法》](20160529_01.md)
89
##### 20160528_01.md [《深入浅出PostgreSQL B-Tree索引结构》](20160528_01.md)

0 commit comments

Comments
 (0)