C语言和Oracle数据库都是广泛使用的技术,在实际开发中,有时候需要将图片保存到Oracle数据库中。本文将介绍如何使用C语言和Oracle,将图片保存到Oracle数据库。
首先,在C语言中读取图片并将图片转换成二进制格式。
FILE *fp;
long lSize;
unsigned char *buffer;
fp = fopen ( "test.jpg" , "rb" );
if( !fp ) {
printf("Image not found");
exit(1);
}
fseek( fp , 0L , SEEK_END);
lSize = ftell( fp );
rewind( fp );
buffer = (unsigned char*)calloc( 1, lSize+1 );
if( !buffer ){
fclose(fp);
printf("bad calloc");
exit(1);
}
if( 1!=fread( buffer , lSize, 1 , fp) ){
fclose(fp);
free(buffer);
printf("Read error");
exit(1);
}
接下来,将图片数据插入到Oracle表中。
OCIEnv* envhp = NULL;
OCIError *errhp = NULL;
OCIServer *srvhp = NULL;
OCISvcCtx *svchp = NULL;
OCISession *usrhp = NULL;
OCIStmt *stmthp = NULL;
OCIBind *bndhp1 = NULL, *bndhp2 = NULL;
// Initialize OCI environment.
if (OCIInitialize(OCI_DEFAULT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t))0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *))0 ))
printf("OCIInitialize failed.");
if (OCIEnvInit(&envhp, OCI_DEFAULT, 0, NULL))
printf("OCIEnvInit failed.");
// Initialize OCI handles.
OCIHandleAlloc((dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) NULL);
OCIHandleAlloc((dvoid *) envhp, (dvoid **) &srvhp, OCI_HTYPE_SERVER,(size_t) 0, (dvoid **) NULL);
OCIHandleAlloc((dvoid *) envhp, (dvoid **) &svchp, OCI_HTYPE_SVCCTX,(size_t) 0, (dvoid **) NULL);
OCIHandleAlloc((dvoid *) envhp, (dvoid **) &usrhp, OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) NULL);
// Logon to server.
OCIServerAttach(srvhp, errhp, (text *)"localhost:1521/orcl", (sb4) strlen("localhost:1521/orcl"), OCI_DEFAULT);
OCIAttrSet((dvoid *) svchp, OCI_HTYPE_SVCCTX, (dvoid *)srvhp, (ub4) 0, OCI_ATTR_SERVER, errhp);
OCIAttrSet((dvoid *) usrhp, OCI_HTYPE_SESSION, "username", strlen("username"), OCI_ATTR_USERNAME, errhp);
OCIAttrSet((dvoid *) usrhp, OCI_HTYPE_SESSION, "password", strlen("password"), OCI_ATTR_PASSWORD, errhp);
OCISessionBegin(svchp, errhp, usrhp, OCI_CRED_RDBMS, OCI_DEFAULT);
// Prepare SQL statement.
ociresult = OCIStmtPrepare(stmthp, errhp, (text *)"INSERT INTO IMAGES(ID, IMAGE) VALUES(:id, :image)", strlen("INSERT INTO IMAGES(ID, IMAGE) VALUES(:id, :image)"), OCI_NTV_SYNTAX, OCI_DEFAULT);
// Bind the parameters.
OCIParamGet(stmthp, OCI_HTYPE_STMT, errhp, (dvoid **)&prmhp, (ub4) 1);
OCIBindByName(stmthp, &bndhp1, errhp, (text *)":id", strlen(":id"), (dvoid *)(&record.id), sizeof(record.id), SQLT_INT, (dvoid *)&id_ind, (ub2 *)0, (ub2 *)0, 0, (ub4 *)0, OCI_DEFAULT);
OCIBindByName(stmthp, &bndhp2, errhp, (text *)":image", strlen(":image"), bindbuffer, txtlen, SQLT_BIN, (dvoid *)&img_ind, (ub2 *)0, (ub2 *)0, 0, (ub4 *)0, OCI_DEFAULT);
// Execute the statement and check for errors.
OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_COMMIT_ON_SUCCESS);
// Cleanup.
OCISessionEnd(svchp, errhp, usrhp, OCI_DEFAULT);
OCIServerDetach(srvhp, errhp, OCI_DEFAULT);
OCIHandleFree((dvoid *)usrhp, OCI_HTYPE_SESSION);
OCIHandleFree((dvoid *)svchp, OCI_HTYPE_SVCCTX);
OCIHandleFree((dvoid *)srvhp, OCI_HTYPE_SERVER);
OCIHandleFree((dvoid *)envhp, OCI_HTYPE_ENV);
可以看到,使用OCIBindByName绑定参数,并使用OCIStmtExecute执行SQL语句。图片数据存储在bindbuffer中,id存储在record.id中。
最后,我们来完整的看一下整个过程:
- 读取图片并将图片转换成二进制格式。
- 在Oracle数据库中创建表,表的结构为ID(int)和IMAGE(BLOB)。
- 使用OCIBindByName进行参数绑定和执行SQL语句来将图片数据插入到数据库中。
总体来说,使用C语言和Oracle存储图片并不复杂,只需在读取图片并转换格式后,将数据用Bind参数绑定后插入到数据库中即可实现。