数据库 proc编程四
错误处理机制 当在Pro*C/C++应用程序中运行SQL语句中,Oracle会将最近执行的SQL语句的状态信息存储到状态变量SQLCODE、SQLSTATE或者SQLCA结构中。 当SQL语句执行成功时,一般情况下不需要进行任何其他处理;当SQL语句执行失败时,应用程序应该能够检测到失败信息,并进行适当的处理, 以加强应用程序的健壮性。在编写Pro*C/C++应用程序时,通过使用WHENEVER语句可以检测并处理SQL错误,语法如下: EXEC SQL WHENEVER <condition> <action> 其中condition用于指定要检测的条件,action用户指定满足特定条件时要执行的操作。 1.条件 --SQLWARNING:用于检测oracle警告。当检测到该条件时,sqlca.sqlwarn[0]会被设置为W。注意:当使用该条件时,必须定义SQLCA结构。 --SQLERROR:用于检测oracle错误。当检测到该条件时,sqlca.sqlcode或者SQLCODE会被设置为负值。 --NOT FOUND:用户检测SELECT或者FETCH操作未检索到行的情况。当MODE=ORACLE时,如果不能找到满足条件的行, 则sqlca.sqlcode会被设置为+1403;当MODE=ANSI时,SQLCODE会被设置为+100,默认选项是MODE=ORACLE,可以在proc命令行参数中修改配置。 2.操作 --CONTINUE:继续执行下一条语句 --DO:执行错误处理函数 --GOTO label_name:转移到标号处执行。 --STOP:回退事务,停止运行。
错误处理方法一 if(sqlca.sqlcode!=0) { ret=sqlca.sqlcode; printf("delete err :%d",ret); return; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include "sqlca.h" //EXEC SQL INCLUDE sqlca;可以用来代替#include "sqlca.h" EXEC SQL BEGIN DECLARE SECTION; char *serverid="scott/12356@orcl"; int deptid; char edname[32]; char edloc[32]; EXEC SQL END DECLARE SECTION; void main() { int ret=0; EXEC SQL connect:serverid ; if(sqlca.sqlcode!=0) { ret=sqlca.sqlcode; printf("connect err :%d",ret); system("pause"); }else{ printf("connect ok !\r\n"); system("pause"); } }
错误处理方法二
EXEC SQL WHENEVER SQLERROR DO sqlerr();
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include "sqlca.h" EXEC SQL BEGIN DECLARE SECTION; char *serverid="scott/123456@orcl"; int deptid; char edname[32]; char edloc[32]; EXEC SQL END DECLARE SECTION; //错误处理函数 void sqlerr() { int ret=0; ret=sqlca.sqlcode; printf("check err :%d",ret); } void main() { int ret=0; //注意:安装错误处理函数,必须在执行SQL嵌入之前安装 EXEC SQL WHENEVER SQLERROR DO sqlerr(); EXEC SQL connect:serverid ; printf("connect ok!\r\n"); system("pause"); }
错误处理方法三
EXEC SQL WHENEVER SQLERROR CONTINUE;
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include "sqlca.h" EXEC SQL BEGIN DECLARE SECTION; char *serverid="scott/12345@orcl"; int deptid; char edname[32]; char edloc[32]; EXEC SQL END DECLARE SECTION; //错误处理升级函数 void sqlerr() { //CONTINUE的目的是假设EXEC SQL ROLLBACK WORK RELEASE执行失败,会再次执行sqlerr()函数,造成死循环 //所以设置CONTINUE EXEC SQL WHENEVER SQLERROR CONTINUE;//下一步 //%.*s解释:sqlca.sqlerrm.sqlerrml是错误信息的长度,sqlca.sqlerrm.sqlerrmc是错误信息,长度为70个字节 //%70s 表示按70个字符显示字符串,但是没有%d %s这种语法,所以c语言是这个%.*s语法,".*"相当于一个占位符 printf("err reason:%.*s\r\n",sqlca.sqlerrm.sqlerrml,sqlca.sqlerrm.sqlerrmc); EXEC SQL ROLLBACK WORK RELEASE;//回滚事务,关闭SQL连接 } void main() { //注意:安装错误处理函数,必须在执行SQL嵌入之前安装 EXEC SQL WHENEVER SQLERROR DO sqlerr(); EXEC SQL connect:serverid ; printf("connect ok!\r\n"); system("pause"); }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include "sqlca.h" EXEC SQL BEGIN DECLARE SECTION; char *serverid="scott/1234456@orcl"; int deptid; char edname[32]; char edloc[32]; EXEC SQL END DECLARE SECTION; //错误处理升级函数 void sqlerr() { int ret=0; char stn[120]; //sqlfc:SQL语句的实际长度 size_t sqlfc,stmlen=120; EXEC SQL WHENEVER SQLERROR CONTINUE; ret=sqlgls(stn,&stmlen,&sqlfc); if(ret!=0) { printf("sqlgls() failed ! err code: %d\r\n",ret); return ; } printf("出错的SQL语句是:%.*s\r\n",stmlen,stn); printf("err reason:%.*s\r\n",sqlca.sqlerrm.sqlerrml,sqlca.sqlerrm.sqlerrmc); EXEC SQL ROLLBACK WORK RELEASE; } void main() { EXEC SQL WHENEVER SQLERROR DO sqlerr(); EXEC SQL connect:serverid ; printf("connect ok!\r\n"); system("pause"); }