如何绑定NULL值以及单列删除绑定

本文介绍了Oracle OCI中关于NULL值的处理,包括如何通过indicator变量插入和判断NULL值。同时提到了在输出时,indicator变量如何处理数据库中的NULL值。文章还提及了sqlite3_clear_bindings函数用于清除SQL语句的所有绑定值,但未找到单列删除绑定的函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结合占位符和指示器变量:
占位符:在程序中,一些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 ValueAction Taken by Oracle

-1

Oracle assigns a NULL to the column, ignoring the value of the input variable.

>=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 ValueMeaning

-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.htm


http://soft.zdnet.com.cn/software_zone/2007/0916/509767.shtml

谷歌

数据库接口 取消绑定

数据库接口 取消绑定变量

数据库接口 clear bind

绑定NULL值 mysql

绑定NULL oci

取消绑定 oci

删除绑定 oci

====================================================

  1. int sqlite3_clear_bindings( sqlite3_stmt *stmt )  

  如果想清空在一条SQL语句中所有参数所绑定的值,调用sqlite3_clear_bindings函数,该函数调用之后,语句中所有参数都绑定NULL值。该函数总是返回SQLITE_OK

单列删除绑定函数还未找到。

数据库编程接口---- 绑定参数(Bound Parameters)

====================================================

OCI中绑定变量的实现例子 2011-10-21 17:01:05

分类: Linux

 
/*CREATE TABLE TMP
(
  HOSTNAME      VARCHAR2(61 BYTE),
  MODULENAME    VARCHAR2(20 BYTE),
  LOGTIME       DATE                            NOT NULL,
  LOGID         NUMBER(3),
  LOGLEVEL      NUMBER(3),
  LOGLEVELMASK  NUMBER(3),
  LOGCONTENT    CLOB
)*/
===========================================================
OCIBind *bnd1p = NULL; /* the first bind handle */
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;
 
bool DBAccess::do_bind_insert_log_to_db(
 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;
    }
 
 //char *logcontent,7
    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;
}
 
说明:
1. OCI中DateTime的处理相当麻烦, 可以使用char来替换DateTime使用. 在构造SQL的时候, 使用to_date进行转换. to_date(:Vlogtime,'YYYY-MM-DD HH24:MI:SS')
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值