oracle.c
上传用户:topscale
上传日期:2007-01-08
资源大小:9k
文件大小:16k
源码类别:

数据库系统

开发平台:

C/C++

  1. /*
  2.  copyright: Paladin of http://www.programsalon.com
  3. */
  4. #include <stdio.h> #include <stdlib.h> #include "oracle.h" #include "../util/util.h" extern char *del_lr_spaces(char *pbuf); int db_init(DB_INFO *pdb) {   HRESULT hr;   pdb->m_hpEnv = NULL;   pdb->m_hpErr = NULL;   pdb->m_hpServer = NULL;   pdb->m_hpContext = NULL;   pdb->m_szError[0] =0;   pdb->m_hpSession =NULL;   pdb->m_pOracleTypes =NULL;   pdb->m_auto_commit =0;   CheckErr(pdb, (hr=OCIInitialize( OCI_OBJECT, NULL, NULL, NULL, NULL ) ));   if(FAILED(hr))     return -1;   CheckErr(pdb, (hr =OCIEnvInit( &pdb->m_hpEnv, OCI_DEFAULT, 0, NULL )) );   if ( FAILED(hr) )   {     printf("OCIEnvInit failed!n");     return -2;   }   // Allocate error, server, and service context handles   OCIHandleAlloc( pdb->m_hpEnv, (void**)&pdb->m_hpErr, OCI_HTYPE_ERROR, 0, NULL );   OCIHandleAlloc( pdb->m_hpEnv, (void**)&pdb->m_hpServer, OCI_HTYPE_SERVER, 0, NULL );   OCIHandleAlloc( pdb->m_hpEnv, (void**)&pdb->m_hpContext, OCI_HTYPE_SVCCTX, 0, NULL );   OCIHandleAlloc( pdb->m_hpEnv, (void**)&pdb->m_hpSession, OCI_HTYPE_SESSION, 0, NULL); } int db_exit(DB_INFO *pdb) {   HRESULT hr;   db_close(pdb);   if(pdb->m_hpSession)     OCIHandleFree(pdb->m_hpSession, OCI_HTYPE_SESSION);   // Free server handle   if (pdb->m_hpServer)     CheckErr(pdb, (hr =OCIHandleFree(pdb->m_hpServer, OCI_HTYPE_SERVER)));   // Free service context   if (pdb->m_hpContext)     OCIHandleFree( pdb->m_hpContext, OCI_HTYPE_SVCCTX);   // Free error handle   if (pdb->m_hpErr)     OCIHandleFree( pdb->m_hpErr, OCI_HTYPE_ERROR );   int i =0;   if(pdb->m_pOracleTypes)   {     while(pdb->m_pOracleTypes[i] !=NULL)       free(pdb->m_pOracleTypes[i++]);     free(pdb->m_pOracleTypes);     pdb->m_pOracleTypes =NULL;   } } int db_set_auto_commit(DB_INFO *pdb, int if_auto) {   pdb->m_auto_commit =if_auto;    return 0; } void CheckErr(DB_INFO *pdb, HRESULT status ) {   static struct CErrorPair   {     sword w;     const char* szText;   }epaErrors[] =   {     OCI_SUCCESS, "SUCCESS",     OCI_SUCCESS_WITH_INFO, "SUCCESS_WITH_INFO",     OCI_NEED_DATA, "NEED_DATA",     OCI_NO_DATA, "NO_DATA",     OCI_INVALID_HANDLE, "INVALID_HANDLE",     OCI_STILL_EXECUTING, "STILL_EXECUTE",     OCI_CONTINUE, "CONTINUE",   };   if ( status == OCI_ERROR )   {     sb4 errcode = 0;     OCIErrorGet(pdb->m_hpErr, 1, NULL, &errcode, (unsigned char*)pdb->m_szError, sizeof(pdb->m_szError), OCI_HTYPE_ERROR);   }   else   {     // Look for description in static array     DWORD nTotalResultCodes = sizeof(epaErrors) / sizeof(struct CErrorPair);     for ( int iPos = 0; iPos < sizeof(epaErrors); ++ iPos )     {       if ( epaErrors[iPos].w == status )       {         strcpy( pdb->m_szError, epaErrors[iPos].szText );         break;       }     }   } } char *db_get_error_string(DB_INFO *pdb) {   return pdb->m_szError; } int db_connect(DB_INFO *pdb, char *server, char *user, char *pass) {   HRESULT hr;   // Associate TNS with server handle   CheckErr(pdb, (hr =OCIServerAttach( pdb->m_hpServer, pdb->m_hpErr, (unsigned char*)(char*)server, strlen(server),0 )));   if ( FAILED(hr) )   {     printf("OCIServerAttach failed!n");     return -3;   }   // Get server version string   char version[1024];   CheckErr(pdb, (hr =OCIServerVersion( pdb->m_hpServer, pdb->m_hpErr,     (text*)version, sizeof(version), OCI_HTYPE_SERVER )));   if ( FAILED(hr) )     return -4;   //m_csLog += csVersion + "n";   // Specify server handle to service context   CheckErr(pdb, (hr =OCIAttrSet( pdb->m_hpContext, OCI_HTYPE_SVCCTX, pdb->m_hpServer, 0, OCI_ATTR_SERVER, pdb->m_hpErr )));   if ( FAILED(hr) )      return -5;   // Allocate a session handle   // Associate username with session handle   OCIAttrSet( pdb->m_hpSession, OCI_HTYPE_SESSION, (void*)(const char*)user,   strlen(user), OCI_ATTR_USERNAME, pdb->m_hpErr);   // Associate password with session handle   OCIAttrSet( pdb->m_hpSession, OCI_HTYPE_SESSION, (void*)(const char*)pass,     strlen(pass), OCI_ATTR_PASSWORD, pdb->m_hpErr);   // Open session using service context and session handle   CheckErr(pdb, (hr =OCISessionBegin( pdb->m_hpContext, pdb->m_hpErr, pdb->m_hpSession, OCI_CRED_RDBMS, OCI_DEFAULT )));   if ( FAILED(hr) )     return -6;   // Specify session handle to service context   OCIAttrSet( pdb->m_hpContext, OCI_HTYPE_SVCCTX, pdb->m_hpSession, 0, OCI_ATTR_SESSION, pdb->m_hpErr);   // Change date format   if ( SUCCEEDED(hr) )   {     char *csSQL = "alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss'";     if(db_exec(pdb, csSQL ) <0)       return -7;   }   else return -8;   return TRUE; } int db_close(DB_INFO *pdb) {   HRESULT hr;   if(pdb->m_auto_commit) db_commit(pdb);   // Free select statement handle   // Detach server from server handle   if(pdb->m_hpSession)   {     OCISessionEnd(pdb->m_hpContext, pdb->m_hpErr, pdb->m_hpSession, OCI_DEFAULT);   }   if (pdb->m_hpServer)     OCIServerDetach( pdb->m_hpServer, pdb->m_hpErr, OCI_DEFAULT );   if(FAILED(hr)) return FALSE;   return TRUE; } int db_exec(DB_INFO *pdb, char *stmt) {   HRESULT hr;   OCIStmt *hpStatement = NULL;   CheckErr(pdb, (hr =OCIHandleAlloc( pdb->m_hpEnv,(void**)&hpStatement, OCI_HTYPE_STMT, 0, NULL )));   if(FAILED(hr))     return -1;   // Associate statement string with handle   CheckErr(pdb, (hr =OCIStmtPrepare( hpStatement, pdb->m_hpErr,      (text *)stmt, strlen(stmt), OCI_NTV_SYNTAX, OCI_DEFAULT )));   if(FAILED(hr))   {     if(hpStatement)       OCIHandleFree( hpStatement, OCI_HTYPE_STMT );     return -2;   }   // Execute statement   CheckErr(pdb, (hr =OCIStmtExecute( pdb->m_hpContext, hpStatement, pdb->m_hpErr,1, 0, // row offset NULL, NULL, // snapshot in/out OCI_DEFAULT )));   // Free statement handle   if(FAILED(hr))   {     OCIHandleFree( hpStatement, OCI_HTYPE_STMT );     return -3;   }   if(pdb->m_auto_commit) db_commit(pdb);   int row_count =0;   CheckErr(pdb, (hr=OCIAttrGet(hpStatement, OCI_HTYPE_STMT, (ub2 *)&row_count, (ub4 *)0, OCI_ATTR_ROW_COUNT, pdb->m_hpErr)));   OCIHandleFree( hpStatement, OCI_HTYPE_STMT );   if(FAILED(hr))     return 0;   else return row_count; } #if defined(__STDC__) || defined(__cplusplus) int db_begin_trans(DB_INFO *pdb) #else int db_begin_trans(pdb) DB_INFO *pdb; #endif {   if(FAILED(OCITransStart(pdb->m_hpContext, pdb->m_hpErr, 10, OCI_TRANS_NEW)))     return -1;   return 0; } #if defined(__STDC__) || defined(__cplusplus) int db_roll_back(DB_INFO *pdb) #else int db_roll_back(pdb) DB_INFO *pdb; #endif {   if(FAILED(OCITransRollback(pdb->m_hpContext, pdb->m_hpErr, 0)))     return -1;   return 0; } #if defined(__STDC__) || defined(__cplusplus) int db_commit(DB_INFO *pdb) #else int db_commit(DB_INFO *pdb) DB_INFO *pdb; #endif  {   if(FAILED(OCITransCommit(pdb->m_hpContext, pdb->m_hpErr, 0)))     return -1;   return 0; } int db_query_init(DB_QUERY_INFO *pquery, DB_INFO *pdb) {   pquery->pdb=pdb;   pquery->m_hpSelect =NULL;   pquery->m_BindFields =NULL;   pquery->FieldValues =NULL; } void db_query_close(DB_QUERY_INFO *pquery) {   if(pquery->m_hpSelect)     OCIHandleFree( pquery->m_hpSelect, OCI_HTYPE_STMT );   pquery->m_hpSelect =NULL;   if(pquery->m_BindFields)   {     for(int i =0; i<pquery->FieldCount; i++)     {       if(pquery->m_BindFields[i])       {         if(pquery->m_BindFields[i]->pBuffer)         free(pquery->m_BindFields[i]->pBuffer);         free(pquery->m_BindFields[i]);       }     }     free(pquery->m_BindFields);     pquery->m_BindFields =NULL;   }   if(pquery->FieldValues) free(pquery->FieldValues);   pquery->FieldValues =NULL; } int db_query_select(DB_QUERY_INFO *pquery, char *stmt) {   HRESULT hr;   pquery->RecCount =pquery->FieldCount =0;   if(pquery->m_hpSelect)   {     OCIHandleFree( pquery->m_hpSelect, OCI_HTYPE_STMT );     pquery->m_hpSelect =NULL;   }   CheckErr(pquery->pdb, (hr =OCIHandleAlloc( pquery->pdb->m_hpEnv, (void**)&pquery->m_hpSelect, // ref to statement handle pointer OCI_HTYPE_STMT, // type of handle being allocated 0, NULL )));   if(FAILED(hr))     return -1;   // Associate statement string with handle   CheckErr(pquery->pdb, (hr =OCIStmtPrepare( pquery->m_hpSelect, pquery->pdb->m_hpErr, // error handle pointer (text *)stmt, // statement string strlen(stmt), OCI_NTV_SYNTAX, // specify native syntax OCI_DEFAULT )));   if(FAILED(hr))   {     db_query_close(pquery);     return -1;   }   // Execute but don't fetch yet   CheckErr(pquery->pdb, (hr =(OCIStmtExecute( pquery->pdb->m_hpContext, pquery->m_hpSelect, // prepared by previous function calls pquery->pdb->m_hpErr, 0, // 'iters' i.e. max rows to fetch during this call 0, NULL, NULL, OCI_DEFAULT ))));   // If it returns OCI_NO_DATA then no need to define recordset   if ( hr == OCI_NO_DATA)   {     db_query_close(pquery);     return 0;   }   if(FAILED(hr) )   {     db_query_close(pquery);     return -1;   }   // Load the types into recordset   pquery->FieldCount = 0;   while ( hr == OCI_SUCCESS )   {     // Get pointer to column     void* pFieldAttr = NULL;     HRESULT hrGetNext;     hrGetNext = OCIParamGet( pquery->m_hpSelect, OCI_HTYPE_STMT, pquery->pdb->m_hpErr, &pFieldAttr, pquery->FieldCount+1 // position     );     if ( hrGetNext != OCI_SUCCESS )       break;     // Increment column count and allocate an OdbField structure     ++pquery->FieldCount;     BindField* pField = (BindField *)malloc(sizeof(BindField));     pField->pBuffer =NULL;     if(pquery->m_BindFields ==NULL)       pquery->m_BindFields =(BindField **)malloc(pquery->FieldCount*sizeof(BindField *));     else       pquery->m_BindFields =(BindField **)realloc(pquery->m_BindFields, pquery->FieldCount*sizeof(BindField *));     pquery->m_BindFields[pquery->FieldCount-1] =pField;     if(pquery->FieldValues ==NULL)       pquery->FieldValues =(char **)malloc(pquery->FieldCount*sizeof(char *));     else       pquery->FieldValues =(char **)realloc(pquery->FieldValues, pquery->FieldCount*sizeof(char *));     pquery->FieldValues[pquery->FieldCount-1] =NULL;     // Get data type     CheckErr(pquery->pdb, (hr =OCIAttrGet( pFieldAttr, OCI_DTYPE_PARAM, &pField->wType, 0, OCI_ATTR_DATA_TYPE, pquery->pdb->m_hpErr )));     if(FAILED(hr))     {       db_query_close(pquery);       return -1;     }     // Get data size     CheckErr(pquery->pdb, (hr =OCIAttrGet( pFieldAttr, OCI_DTYPE_PARAM, &pField->wSize, 0, OCI_ATTR_DATA_SIZE, pquery->pdb->m_hpErr )));     if(FAILED(hr))     {       db_query_close(pquery);       return -1;     }     // Type conversions     pField->m_type =SQL_TYPE_STR;     if ( pField->wType == SQLT_LNG )     {       // LONG size       pField->wSize = 32760;     }     else if ( pField->wType == SQLT_DAT )     {       // String is bound to DATE       pField->wType = SQLT_STR;       pField->wSize = 50;       pField->m_type =SQL_TYPE_DATE;     }     else if ( pField->wType == SQLT_NUM )     {       // String is bound to NUMBER       pField->wType = SQLT_STR;       pField->wSize = 30; // allow for null-terminator     }     // Get column name     ub4 nNameLen =0; text *p =NULL;     CheckErr(pquery->pdb, (hr =OCIAttrGet( pFieldAttr, OCI_DTYPE_PARAM, (void**)&p, &nNameLen, OCI_ATTR_NAME, pquery->pdb->m_hpErr ))); strncpy(pField->name, p, nNameLen); pField->name[nNameLen] =0; //printf("name=%s, size=%dn", pField->name,pField->wSize);  //printf("debug:oracle.c:db_query_select:field name %s, tnNameLen=%dn",pField->name, nNameLen);     upper_case(pField->name);     // Set size and name     pField->pBuffer =(dvoid *)malloc( pField->wSize+1 );     memset(pField->pBuffer, 0, pField->wSize+1);     //pField->csName.Format( "%.*s", nNameLen, pName );     //FieldValues[FieldCount-1] =(char *)malloc(pField->wSize+1);     //memset(FieldValues[FieldCount-1], 0, pField->wSize+1);     pquery->FieldValues[pquery->FieldCount-1] =(char *)pField->pBuffer;    }   // Bind storage for receiving input variables   OCIDefine *pDefn; // to hold pointer to field definition   int iField;   for ( iField=0; iField<pquery->FieldCount; ++iField )   {     // Get pointer to field structure     BindField* pField = pquery->m_BindFields[iField];     // Bind     pDefn = NULL;     CheckErr(pquery->pdb, (hr =OCIDefineByPos( pquery->m_hpSelect, &pDefn, // function allocs and gives back a pointer to field definition pquery->pdb->m_hpErr, iField+1, // position in select starting at 1 pField->pBuffer, // storage area for field result pField->wSize, // sizeof storage area pField->wType, // field type &pField->nInd, // indp, null indicator &pField->wLen, // rlenp NULL, OCI_DEFAULT )));     if(FAILED(hr))     {       db_query_close(pquery);       return -1;     }   }   // Fetch   //FetchNext();   return pquery->FieldCount; } int db_query_fetch(DB_QUERY_INFO *pquery) {   HRESULT hr;   CheckErr(pquery->pdb, (hr =OCIStmtFetch( pquery->m_hpSelect, pquery->pdb->m_hpErr, 1, // 'nrows' i.e. max rows OCI_FETCH_NEXT,  OCI_DEFAULT )));   // Set result to 0 if no data returned   if ( SUCCEEDED(hr) && hr != OCI_NO_DATA )   {     pquery->RecCount ++;     for(int i=0; i<pquery->FieldCount; i++)     {       pquery->FieldValues[i][pquery->m_BindFields[i]->wLen] =0;       del_lr_spaces(pquery->FieldValues[i]);     }   }   else if(hr ==OCI_NO_DATA)     return 0;   else return -1;   return 1; } int db_query_is_eos(DB_QUERY_INFO *pquery) { return FALSE; } char *get_field_value(DB_QUERY_INFO *pquery, int field_num) {   if(field_num >=pquery->FieldCount) return NULL;   return pquery->FieldValues[field_num]; } char *get_field_value2(DB_QUERY_INFO *pquery, int field_num, char *buf) {   *buf =0;   if(field_num >=pquery->FieldCount) return NULL;   strcpy(buf, pquery->FieldValues[field_num]);   return buf; } char *get_field_value_by_name(DB_QUERY_INFO *pquery, char *field_name) {   if(field_name ==NULL) return NULL;   upper_case(field_name);   for(int i =0; i<pquery->FieldCount; i++)   {     if(!strcmp(field_name, pquery->m_BindFields[i]->name))     {       return pquery->FieldValues[i];     }   }   return NULL; } char *get_field_value_by_name2(DB_QUERY_INFO *pquery, char *field_name, char *buf) {   *buf =0;   if(field_name ==NULL) return NULL;   upper_case(field_name);   for(int i =0; i<pquery->FieldCount; i++)   {     if(!strcmp(field_name, pquery->m_BindFields[i]->name))     {       strcpy(buf, pquery->FieldValues[i]);       return buf;     }   }   return NULL; } int db_exec_bind_long(DB_INFO *pdb, char *sql_stmt, int count, char **long_values, int *long_sizes) {   HRESULT hr;   OCIStmt *hpstmt;   CheckErr(pdb, (hr =OCIHandleAlloc( pdb->m_hpEnv, (void**)&hpstmt, // ref to statement handle pointer OCI_HTYPE_STMT, // type of handle being allocated 0, NULL )));   if(FAILED(hr))   {     printf("OCIHandleAlloc failed!n");     return -1;   }   // Associate statement string with handle   CheckErr(pdb, (hr =OCIStmtPrepare( hpstmt, pdb->m_hpErr, // error handle pointer (text *)sql_stmt, // statement string strlen(sql_stmt), OCI_NTV_SYNTAX, // specify native syntax OCI_DEFAULT )));   if(FAILED(hr))   {     OCIHandleFree( hpstmt, OCI_HTYPE_STMT );     return -1;   }      int i;   OCIBind *pbind[20];   memset(pbind, 0, sizeof(pbind));   for(i=0; i<count && i<20; i++)   {     if(OCIBindByPos(hpstmt,&pbind[i], pdb->m_hpErr, i+1,         (dvoid *)long_values[i], (ub4)long_sizes[i],         SQLT_LNG/*LBI long binary type */, NULL, NULL, NULL, 0,         NULL, OCI_DEFAULT) !=0)     {       OCIHandleFree(hpstmt, OCI_HTYPE_STMT);       return -1;     }   }   // Execute but don't fetch yet   CheckErr(pdb, (hr =(OCIStmtExecute( pdb->m_hpContext, hpstmt, // prepared by previous function calls pdb->m_hpErr, 1, // 'iters' i.e. max rows to fetch during this call 0, NULL, NULL, OCI_DEFAULT ))));   if (FAILED(hr))   {   OCIHandleFree(hpstmt, OCI_HTYPE_STMT);     return -1;   }   //if(pdb->m_auto_commit) db_commit(pdb);   OCIHandleFree(hpstmt, OCI_HTYPE_STMT);   return 0; }