版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1415364
这是杂货铺的第458篇文章
在写Oracle proc程序的时候,经常会判断,sqlca.sqlcode是否是1405,这次应用搬迁,再次领会了他的真实作用。
原始code的片段,首先变量定义,
exec sql begin declare section; char insert_time300; exec sql end declare section;
具体使用,
exec sql at database declare test_cursor cursor for select to_char(insert_time, 'DDMONYYYY') from test; exec sql open test_cursor; for (i = 0; i<1000; i++) { exec sql fetch test_cursor into :insert_timei; if (sqlca.sqlcode != 0) break; } exec sql close test_cursor;
现象就是,在测试环境中,虽然数据库中符合条件的记录,不止一条,但实际能读到的,就只有第一条。
对比了很多次生产和测试数据,才发现些许不同,测试环境中,第一条数据insert_time字段值为空。这就要看ORA-01405的解释,是指fetched column value is NULL,即取出的某个值是NULL。读到第一条,就因为字段insert_time,值空,因此返回了sqlca.sqlcode=1405,导致退出循环。
此处一种处理NULL值的方法,就是使用nvl函数,即NVL(string, replace),如果string为NULL,则NVL函数返回replace的值,否则返回string的值,前提是string和replace必须为同一数据类型。
所以,这条SQL,
select to_char(insert_time, 'DDMONYYYY') from test;
需要改写为,
select nvl(to_char(insert_time, 'DDMONYYYY'), ' ') from test;
即过滤掉insert_time为空的情况,避免出现sqlca.sqlcode=1405,就可以在循环内,正常读所有数据。
因此,ORA错误的描述信息虽然简短,但其实是指明方向的路灯,是需要了解清楚每个ORA的真实含义,才能顺藤摸瓜,找到导致错误的原因。