0
点赞
收藏
分享

微信扫一扫

基于Oracle OCI的数据访问C语言接口ORADBI


基于Oracle OCI的数据访问C语言接口ORADBI




​​cheungmine@gmail.com​​




Mar. 22, 2008



 



ORADBI是我在Oracle OCI(Oracle 调用接口)基础上开发的,支持Oracle8i、9i、10g等数据库。根据Oracle公司的介绍:OCI是如此可靠,以至于Oracle数据库中的每一条SQL语句都通过OCI来执行。当应用程序开发人员需要面向Oracle数据库服务器的最强大的接口时,他们将调用 Oracle调用接口(OCI)。OCI提供了对所有Oracle数据库功能的最全面的访问。OCI API中包含了最新的性能、可伸缩性和安全性特性。



采用OCI的最大好处就是:它是最切近Oracle底层的技术,因此,效率是最高的。同时,它是跨平台的。因此,在我给出的ORADBI库,除了OCI之外,没有其他外部依赖,稍加改动,就可以移植到非Windows平台上或其他嵌入式平台。






然而,OCI也比较不容易使用。它的功能之强,粒度之细,语法之烦琐,都不适合今天熟悉了快速开发模式的人员使用。然而,OCI的高效,直接根植于数据库核心,跨平台的语言特性,是其他如OO4O、OLEDB、ADO等COM方式不具备的。我最初开发Oralce数据库是4年以前,使用的是OO4O。直到最近,使用OCI成了我的爱好。于是,写了一套OCI的Helper库,方便OCI的使用。我不敢说是OCI的Wrapper库,因为我没能力包装OCI的方方面面。然而,我的ORADBI已经足够我(可能也包括你们)日常使用了。我就是用这套ORADBI操纵BLOB等大数据字段的。






公布这套ORADBI库,没有任何商业上的风险:我拥有这个库的全部版权,任何个人或团体可以为任何目的免费地、无限制地使用ORADBI库,前提是不能声明对ORADBI库的版权。对使用ORADBI库所造成的任何后果,我不负任何责任。如果这套软件对您的工作产生了很大的帮助,我不拒绝任何您的资助。






好了,让我们概览一下这个库,它包含下列文件:






.h文件                 .c文件
oradbi.h *              oradbi.c
oracol.h              oracol.c
oraconn.h           oraconn.c 
oradate.h            oradate.c
oraerr.h               oraerr.c
oraparam.h         oraparam.c

orarows.h            orarows.c
orastmt.h             orastmt.c
oratype.h

unistd.h
list.h                    list.c
hashmap.h        hashmap.c


       其中,oradbi.h是你唯一需要包含的头文件。当把ORADBI作为动态库连接到你的工程里使用时,你在你的项目里加入类似下面的代码:


//
test.cpp


#include
"
../oradbi/oradbi.h
"


#ifdef _DEBUG

#pragma
comment(lib, "../oradbi/debug/oradbid.lib")


#else


#pragma
comment(lib, "../oradbi/release/oradbi.lib")


#endif


    下面是oradbi.h的全部内容:



/*
======================================================================
oradbi.h - Created by cheungmine, All rights reserved.
First : Mar. 8, 2008
======================================================================*/

#ifndef ORADBI_H_INCLUDED

#define ORADBI_H_INCLUDED


#ifdef __cplusplus

extern "C"
{
#endif


#ifdef ORADBI_DLLEXPORT
# define ORADB_CALL __declspec(dllexport)
# define ORADB_CALL1(x) __declspec(dllexport) x

#endif


#ifndef ORADB_CALL
# define ORADB_CALL

#endif


#ifndef ORADB_CALL1
# define ORADB_CALL1(x) x ORADB_CALL

#endif



/* NOT SUPPORT UNICODE */

#ifdef UNICODE

#pragma message( __FILE__" Warning UNICODE: Cannot use UNICODE" )


#endif



/* NOT SUPPORT UNICODE */

#ifdef _UNICODE

#pragma message( __FILE__" Warning UNICODE: Cannot use UNICODE" )


#endif


#include
"unistd.h"

#include
"oratype.h"

#include
"oraerr.h"



/*
======================================================================
connection Functions - oraconn.c
======================================================================*/


/* connects the application to the oracle server. */

lresult ORADB_CALL ORA_connection_create (
OUT ora_connection
*
connection,
IN const char *
service_name,
IN const char *
username,
IN const char *
password,
IN ulong env_mode, /* =OCI_THREADED|OCI_OBJECT */

IN BOOL non_blocking_mode,
/* =FALSE */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* disconnects the application from the oracle server. */


void
ORADB_CALL ORA_connection_free (
IN ora_connection connection
);

/* executes a sql statement with no result */

lresult ORADB_CALL ORA_connection_execute (
IN ora_connection connection,
IN
const char *
sql_block,
IN int sql_len, /* -1 for strlen called*/

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* prepares (and returns) a sql statement for execution */

lresult ORADB_CALL ORA_connection_prepare (
IN ora_connection connection,
IN
const char *
sql_block,
IN int sql_len, /* -1 for strlen called*/

OUT ora_sqlstmt
*sqlstmt, /* a sql statement for execution returned */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* executes a select sql statement and return the result set */

lresult ORADB_CALL ORA_connection_select (
IN ora_connection connection,
IN
const char *
sql_select,
IN int sql_len, /* -1 for strlen called*/

OUT ora_rowset
*rowset, /* the result set returned */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* commits changes */

lresult ORADB_CALL ORA_connection_commit (
IN ora_connection connection,
OUT ora_error_t
*error /* NULL for no err msg return */

);


/* rollbacks changes */

lresult ORADB_CALL ORA_connection_rollback (
IN ora_connection connection,
OUT ora_error_t
*error /* NULL for no err msg return */

);


/*
======================================================================
sqlstmt Functions - orastmt.c
======================================================================*/

lresult ORADB_CALL ORA_sqlstmt_create (
OUT ora_sqlstmt
*
sqlstmt,
IN ora_connection connection,
IN const char *
sql_block,
IN int sql_len, /* -1 for strlen to be called*/

IN
ushort fetch_size, /* 0 for default or bind array size for INSERT */

OUT ora_error_t *error /* NULL for no err msg return */

);


void
ORADB_CALL ORA_sqlstmt_free (
IN ora_sqlstmt sqlstmt
);

/* executes a sql statement with no output parameters */

lresult ORADB_CALL ORA_sqlstmt_execute (
IN ora_sqlstmt sqlstmt,
IN ORADBI_ExecMode mode,
/* execute mode: MOD_DEFAULT=0 */

IN
ushort iters, /* 0 is default */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* executes a select sql statement and returns the result set */

lresult ORADB_CALL ORA_sqlstmt_select (
IN ora_sqlstmt sqlstmt,
IN ORADBI_ExecMode mode,
/* execute mode: MOD_DEFAULT=0 */

OUT ora_rowset
*
rowset,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* binds a named variable to sqlstmt but for lob, when type is set to ODT_UNKNOWN type is taken from name's prefix */

lresult ORADB_CALL ORA_sqlstmt_bind (
IN ora_sqlstmt sqlstmt,
IN
const char *name, /* param name bound */

IN ORADBI_DataType type,
/* param type bound. set ODT_UNKNOWN for simplely. cannot be a lob type */

IN
int size, /* param size for TEXT, LOB. 0 for others */

OUT ora_param *param, /* a out param bound to sqlstmt */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* binds a named variable to sqlstmt only with lob type */

lresult ORADB_CALL ORA_sqlstmt_bind_lob (
IN ora_sqlstmt sqlstmt,
IN
const char *name, /* param name bound */

IN
int max_size, /* maximum size of lob data, 0 for default. if 0, client_data must be a valid pointer */

IN ORADBI_InBind
*inbind, /* can be null. if null, max_size must be a meaningful value not more than 65535 */

IN ORADBI_OutBind
*outbind, /* can be null */

OUT ora_param *param, /* a out param bound to sqlstmt */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* accesses param in the sqlstmt by name. gets a reference to param */

ora_param ORADB_CALL ORA_sqlstmt_get_param_by_name (
IN ora_sqlstmt sqlstmt,
IN
const char* param_name, /* MUST be a valid name string */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* accesses param in the sqlstmt by index: 1-based. gets a reference to param */

ora_param ORADB_CALL ORA_sqlstmt_get_param_by_index (
IN ora_sqlstmt sqlstmt,
IN
ushort param_index, /* PARAM_INDEX_BASE based */

OUT ora_error_t *error /* NULL for no err msg return */

);



/*
======================================================================
rowset Functions - orarows.c
======================================================================*/


/* returns number of rows fetched so far */

lresult ORADB_CALL ORA_rowset_num_rows (
IN ora_rowset rowset,
OUT size_t
*
num_rows,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns number of columns */

lresult ORADB_CALL ORA_rowset_num_columns (
IN ora_rowset rowset,
OUT size_t
*
num_cols,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* fetches next row of record. TRUE for NOT completed; FALSE for completed */

BOOL ORADB_CALL ORA_rowset_next (
IN ora_rowset rowset
);


/* frees a ora_rowset. a freed rowset handle is an invalid pointer and cannot be used any more */


void
ORADB_CALL ORA_rowset_free (
IN ora_rowset rowset
);

/* accesses column in the current row by name. gets a reference to column */

ora_column ORADB_CALL ORA_rowset_get_column_by_name (
IN ora_rowset rowset,
IN
const char* col_name, /* MUST be a valid name string */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* accesses column in the current row by index: 1-based. gets a reference to column */

ora_column ORADB_CALL ORA_rowset_get_column_by_index (
IN ora_rowset rowset,
IN
ushort col_index, /* COLUMN_INDEX_BASE based */

OUT ora_error_t *error /* NULL for no err msg return */

);


/*
======================================================================
column Functions - oracol.c
======================================================================*/


/* returns column data type */

ORADB_CALL1(
const char*
) ORA_column_get_name (
IN ora_column column
);

/* returns column data type */

ORADBI_DataType ORADB_CALL ORA_column_get_type (
IN ora_column column
);


/* returns column display size */

size_t ORADB_CALL ORA_column_get_dispsize (
IN ora_column column
);


/* returns column precision of numberic data type */


int
ORADB_CALL ORA_column_get_precision (
IN ora_column column
);

/* returns column scale of numberic data type */


int
ORADB_CALL ORA_column_get_scale (
IN ora_column column
);

/* returns whether column is null ok */

BOOL ORADB_CALL ORA_column_is_null_ok (
IN ora_column column
);


/* returns whether column value is null */

BOOL ORADB_CALL ORA_column_is_null (
IN ora_column column
);


/* returns column value as string */

lresult ORADB_CALL ORA_column_as_string (
IN ora_column column,
OUT
char **outval, /* Returns address of pointer to actual data */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* returns column value as double */

lresult ORADB_CALL ORA_column_as_double (
IN ora_column column,
OUT
double *
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns column value as float32 */

lresult ORADB_CALL ORA_column_as_float (
IN ora_column column,
OUT
float *
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns column value as long */

lresult ORADB_CALL ORA_column_as_long (
IN ora_column column,
OUT
long *
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns column value as unsigned long */

lresult ORADB_CALL ORA_column_as_ulong (
IN ora_column column,
OUT
ulong *
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns column value as int64 */

lresult ORADB_CALL ORA_column_as_longlong (
IN ora_column column,
OUT longlong
*
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns column value as uint64 */

lresult ORADB_CALL ORA_column_as_ulonglong (
IN ora_column column,
OUT ulonglong
*
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns column value as datetime */

lresult ORADB_CALL ORA_column_as_datetime (
IN ora_column column,
OUT ora_datetime
*
outval,
OUT ora_error_t *
error
);


/* gets lob size for read. if a column isn't a LOB type or NULL, return 0 */

size_t ORADB_CALL ORA_column_lob_size (
IN ora_column column
);


/* read lob column value - pulling mode */


/*
An example of pulling lob data with ORA_column_read_lob:
#define BUFF_SIZE 512

byte lob_buf[BUFF_SIZE];
lob_siz = ORA_column_lob_size (col);
lob_data = (byte*) malloc (lob_siz);
cb_offs = 0;
cb_read = BUFF_SIZE;

while ((rc=ORA_column_read_lob (col, lob_siz, cb_offs, lob_buf, &cb_read, &err))==ORC_NEED_DATA || rc==ORC_SUCCESS)
{
memcpy (lob_data+cb_offs, lob_buf, cb_read);
cb_offs += cb_read;
if (rc==ORC_SUCCESS)
break;
cb_read = BUFF_SIZE;
}
ASSERT (cb_offs == lob_siz);
*/

lresult ORADB_CALL ORA_column_read_lob (
IN ora_column column,
IN size_t lobsize_to_read,
/* total bytes to read, usually is lob_size */

IN size_t cb_offset,
/* offset bytes from the start of lob data */

INOUT
byte* in_buf, /* when returned, in_buf has actual data */

INOUT size_t
* cb_read, /* input is buf size and output is size of bytes be read */

OUT ora_error_t
*error /* NULL for no err msg return */

);



/*
returns lob column value as bytes once for all. out_buf is allocated by caller for fetch bytes.
* buf_size is size of out_buf
* ORA_column_as_bytes calls ORA_column_read_lob internally.
*/


/*
An example of pulling lob data with ORA_column_as_bytes:
size_t lob_size = ORA_column_lob_size (col);
byte* out_buf = malloc (lob_size);
ORA_column_as_bytes (col, out_buf, &lob_size, NULL);
...
free (out_buf);
*/

lresult ORADB_CALL ORA_column_as_bytes (
IN ora_column column,
INOUT
byte*
out_buf,
INOUT size_t* lob_size, /* size bytes of lob data which must <= size of buffer */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/*
======================================================================
param Functions - oraparam.c
======================================================================*/

ORADBI_DataType ORADB_CALL ORA_param_get_type (
IN ora_param param
);

lresult ORADB_CALL ORA_param_set_long (
IN ora_param param,
IN
long
val,
OUT ora_error_t *error /* NULL for no err msg return */

);

lresult ORADB_CALL ORA_param_set_ulong (
IN ora_param param,
IN
ulong
val,
OUT ora_error_t *error /* NULL for no err msg return */

);

lresult ORADB_CALL ORA_param_set_longlong (
IN ora_param param,
IN longlong val,
OUT ora_error_t
*error /* NULL for no err msg return */

);

lresult ORADB_CALL ORA_param_set_ulonglong (
IN ora_param param,
IN ulonglong val,
OUT ora_error_t
*error /* NULL for no err msg return */

);

lresult ORADB_CALL ORA_param_set_datetime (
IN ora_param param,
IN ora_datetime val,
OUT ora_error_t
*error /* NULL for no err msg return */

);


void
ORADB_CALL ORA_param_set_null (
IN ora_param param
);

lresult ORADB_CALL ORA_param_set_float (
IN ora_param param,
IN float
val,
OUT ora_error_t *error /* NULL for no err msg return */

);

lresult ORADB_CALL ORA_param_set_double (
IN ora_param param,
IN
double
val,
OUT ora_error_t *error /* NULL for no err msg return */

);

lresult ORADB_CALL ORA_param_set_string (
IN ora_param param,
IN
const char *
val,
IN short len, /* -1 for strlen called */

OUT ora_error_t
*error /* NULL for no err msg return */

);

lresult ORADB_CALL ORA_param_set_bytes (
IN ora_param param,
IN
const byte *
in_buf,
IN ushort
size_buf,
OUT ora_error_t *error /* NULL for no err msg return */

);

BOOL ORADB_CALL ORA_param_is_null (
IN ora_param param
);


/* returns column value as string */

lresult ORADB_CALL ORA_param_as_string (
IN ora_param param,
OUT
char **outval, /* Returns address of pointer to actual data */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* returns param value as double */

lresult ORADB_CALL ORA_param_as_double (
IN ora_param param,
OUT
double *
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns param value as float32 */

lresult ORADB_CALL ORA_param_as_float (
IN ora_param param,
OUT
float *
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns param value as long */

lresult ORADB_CALL ORA_param_as_long (
IN ora_param param,
OUT
long *
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns param value as unsigned long */

lresult ORADB_CALL ORA_param_as_ulong (
IN ora_param param,
OUT
ulong *
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns param value as long */

lresult ORADB_CALL ORA_param_as_longlong (
IN ora_param param,
OUT longlong
*
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns param value as unsigned long */

lresult ORADB_CALL ORA_param_as_ulonglong (
IN ora_param param,
OUT ulonglong
*
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns param value as datetime */

lresult ORADB_CALL ORA_param_as_datetime (
IN ora_param param,
OUT ora_datetime
*
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/* returns param value as rowset */

lresult ORADB_CALL ORA_param_as_rowset (
IN ora_param param,
OUT ora_rowset
*
outval,
OUT ora_error_t *error /* NULL for no err msg return */

);


/*
======================================================================
datetime Functions - oradate.c
======================================================================*/


/* creates a datetime opaque pointer which must be free after using */

lresult ORADB_CALL ORA_datetime_create (
OUT ora_datetime
*dt /* must be a valid pointer */

);

lresult ORADB_CALL ORA_datetime_set_all (
IN ora_datetime dt,
IN
short year, /* gregorian year; range is -4712 <= year <= 9999 */

IN ORADBI_DTMonth month,
/* month; range is 1 <= month < 12 */

IN
byte day, /* day; range is 1 <= day <= 31 */

IN
byte hours, /* hours; range is 0 <= hours <=23 */

IN
byte minutes, /* minutes; range is 0 <= minutes <= 59 */

IN
byte seconds, /* seconds; range is 0 <= seconds <= 59 */

OUT ora_error_t
*error /* NULL for no err msg return */

);


void
ORADB_CALL ORA_datetime_get_all (
IN ora_datetime dt,
OUT short *year, /* gregorian year; range is -4712 <= year <= 9999 */

OUT ORADBI_DTMonth
*month, /* month; range is 1 <= month < 12 */

OUT
byte *day, /* day; range is 1 <= day <= 31 */

OUT
byte *hours, /* hours; range is 0 <= hours <=23 */

OUT
byte *minutes, /* minutes; range is 0 <= minutes <= 59 */

OUT
byte *seconds /* seconds; range is 0 <= seconds <= 59 */

);

lresult ORADB_CALL ORA_datetime_set_fld (
IN ora_datetime dt,
IN ORADBI_DTField dt_field,
IN
short
dt_val,
OUT ora_error_t *error /* NULL for no err msg return */

);


short
ORADB_CALL ORA_datetime_get_fld (
IN ora_datetime dt,
IN ORADBI_DTField dt_field
);

lresult ORADB_CALL ORA_string_to_datetime (
IN const char *dt_string, /* datetime string such as: 1975-08-14 12:53:42 */

IN
char *dt_format, /* datetime format such as: yyyy-mm-dd hh:uu:ss */

OUT ora_datetime dt_to,
/* datetime that string translated to */

OUT ora_error_t
*error /* NULL for no err msg return */

);

lresult ORADB_CALL ORA_datetime_to_string (
IN ora_datetime dt_in,
/* datetime to be translated */

IN
char *dt_format, /* datetime format such as: yyyy-mm-dd hh:uu:ss */

OUT
char *string_to, /* datetime string such as: 1975-08-14 12:53:42 */

OUT ora_error_t
*error /* NULL for no err msg return */

);


/* frees a ora_datetime */


void
ORADB_CALL ORA_datetime_free (
IN ora_datetime dt
);


#ifdef __cplusplus
}
#endif



/*====================================================================*/


#endif /* ndef ORADBI_H_INCLUDED .


VS2005(VC8)打开、编译。


举报

相关推荐

0 条评论