您的位置:首页 > 数据库

【转】PostgreSQL 数据库C语言代码实现【数据库连接,创建表, 以及增删改查】

2013-04-24 13:50 991 查看
首先YY下,postgreSQL数据库是一开源数据库,使用的人貌似不多,差了好半天的资料也没找到合适的,最后别人给了个链接,

是英文版的,写的很详细!文章如下:

Inthisarticle,I’llshowyouanexampleonhowtointegratethePostgreSQLC++libraryintoyourC++projectsolution.ThePostgreSQLversionthatiamusingforthisexampleisPostgreSQLforWindowsversion
8.4.4.Incaseyoudon’thavePostgreSQLinstalledonyourmachine,youcandownloaditatpostgresql-8.4.4-1-windows.exe.
Youmayneedtoprovidesomedetailsfirstbeforestarttodownload.MakesurethatyouhaveinstalledPostgreSQLsuccessfullyandpleaseREMEMBERyourpasswordtologintoPostgreSQLthroughitscommandconsolewindowsinlater.Let’sstarttocreateadatabase
forthisexamplenow.Runthepsqlinthecommandwindowsandcreateanewdatabasenamed“testdb”asthefollowingscreenshot.



Oncethedatabasehasbeencreated,wearenowreadyforthecodingpart.Let’screateaWin32consoleapplicationnow(Iamusingvisualstudio2005forthisexample).ThefirsttaskweneedtodorightnowistoincludethePostgreSQLC++interfaceheader
fileandlibtoourproject.Youcandothatbyrightclickyourprojectsolutionandclickproperties.Note1:Youmightneedtochangethefollowingfilepathaccordingly.[C/C++->General->AdditionalIncludeDirectories]C:\Program
Files\PostgreSQL\8.4\include[Linker->General->AdditionalLibraryDirectories]C:\ProgramFiles\PostgreSQL\8.4\lib[Linker->Input->AdditionalDependencies]libpq.libNote2:Atthe
endofthisexample,youwillneedtocopyyourprojectoutput(EXE)to..\PostgreSQL\8.4\bin.Alternately,youcancopyallDLLslocatedat..\PostgreSQL\8.4\bin\toyouprojectoutputfolder.




PS:我在项目里面添加的库文件只有一个,一个是libqp.lib,另外一个是对应的libpq.dll

Wewillstartthecodingpartinourcppfilenow.Makesurethatyouincludethefollowingheaderaccordingly.libpq-fe.hmustbeincluded.

#include<string>
#include<libpq-fe.h>

Wewillstartthecodingpartinourcppfilenow.Makesurethatyouincludethefollowingheaderaccordingly.libpq-fe.hmustbeincluded.

/*Closeconnectiontodatabase*/
voidCloseConn(PGconn*conn)
{
PQfinish(conn);
getchar();
exit(1);
}



Next,wecreateafunctionnamedConnectDB().ThisfunctionwillestablishaconnectiontoPostgreSQLserver.PleasebesurethatyouprovidethecorrectparametersinPostgreSQL().Priortothisexample,ihavesetupadatabasecalledtestdbwithuser
passwordoftest123duringtheinstallation.Youmightneedtomodifyitaccordinglyinordertomakesurethecompilationsuccess.

/*Establishconnectiontodatabase*/
PGconn*ConnectDB()
{
PGconn*conn=NULL;

//Makeaconnectiontothedatabase
conn=PQconnectdb("user=postgrespassword=test123dbname=testdbhostaddr=127.0.0.1port=5432");

//Checktoseethatthebackendconnectionwassuccessfullymade
if(PQstatus(conn)!=CONNECTION_OK)
{
printf("Connectiontodatabasefailed");
CloseConn(conn);
}

printf("Connectiontodatabase-OK\n");

returnconn;
}



Next,wecreateafunctionnamedCreateEmployeeTable().Thisfunctionwillcreateanemployeetableinourtestdbdatabase.

/*Createemployeetable*/
voidCreateEmployeeTable(PGconn*conn)
{
//Executewithsqlstatement
PGresult*res=PQexec(conn,"CREATETABLEemployee(Fnamechar(30),Lnamechar(30))");

if(PQresultStatus(res)!=PGRES_COMMAND_OK)
{
printf("Createemployeetablefailed");
PQclear(res);
CloseConn(conn);
}

printf("Createemployeetable-OK\n");

//Clearresult
PQclear(res);
}

这里我想补充一下,创建表也可以在SQLshell(psql)里面创建:



首先连接数据库,然后执行createtable的sql语句,注意各个字段的数据类型,注意语句最后用“;”分号结尾。

Next,wecreateafunctionnamedInsertEmployeeRec().Thisfunctionwilltake2parameters,fnameandlnameincharpointertype,toformaSQLstatement.Itthenwillbeexecutedinordertostoretherecordintotheemployeetable.

/*AppendSQLstatementandinsertrecordintoemployeetable*/
voidInsertEmployeeRec(PGconn*conn,char*fname,char*lname)
{
//AppendtheSQLstatment
std::stringsSQL;
sSQL.append("INSERTINTOemployeeVALUES('");
sSQL.append(fname);
sSQL.append("','");
sSQL.append(lname);
sSQL.append("')");

//Executewithsqlstatement
PGresult*res=PQexec(conn,sSQL.c_str());

if(PQresultStatus(res)!=PGRES_COMMAND_OK)
{
printf("Insertemployeerecordfailed");
PQclear(res);
CloseConn(conn);
}

printf("Insertemployeerecord-OK\n");

//Clearresult
PQclear(res);
}



Next,wecreateafunctionnamedFetchEmployeeRec().Thisfunctionwillfetchalltherecordinemployeetableanddisplayitontheconsolewindows.

/*Fetchemployeerecordanddisplayitonscreen*/
voidFetchEmployeeRec(PGconn*conn)
{
//Willholdthenumberoffieldinemployeetable
intnFields;

//Startatransactionblock
PGresult*res=PQexec(conn,"BEGIN");

if(PQresultStatus(res)!=PGRES_COMMAND_OK)
{
printf("BEGINcommandfailed");
PQclear(res);
CloseConn(conn);
}

//Clearresult
PQclear(res);

//Fetchrowsfromemployeetable
res=PQexec(conn,"DECLAREemprecCURSORFORselect*fromemployee");
if(PQresultStatus(res)!=PGRES_COMMAND_OK)
{
printf("DECLARECURSORfailed");
PQclear(res);
CloseConn(conn);
}

//Clearresult
PQclear(res);

res=PQexec(conn,"FETCHALLinemprec");

if(PQresultStatus(res)!=PGRES_TUPLES_OK)
{
printf("FETCHALLfailed");
PQclear(res);
CloseConn(conn);
}

//Getthefieldname
nFields=PQnfields(res);

//Preparetheheaderwithemployeetablefieldname
printf("\nFetchemployeerecord:");
printf("\n********************************************************************\n");
for(inti=0;i<nFields;i++)
printf("%-30s",PQfname(res,i));
printf("\n********************************************************************\n");

//Next,printouttheemployeerecordforeachrow
for(inti=0;i<PQntuples(res);i++)
{
for(intj=0;j<nFields;j++)
printf("%-30s",PQgetvalue(res,i,j));
printf("\n");
}

PQclear(res);

//Closetheemprec
res=PQexec(conn,"CLOSEemprec");
PQclear(res);

//Endthetransaction
res=PQexec(conn,"END");

//Clearresult
PQclear(res);
}



Next,wecreateafunctionnamedRemoveAllEmployeeRec().Thisfunctionwillremoveallrecordinemployeetable.

/*Eraseallrecordinemployeetable*/
voidRemoveAllEmployeeRec(PGconn*conn)
{
//Executewithsqlstatement
PGresult*res=PQexec(conn,"DELETEFROMemployee");

if(PQresultStatus(res)!=PGRES_COMMAND_OK)
{
printf("Deleteemployeesrecordfailed.");
PQclear(res);
CloseConn(conn);
}

printf("\nDeleteemployeesrecord-OK\n");

//Clearresult
PQclear(res);
}



Next,wecreateafunctionnamedDropEmployeeTable().Thisfunctionwilldroporremovetheemployeefromthetestdbdatabase.

/*Dropemployeetablefromthedatabase*/
voidDropEmployeeTable(PGconn*conn)
{
//Executewithsqlstatement
PGresult*res=PQexec(conn,"DROPTABLEemployee");

if(PQresultStatus(res)!=PGRES_COMMAND_OK)
{
printf("Dropemployeetablefailed.");
PQclear(res);
CloseConn(conn);
}

printf("Dropemployeetable-OK\n");

//Clearresult
PQclear(res);
}


Finally,weupdatethemainentrypointfunctionsothatitcallallthefunctionsthatwehavecreatedtodemonstratewhatweintendtoshowinthisexample.Finally,weupdatethemainentrypointfunctionsothatitcallallthefunctionsthatwehavecreated
todemonstratewhatweintendtoshowinthisexample.Finally,weupdatethemainentrypointfunctionsothatitcallallthefunctionsthatwehavecreatedtodemonstratewhatweintendtoshowinthisexample.Next,wecreateafunctionnamedConnectDB().
ThisfunctionwillestablishaconnectiontoPostgreSQLserver.PleasebesurethatyouprovidethecorrectparametersinPostgreSQL().Priortothisexample,ihavesetupadatabasecalledtestdbwithuserpasswordoftest123duringtheinstallation.You
mightneedtomodifyitaccordinglyinordertomakesurethecompilationsuccess.Finally,weupdatethemainentrypointfunctionsothatitcallallthefunctionsthatwehavecreatedtodemonstratewhatweintendtoshowinthisexample.

int_tmain(intargc,_TCHAR*argv[])
{
PGconn*conn=NULL;

conn=ConnectDB();
CreateEmployeeTable(conn);
InsertEmployeeRec(conn,"Mario","Hewardt");
InsertEmployeeRec(conn,"Daniel","Pravat");
FetchEmployeeRec(conn);

printf("\nPressENTERtoremoveallrecords&table.....\n");
getchar();

RemoveAllEmployeeRec(conn);
DropEmployeeTable(conn);

CloseConn(conn);

return0;
}



thentrytocompileandrunthisapplicationnow,youshouldseefollowingscreenshot:




Atthispoint,ifyourunningSELECTstatmentfromthePostgreSQLcommandconsole,youwillseethesamedatabeingdisplayonyouC++Win32consoleWindow.







创建表的时候,对于主键primarykey,往往有很多时候我们希望他做到自增,主键数据对于我们来说不是很关键的数据,但又不能少,比如昨天添加了100条数据,id最大为100,那么今天重启电脑了后,继续插入,那么id自动从101开始,逐个增大。

记得在sqlite里面好像用一个autoincrement来对主键进行说明,但是postgresql里面没有这么了,而是用一个serial来实现了这个功能,

CREATETABLEtablename(

colnameSERIAL

);

等价于声明下面几句话:

CREATESEQUENCEtablename_colname_seq;

CREATETABLEtablename(

colnameintegerDEFAULTnextval('tablename_colname_seq')NOTNULL

);

因此,我们就创建了一个整数字段并且把它的缺省数值安排为从一个序列发生器取值。应用了一个NOTNULL约束以确保空值不会被明确地插入。在大多数情况下你可能还希望附加一个UNIQUE或者PRIMARYKEY约束避免意外地插入重复的数值,但这个不是自动发生的。



注意:在PostgreSQL7.3以前,serial隐含UNIQUE。但现在不再如此。如果你希望一个序列字段有一个唯一约束或者一个主键,那么你现在必须声明,就像其它数据类型一样。

要使用serial字段插入序列的下一个数值到表中,主要是要注意serial应该赋予缺省值。我们可以通过在INSERT语句中把该字段排除在字段列表之外来实现,也可以通过使用DEFAULT关键字来实现。

比如:

>>createtablepk(idserialprimarykey,lastnametext,firstnametext);

>>CREATETABLEpk

>>insertintopkvalues('a','Hello','mary');//错误,id为序列不可以为字符,但是好像可以用小数吧。

>>insertintopkvalues(1,'AAA','BBB');//插入成功

>>insertintopkvalues(default,'BBBB','BBBB');//插入成功,default关键字会让id从2开始增加,同样的方法在插入一条,则id从3开始。

>>insertintopkvalues(2,'BBBBB‘,'NNNN’);id为2的一行已经存在(上面那条插入default时的),违反了notnull限制。



OK,thatsall,thanksformasters'sharing!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐