根據fp自帶例子修改sql
一、testpg1.ppbash
Program testpg; { Demo program to test pascal connection with postgres database } { Translated from the testlibpq example program of PostGreSQL } Uses postgres,strings; Procedure exit_nicely(Conn : PPGconn); begin PQfinish(conn); halt(1); end; Var pghost,pgport,pgoptions,pgtty,dbname : Pchar; nFields,i,j : longint; conn : PPGConn; res : PPGresult; begin pghost := 'localhost'; { host name of the backend server } pgport := '5432'; { port of the backend server } pgoptions := NiL; { special options to start up the backend server } pgtty := NiL; { debugging tty for the backend server } dbName := 'template1'; { make a connection to the database } conn := PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); { check to see that the backend connection was successfully made } if (PQstatus(conn) = CONNECTION_BAD) then begin Writeln (stderr, 'Connection to database ',dbname,' failed.'); Writeln (stderr, PQerrorMessage(conn)); exit_nicely(conn); end; { start a transaction block } res := PQexec(conn, 'BEGIN'); if (PQresultStatus(res) <> PGRES_COMMAND_OK) then begin Writeln (stderr, 'BEGIN command failed'); PQclear(res); exit_nicely(conn); end; { * should PQclear PGresult whenever it is no longer needed to avoid * memory leaks } PQclear(res); { * fetch instances from the pg_database, the system catalog of * databases } res := PQexec(conn, 'DECLARE myportal CURSOR FOR select * from pg_database'); if (PQresultStatus(res) <> PGRES_COMMAND_OK) then begin Writeln (stderr, 'DECLARE CURSOR command failed'); PQclear(res); exit_nicely(conn); end; PQclear(res); res := PQexec(conn, 'FETCH ALL in myportal'); if (PQresultStatus(res) <> PGRES_TUPLES_OK) then begin Writeln (stderr, 'FETCH ALL command didn''t return tuples properly'); PQclear(res); exit_nicely(conn); end; { first, print out the attribute names } nFields := PQnfields(res); for i := 0 to nFields-1 do Write (PQfname(res, i),space (15-strlen(PQfname(res, i))) ); writeln; writeln; { next, print out the instances } for i := 0 to PQntuples(res)-1 do begin for j := 0 to nFields-1 do write(PQgetvalue(res, i, j),space (15-strlen(PQgetvalue(res, i,j)))); writeln; end; PQclear(res); { close the portal } res := PQexec(conn, 'CLOSE myportal'); PQclear(res); { end the transaction } res := PQexec(conn, 'END'); PQclear(res); { close the connection to the database and cleanup } PQfinish(conn); end.
編譯運行:dom
$ fpc testpg1.pp Free Pascal Compiler version 3.0.4 [2017/10/03] for x86_64 Copyright (c) 1993-2017 by Florian Klaempfl and others Target OS: Linux for x86-64 Compiling testpg1.pp Linking testpg1 /usr/bin/ld: 警告: link.res 含有輸出節;您忘記了 -T? 105 lines compiled, 0.1 sec ~/prg/mypas/psqlExample$ ./testpg1 datname datdba encoding datcollate datctype datistemplate datallowconn datconnlimit datlastsysoid datfrozenxid datminmxid dattablespace datacl template1 10 6 zh_CN.UTF-8 zh_CN.UTF-8 t t -1 12410 656 1 1663 {=c/postgres,postgres=CTc/postgres} template0 10 6 zh_CN.UTF-8 zh_CN.UTF-8 t f -1 12410 656 1 1663 {=c/postgres,postgres=CTc/postgres} postgres 10 6 zh_CN.UTF-8 zh_CN.UTF-8 f t -1 12410 656 1 1663 mymotif 16393 6 zh_CN.UTF-8 zh_CN.UTF-8 f t -1 12410 656 1 16394 mydb 16393 6 zh_CN.UTF-8 zh_CN.UTF-8 f t -1 12410 656 1 16396 testdb 16393 6 zh_CN.UTF-8 zh_CN.UTF-8 f t -1 12410 656 1 16394 drupal8.2.1 16393 6 zh_CN.UTF-8 zh_CN.UTF-8 f t -1 12410 656 1 16473
2、testpg2.ppsocket
Program testpg; { Demo program to test pascal connection with postgres database } { Translated from the testlibpq example program of PostGreSQL } Uses postgres,strings; Procedure exit_nicely(Conn : PPGconn); begin PQfinish(conn); halt(1); end; Var pghost,pgport,pgoptions,pgtty,dbname : Pchar; nFields,i : longint; conn : PPGConn; res : PPGresult; dummy : string; begin pghost := 'localhost'; { host name of the backend server } pgport := '5432'; { port of the backend server } pgoptions := NiL; { special options to start up the backend server } pgtty := NiL; { debugging tty for the backend server } if paramcount=1 then begin dummy:=paramstr(1)+#0; dbname:=@dummy[1]; end else dbName := 'testdb'; { make a connection to the database } conn := PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); { check to see that the backend connection was successfully made } if (PQstatus(conn) = CONNECTION_BAD) then begin Writeln (stderr, 'Connection to database ',dbname,' failed.'); Writeln (stderr, PQerrorMessage(conn)); exit_nicely(conn); end; res := PQexec(conn, 'select * from userdeatail'); if (PQresultStatus(res) <> PGRES_TUPLES_OK) then begin Writeln (stderr, 'select command failed.'); PQclear(res); exit_nicely(conn); end; { first, print out the attribute names } nFields := PQnfields(res); Write ('|',PQfname(res, 0),space (4-strlen(PQfname(res, 0))) ); Write ('|',PQfname(res, 1),space (20-strlen(PQfname(res, 1))) ); Write ('|',PQfname(res, 2),space (40-strlen(PQfname(res, 2))) ); writeln ('|'); writeln ('+----+--------------------+----------------------------------------+'); { next, print out the instances } for i := 0 to PQntuples(res)-1 do begin write('|',PQgetvalue(res, i, 0),space (4-strlen(PQgetvalue(res, i,0)))); write('|',PQgetvalue(res, i, 1),space (20-strlen(PQgetvalue(res, i,1)))); write('|',PQgetvalue(res, i, 2),space (40-strlen(PQgetvalue(res, i,2)))); writeln ('|'); end; PQclear(res); { close the connection to the database and cleanup } PQfinish(conn); end.
testdb庫中表:tcp
CREATE TABLE userdeatail ( uid integer, intro character varying(30), profile character varying(30) );
編譯運行:ide
$ fpc testpg2.pp Free Pascal Compiler version 3.0.4 [2017/10/03] for x86_64 Copyright (c) 1993-2017 by Florian Klaempfl and others Target OS: Linux for x86-64 Compiling testpg2.pp testpg2.pp(19,3) Note: Local variable "nFields" is assigned but never used Linking testpg2 /usr/bin/ld: 警告: link.res 含有輸出節;您忘記了 -T? 78 lines compiled, 0.1 sec 1 note(s) issued $ ./testpg2 |uid |intro |profile | +----+--------------------+----------------------------------------+ |11 |wxw |pppp |
3、一些出錯的處理:
(1)編譯鏈接時找不到-lpq庫:
$ fpc testpg1.pp
/usr/bin/ld: 找不到 -lpq
testpg1.pp(107,1) Error: Error while linking
testpg1.pp(107,1) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
改成:
$ fpc testpg1.pp -Fl/opt/PostgreSQL/10/lib(/opt/PostgreSQL/10爲PostgreSQL實際安裝的路徑)
或在Makefile中處理:
追加環境變量:export PGLIBDIR=/opt/PostgreSQL/10/lib
在Makefile中增長下面內容:
ifdef PGLIBDIR
override FPCOPT+=$(addprefix -Fl,$(PGLIBDIR))
endifpost
(2)、出現Unix domain socket鏈接錯誤:
$ ./testpg1
Connection to database template1 failed.
could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
有兩種處理方法:
一、指定pg Unix domain socket的位置
在.bashrc中設置環境變量$PGHOST:export PGHOST=/tmp
二、改用tcp/ip鏈接方式:
即pghost := NiL; 改成 pghost := 'localhost'; {或pghost := '127.0.0.1'}fetch
(3)、出現用戶名密碼錯誤
$ ./testpg1
Connection to database template1 failed.
fe_sendauth: no password supplied
處理方法:PQsetdb,改成PQsetdbLogin
即:conn=PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
改成:conn=PQsetdbLogin(pghost,pgport,pgoptions,pgtty,dbname,user,pwd)ui
修改後代碼testpg1.ppspa
Program testpg; { Demo program to test pascal connection with postgres database } { Translated from the testlibpq example program of PostGreSQL } Uses postgres,strings; Procedure exit_nicely(Conn : PPGconn); begin PQfinish(conn); halt(1); end; Var pghost,pgport,pgoptions,pgtty,dbname,myuser,passwd : Pchar; nFields,i,j : longint; conn : PPGConn; res : PPGresult; begin pghost := 'localhost'; { host name of the backend server } pgport := NiL; { port of the backend server } pgoptions := NiL; { special options to start up the backend server } pgtty := NiL; { debugging tty for the backend server } dbName := 'template1'; myuser:='postgres'; passwd:='wxwpxh'; { make a connection to the database } {conn := PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);} conn := PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName,myuser,passwd); { check to see that the backend connection was successfully made } if (PQstatus(conn) = CONNECTION_BAD) then begin Writeln (stderr, 'Connection to database ',dbname,' failed.'); Writeln (stderr, PQerrorMessage(conn)); exit_nicely(conn); end; { start a transaction block } res := PQexec(conn, 'BEGIN'); if (PQresultStatus(res) <> PGRES_COMMAND_OK) then begin Writeln (stderr, 'BEGIN command failed'); PQclear(res); exit_nicely(conn); end; { * should PQclear PGresult whenever it is no longer needed to avoid * memory leaks } PQclear(res); { * fetch instances from the pg_database, the system catalog of * databases } res := PQexec(conn, 'DECLARE myportal CURSOR FOR select * from pg_database'); if (PQresultStatus(res) <> PGRES_COMMAND_OK) then begin Writeln (stderr, 'DECLARE CURSOR command failed'); PQclear(res); exit_nicely(conn); end; PQclear(res); res := PQexec(conn, 'FETCH ALL in myportal'); if (PQresultStatus(res) <> PGRES_TUPLES_OK) then begin Writeln (stderr, 'FETCH ALL command didn''t return tuples properly'); PQclear(res); exit_nicely(conn); end; { first, print out the attribute names } nFields := PQnfields(res); for i := 0 to nFields-1 do Write (PQfname(res, i),space (15-strlen(PQfname(res, i))) ); writeln; writeln; { next, print out the instances } for i := 0 to PQntuples(res)-1 do begin for j := 0 to nFields-1 do write(PQgetvalue(res, i, j),space (15-strlen(PQgetvalue(res, i,j)))); writeln; end; PQclear(res); { close the portal } res := PQexec(conn, 'CLOSE myportal'); PQclear(res); { end the transaction } res := PQexec(conn, 'END'); PQclear(res); { close the connection to the database and cleanup } PQfinish(conn); end.
修改後testpg2.pp代碼:
Program testpg; { Demo program to test pascal connection with postgres database } { Translated from the testlibpq example program of PostGreSQL } Uses postgres,strings; Procedure exit_nicely(Conn : PPGconn); begin PQfinish(conn); halt(1); end; Var pghost,pgport,pgoptions,pgtty,dbname,myuser,passwd : Pchar; nFields,i : longint; conn : PPGConn; res : PPGresult; dummy : string; begin pghost := 'localhost'; { host name of the backend server } pgport := '5432'; { port of the backend server } pgoptions := NiL; { special options to start up the backend server } pgtty := NiL; { debugging tty for the backend server } myuser:='mymotif'; passwd:='wxwpxh'; if paramcount=1 then begin dummy:=paramstr(1)+#0; dbname:=@dummy[1]; end else dbName := 'testdb'; { make a connection to the database } {conn := PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);} conn := PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName,myuser,passwd); { check to see that the backend connection was successfully made } if (PQstatus(conn) = CONNECTION_BAD) then begin Writeln (stderr, 'Connection to database ',dbname,' failed.'); Writeln (stderr, PQerrorMessage(conn)); exit_nicely(conn); end; res := PQexec(conn, 'select * from userdeatail'); if (PQresultStatus(res) <> PGRES_TUPLES_OK) then begin Writeln (stderr, 'select command failed.'); PQclear(res); exit_nicely(conn); end; { first, print out the attribute names } nFields := PQnfields(res); Write ('|',PQfname(res, 0),space (4-strlen(PQfname(res, 0))) ); Write ('|',PQfname(res, 1),space (20-strlen(PQfname(res, 1))) ); Write ('|',PQfname(res, 2),space (40-strlen(PQfname(res, 2))) ); writeln ('|'); writeln ('+----+--------------------+----------------------------------------+'); { next, print out the instances } for i := 0 to PQntuples(res)-1 do begin write('|',PQgetvalue(res, i, 0),space (4-strlen(PQgetvalue(res, i,0)))); write('|',PQgetvalue(res, i, 1),space (20-strlen(PQgetvalue(res, i,1)))); write('|',PQgetvalue(res, i, 2),space (40-strlen(PQgetvalue(res, i,2)))); writeln ('|'); end; PQclear(res); { close the connection to the database and cleanup } PQfinish(conn); end.