嵌入式开发中对db2 null字段的处理

来源:互联网 发布:雾月政变 知乎 编辑:程序博客网 时间:2024/06/05 19:01

1. 个人经历
在上一家公司做数据转移项目(实时异库数据同步)时,碰到一个bug,为此焦心加班整个周末,特此记录
在从源数据库导出数据到内存时,select某一字段into宿主变量中,但是当导出某一张表时,程序都会报错:SQL0305 SQLCODE -305   SQLSTATE 22002     
Explanation: Indicator variable required. 而且取出的数据,插入到目标数据库之后出现乱码。
后来查询数据库结构发现这张表中有一个字段没有not null default '',因此当取到这个字段时,宿主变量的值不会被改变,是随机的(不记得初始化为0是否有用)。
于是在网上查到了指示符变量的相关资料:
在实际中,数据库中有些对象的值未知,我们用空值表示。当我们选择数据时,如果是空值,宿主变量的内容将不会被改变,是随机的。
DB2数据库管理器提供了一个机制去通知用户返回数据是空值,这个机制就是指示符变量。
指示符(indicator)变量是一种特殊的宿主变量类型,它用来表示列的空值或非空值。
当这些宿主变量作为输入进入数据库中时,应当在执行SQL语句之前由应用程序对它们设置值。
当这些宿主变量作为数据库的输出使用时,这些指示符由应用程序定义,但由DB2更新和将它们返回。然后,在结果被返回时,应用程序应当检查这些指示符变量的值。


而我就需要使用 空值指示符(null indicator)
定义如下:
EXEC SQL BEGIN DECLARE SECTION;
short     null_indicator;(数据类型与SQL数据类型SMALLINT对应,在C语言中为SHORT类型)
EXEC SQL END DECLARE SECTION;


使用方法如下:
select 
field_name into :field:null_indicator
from table_name 
where conditions;


当db2在fetch发现该字段时空时,null_indicator的值会为负(通常为-1),否则null_indicator的值为非负(通常为0)
后续在使用数据进行插入时,就可以根据这个null_indicator来判断,是插入宿主变量的值,还是插入空值。


2. 拓展了解指示符变量用法
2.1 指示符空值列空值
指示符逻辑例子1——作为输出:
 
  EXEC  SQL
       SELECT   PHONENO, SEX
       INTO  :phoneno:phoneind, :sex
       FROM  TEMPL
       WHERE  EMPNO = :eno;
  
       if (phoneind < 0)
               null_phone();
       else
               good_phone();
在这个例子里,DB2维护指示符变量,应用程序在SQL语句执行后,询问指示符变量的值,调用相应的处理函数




指示符逻辑例子2——作为输入:
 
  if (some condition)
     phoneind = -1;
  else
     phoneind = 0;
 
  EXEC  SQL
       UPDATE TEMPL
       SET NEWPHONE = :newphoneno :phoneind
       WHERE EMPNO = :eno;
在这个例子里,应用程序维护指示符变量。应用程序根据条件设置指示符变量phoneind的值。
如果DB2发现指示符的值为负数,那么给定行集合中的列被设置为空值,宿主变量的值被忽略;如果指示符的值为正数或者为零,宿主变量中的值被使用。


在嵌入SQL语句中可以使用关键字NULL。下面是不使用指示符变量的一个UPDATE语句例子:
if ( some condition)
     EXEC SQL
     UPDATE  TEMPL
     SET  PHONENO = NULL
     WHERE  EMPNO = :eno ;
else
     EXEC SQL
     UPDATE   TEMPL
     SEST PHONENO = :newphone
     WHERE EMPNO = :eno ;
但是,这种写法有缺点:如果UPDATE语句需要修改,就要修改两处代码。


两个例子总结:
DB2在执行SELECT和FETCH语句的过程中设置指示符变量的值,应用程序应该在执行SELECT和FETCH语句后检查它们的值。
应用程序在执行UPDATE和INSERT语句之前设置指示符变量的值来指示DB2是否在数据库中放置一个空值(NULL)。




2.2 指示符变量在数值转换方面的应用
当宿主变量的数据类型与相应列的数据类型不兼容或者不能转换时,DB2也通过指示符变量通知应用程序。
数值转换由数据库管理器处理,能转换时自动完成,对程序透明;
如果列中的值不能存储到宿主变量中时(例如,列的数据类型为DECIMAL(15),值的长度为12个数字,不能存储到INTEGER类型的宿主变量中),指示符变量的值为-2。


2.3 指示符变量在截取方面的应用
在SQL语句执行后,如果指示符变量的值为正数,说明发生了数据截取:
—如果是时间数据类型的秒部分被截取,那么指示符变量中的值为截取的秒数
—对于其他数据类型,指示符变量表示数据库中列的数据原始长度,通常为字节数(数据库尽可能返回更多的数据)。


0 0