占位符:在程序中,一些SQL语句需要在程序运行时才能确定它的语句数据,在设计时可用一个占位符来代替,当程序运行时,在它准备好语句后,必须为每个占位符指定一个变量,即将占位符与程序变量地址结合,执行时,Oracle就从这些变量中读取数据,并将它们与SQL语句一起传递给Oracle服务器执行。OCI结合占位符时,它将占位符与程序变量关联起来,并同时要指出程序变量的数据类型和数据长度。
如:select * from test where name=:p1 and age>:p2
:p1和:p2为占位符
指示器变量:由于在Oracle中,列值可以为NULL,但在C语言中没有 NULL值,为了能使OCI程序表达NULL列值,OCI函数允许程序为所执行语句中的结合变量同时关联一个指示符变量或指示符变量数组,以说明所结合的占位符是否为NULL或所读取的列值是否为NULL,以及所读取的列值是否被截取。
除SQLT_NTY(SQL Named DataType)外,指示符变量或指示符变量数组的数据类型为sb2,其值说明:
作为输入变量时:(如insert ,update语句中)
=-1:OCI程序将NULL赋给Oracle表的列,忽略占位符结合的程序变量值
>=0:应用程序将程序变量值赋给指定列
作为输出变量时:(如select语句中)
=-2:所读取的列数据长度大于程序变量的长度,则被截取。
=-1:所读取的值为NULL,输出变量的值不会被改变。
=0:数据被完整读入到指定的程序变量中
>0:所读取的列数据长度大于程序变量的长度,则被截取,指示符变量值为所读取数据被截取前的实际长度
===================================================
官方文档中的描述
Input
For input host variables, the OCI application can assign the following values to an indicator variable:
Table 2-7 Input Indicator Values
Input Indicator Value | Action Taken by Oracle |
---|---|
-1 | Oracle assigns a |
>=0 | Oracle assigns the value of the input variable to the column. |
Output
On output, Oracle can assign the following values to an indicator variable:
Table 2-8 Output Indicator Values
Output Indicator Value | Meaning |
---|---|
-2 | The length of the item is greater than the length of the output variable; the item has been truncated. Additionally, the original length is longer than the maximum data length that can be returned in the sb2 indicator variable. |
-1 | The selected value is null, and the value of the output variable is unchanged. |
0 | Oracle assigned an intact value to the host variable. |
>0 | The length of the item is greater than the length of the output variable; the item has been truncated. The positive value returned in the indicator variable is the actual length before truncation. |
Indicator Variables for Named Data Types and REFs
Indicator variables for most new (after release 8.0) datatypes function as described above. The only exception is SQLT_NTY (a named datatype). Data of type SQLT_REF uses a standard scalar indicator, just like other variable types. For data of type SQLT_NTY, the indicator variable must be a pointer to an indicator structure.
When database types are translated into C struct representations using the Object Type Translator (OTT), a null indicator structure is generated for each object type. This structure includes an atomic null indicator, plus indicators for each object attribute.
sb2 indicator ;
对于in
indicator = -1;
OCIBindByPos(stmthp,&bindhp,errhp,1, (dvoid *)&aa,4, SQLT_INT, (void*)&indicator, NULL, NULL,0,0,0))
当indicator = -1;无论绑定的是任何值,插入数据库的全为null
对于out
初始
indicator = 0;
OCIDefineByPos(stmthp,&defhp1,errhp,1,&a,sizeof(a),SQLT_INT, (void*)&indicator,0,0,OCI_DEFAULT);
执行完成,当indicator = -1;如数据库中的值为null,则绑定的值不修改,并且不报错,否则替换成数据库中的值,
如果没传入indicator参数,而只是指定一个空指针的话,报错,说提取的列为null,
-2 和 >0时,测试发现差不多,都是当绑定值小于数据库的值时,把indicator 置为数据库中的实际长度,用处不大
综上所述主要就是indicator = -1,可以在数据库中插入null值,或判断数据库中的是否为null
参数indp是指示符缓冲区,也是一个数组,每个元素是一个sb2类型的值。一般作输入用,如果此项动态参数会被输出,则也作输出用。在输入时,元素值为-1时表示NULL值输入,大于或等于0时是普通得值输入。在输出时,和函数OCIDefineByPos()里的指示符缓冲区作用相同,其值将会在提取数据后填入。其值标志着取到的数值的特殊信息。-2表示值的长度过大,且超过sb4类型的最大值,取出的值被截断,是部分值。-1表示值为NULL,因为C/C++没有NULL这个类型,因此这是判断取出的字段值是否是NULL的唯一方法。0表示数据被完整取出。大于0的值,表示取出的值的字节大小超过定义的每个值的字节大小,取出的值被截断,返回的值是被截断前的字节的大小。
参考:
oracle 中oci 关于null 的处理方法
常用的OCI函数
http://baike.baidu.com/subview/159779/159779.htmhttp://soft.zdnet.com.cn/software_zone/2007/0916/509767.shtml
谷歌
数据库接口 取消绑定
数据库接口 取消绑定变量
数据库接口 clear bind
绑定NULL值 mysql
绑定NULL oci
取消绑定 oci
删除绑定 oci
====================================================
- int sqlite3_clear_bindings( sqlite3_stmt *stmt )
如果想清空在一条SQL语句中所有参数所绑定的值,调用sqlite3_clear_bindings函数,该函数调用之后,语句中所有参数都绑定NULL值。该函数总是返回SQLITE_OK。
单列删除绑定函数还未找到。
数据库编程接口---- 绑定参数(Bound Parameters)
====================================================
分类: Linux
(
HOSTNAME VARCHAR2(61 BYTE),
MODULENAME VARCHAR2(20 BYTE),
LOGTIME DATE NOT NULL,
LOGID NUMBER(3),
LOGLEVEL NUMBER(3),
LOGLEVELMASK NUMBER(3),
LOGCONTENT CLOB
)*/
OCIBind *bnd2p = NULL; /* the second bind handle */
OCIBind *bnd3p = NULL; /* the third bind handle */
OCIBind *bnd4p = NULL; /* the fouth bind handle */
OCIBind *bnd5p = NULL;
OCIBind *bnd6p = NULL;
OCIBind *bnd7p = NULL;
char *hostname,
char *modulename,
char *logtime,
int logid,
int loglevel,
int loglevelmask,
char *logcontent)
{
sword errr;
if ( !DBConnected() ) // if DB not open, open it
if(!OpenDbConnect(database)) return false;
dlog_debug("DBAccess::do_bind_insert_log_to_db, OCIStmtPrepare,stmthp=%d,errhp=%d",stmthp,errhp);
char *insertsql = "INSERT INTO LOCATION_LOG(HOSTNAME, MODULENAME, LOGTIME, LOGID, LOGLEVEL, LOGLEVELMASK, LOGCONTENT)\
VALUES (:Vhostname, :Vmodulename, to_date(:Vlogtime,'YYYY-MM-DD HH24:MI:SS'), :Vlogid, :Vloglevel, :Vloglevelmask, :Vlogcontent)";
if ((errr=OCIStmtPrepare(stmthp,errhp, reinterpret_cast<unsigned char *>(insertsql), (ub4)strlen((char *)insertsql),OCI_NTV_SYNTAX,OCI_DEFAULT))!=OCI_SUCCESS)
{
CheckError(errr);
dlog_error("DBAccess::do_bind_insert_log_to_db Error when OCIStmtPrepare INSERT INTO LOCATION_LOG \n");
return false;
}
//char *hostname,1
if ((errr= OCIBindByName(stmthp, &bnd1p, errhp, (text *) ":Vhostname",strlen(":Vhostname"), (ub1 *)hostname , strlen(hostname)+1, SQLT_STR, (void *) 0,(ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT))!=OCI_SUCCESS)
{
CheckError(errr);
dlog_error("DBAccess::do_bind_insert_log_to_db Error when OCIBindByName HOSTNAME \n");
return false;
}
//char *modulename,2
if ((errr= OCIBindByName(stmthp, &bnd2p, errhp, (text *) ":Vmodulename",strlen(":Vmodulename"), (ub1 *)modulename , strlen(modulename)+1, SQLT_STR, (void *) 0,(ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT))!=OCI_SUCCESS)
{
CheckError(errr);
dlog_error("DBAccess::do_bind_insert_log_to_db Error when OCIBindByName MODULENAME \n");
return false;
}
//char *logtime,3
if ((errr= OCIBindByName(stmthp, &bnd3p, errhp, (text *) ":Vlogtime",strlen(":Vlogtime"), (ub1 *)logtime , strlen(logtime)+1, SQLT_STR, (void *) 0,(ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT))!=OCI_SUCCESS)
{
CheckError(errr);
dlog_error("DBAccess::do_bind_insert_log_to_db Error when OCIBindByName LOGTIME \n");
return false;
}
//int logid,4
if ((errr= OCIBindByName(stmthp, &bnd4p, errhp, (text *) ":Vlogid",-1, (ub1 *) &logid, (sword) sizeof(logid), SQLT_INT,(void *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0,OCI_DEFAULT))!=OCI_SUCCESS)
{
CheckError(errr);
dlog_error("DBAccess::do_bind_insert_log_to_db Error when OCIBindByName LOGID \n");
return false;
}
//int loglevel,5
if ((errr= OCIBindByName(stmthp, &bnd5p, errhp, (text *) ":Vloglevel",-1, (ub1 *) &loglevel, (sword) sizeof(loglevel), SQLT_INT,(void *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0,OCI_DEFAULT))!=OCI_SUCCESS)
{
CheckError(errr);
dlog_error("DBAccess::do_bind_insert_log_to_db Error when OCIBindByName LOGLEVEL \n");
return false;
}
//int loglevelmask,6
if ((errr= OCIBindByName(stmthp, &bnd6p, errhp, (text *) ":Vloglevelmask",-1, (ub1 *) &loglevelmask, (sword) sizeof(loglevelmask), SQLT_INT,(void *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0,OCI_DEFAULT))!=OCI_SUCCESS)
{
CheckError(errr);
dlog_error("DBAccess::do_bind_insert_log_to_db Error when OCIBindByName LOGLEVELMASK \n");
return false;
}
if ((errr= OCIBindByName(stmthp, &bnd7p, errhp, (text *) ":Vlogcontent",strlen(":Vlogcontent"), (ub1 *)logcontent , strlen(logcontent)+1, SQLT_STR, (void *) 0,(ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT))!=OCI_SUCCESS)
{
CheckError(errr);
dlog_error("DBAccess::do_bind_insert_log_to_db Error when OCIBindByName LOGCONTENT \n");
return false;
}
dlog_debug("DBAccess::do_bind_insert_log_to_db, OCIStmtExecute,stmthp=%d,errhp=%d \n",stmthp,errhp);
if ((errr=OCIStmtExecute(svchp,stmthp,errhp,1,(ub4)0,NULL,NULL,(ub4) OCI_DEFAULT))!=OCI_SUCCESS) //execute
{
CheckError(errr);
dlog_error("DBAccess::do_bind_insert_log_to_db Error when OCIStmtExecute \n");
return false;
}
dlog_debug("DBAccess::do_bind_insert_log_to_db, OCIStmtExecute,done \n");
if ((errr=OCITransCommit(svchp, errhp, (ub4) 0)) != OCI_SUCCESS) //commit
{
CheckError(errr);
dlog_error("DBAccess::do_bind_insert_log_to_db Error when OCIStmtCommit \n");
return false;
}
return true;
}