proc 编程错误处理机制及null处理

在连接数据库的过程中我们有的时候可能会遇到连接数据库出错、插入数据出错、sql语句写错等等情况,除了这些,我们还会在插入和读取数据时会遇到处理 null 值的问题,以下代码演示了如何对 sql 执行出错进行处理,并执行了一个 null 值插入的操作,中间引入了指示变量的概念,就是专门为了处理 null 值而存在的,注意在插入数据时,指示变量是紧随宿主变量的(:loc:loc_ind)。后面我们将介绍 select 查询出来的 null 值该如何处理。


代码实现

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sqlca.h"

// 拓展 sqlgls 函数作用域
extern sqlgls(char * , size_t *, size_t * );

EXEC SQL BEGIN DECLARE SECTION;
	
	char *serversid = "scott/tiger@orcl";
	
	// 宿主变量,c与sql的一种数据类型的桥梁
	int deptno;
	char dname[20];
	char loc[10];
	
	// loc 的指示变量,唯一的作用就是用来处理null值
	short loc_ind;
	
EXEC SQL END DECLARE SECTION;

void sqlerr()
{
	// 临时变量
	char	stm[120];
	size_t	sqlfc, stmlen=120;
	unsigned int ret = 0;
	
	// 让下一次出现错误时不再跳转到函数中,而是继续下一步(CONTINUE)
	// 防止处理函数中有执行错误再次调用处理函数而导致的递归
	EXEC SQL WHENEVER SQLERROR CONTINUE;
	
	// 获取错误的sql语句
	ret = sqlgls(stm, &stmlen, &sqlfc);
	// c语言使用printf可以用 %.*s 的方式来打印两个衔接的变量
	printf("%.*s\n", stmlen, stm);
	// sqlca.sqlerrm.sqlerrml 为错误编号长度
	// sqlca.sqlerrm.sqlerrmc 为错误内容
	printf("%.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
	
	// 执行回滚并释放连接
	EXEC SQL ROLLBACK WORK RELEASE;
	exit(1);
}


int main(int argc, char* argv[])
{
	int ret = 0;
	
	// 开启错误处理机制,指定错误处理函数为 sqlerr
	EXEC SQL WHENEVER SQLERROR DO sqlerr();
	
	// 连接 oracle 服务器
	EXEC SQL CONNECT :serversid;
	if (sqlca.sqlcode != 0)
	{
		ret = sqlca.sqlcode;
		printf("connect oracle error... code = %d\n", ret);
		return ret;
	}

	// 插入一个已经存在的 deptno ,会导致出错
	deptno = 60;
	strcpy(dname, "dengjia");
	strcpy(loc, "hello");
	// 如果希望将 loc 插入时置为 null,那么就把指示变量 loc_ind 设置为 -1
	loc_ind = -1;
	// 插入数据时,注意指示变量的用法
	EXEC SQL insert into dept(deptno, dname, loc) values(:deptno, :dname, :loc:loc_ind);
	if (sqlca.sqlcode != 0)
	{
		ret = sqlca.sqlcode;
		printf("insert into error... code = %d\n", ret);
		return ret;
	}

	EXEC SQL commit release;
	
	return 0;
}

执行效果

我们插入了一个已经存在的数据,程序执行后提示的错误如下:

2015-07-24_165554

首先是将错误的 sql 语句输出了出来,随后告诉我们是因为 pk_dept 唯一,不能再插入同样的数据。

 

发表评论