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參數綁定后插入到數據庫中即可實現。