云服务器内容精选

  • SQLSTATE与SQLCODE SQLSTATE是一个由五个字符组成的数组。这五个字符包含数字或大写字母,它表示多种错误或告警情况的代码。SQLSTATE具有一种层次模式:前两个字符表示情况的总体分类,后三个字符表示总体情况的子类。例如:代码00000表示成功状态。 SQLCODE是一个简单的整数形式。值为0表示成功,一个正值表示带附加信息的成功,一个负值表示错误。SQL标准只定义了正值+100,它表示上一个命令返回或者影响了零行,且没有特定的负值。 表1 SQLSTATE与SQLCODE对应关系表 SQLCODE值 SQLSTATE值 含义 0 (ECPG_NO_ERROR) SQLSTATE 00000 表示没有错误。 100 (ECPG_NOT_FOUND) SQLSTATE 02000 一种无害情况,它表示上一个命令检索或者处理了零行,或者已到达游标的末尾。 在循环中处理游标时,可以使用这个代码来检测何时中止该循环,示例如下: while (1) { EXEC SQL FETCH ... ; if (sqlca.sqlcode == ECPG_NOT_FOUND) break; } 实际上WHENEVER NOT FOUND DO BREAK也会在内部这样做,所以一般不会直接使用这种方法。 -12 (ECPG_OUT_OF_MEMORY) SQLSTATE YE001 虚拟内存已被耗尽,数字值被定义为-ENOMEM。 -200 (ECPG_UNSUPPORTED) SQLSTATE YE000 预处理器产生了一些该库无法识别的内容。 -201 (ECPG_TOO_MANY_ARGUMENTS) SQLSTATE 07001 或 07002 表示命令指定的宿主变量数量超过该命令预期。 -202 (ECPG_TOO_FEW_ARGUMENTS) SQLSTATE 07001 或 07002 表示命令指定的宿主变量数量低于该命令的预期。 -203 (ECPG_TOO_MANY_MATCHES) SQLSTATE 21000 表示一个查询已经返回了多行,但是该语句只准备存储一个结果行。 -204 (ECPG_INT_FORMAT) SQLSTATE 42804 宿主变量是类型int而数据库中的数据是一种不同的类型并且含有不能被解释为int的值。该库使用strtol()进行转换。 -205 (ECPG_UINT_FORMAT) SQLSTATE 42804 宿主变量是类型unsigned int而数据库中的数据是一种不同的类型并且含有不能被解释为unsigned int的值。该库使用strtoul()进行转换。 -206 (ECPG_FLOAT_FORMAT) SQLSTATE 42804 宿主变量是类型float而数据库中的数据是另一种类型并且含有不能被解释为float的值。该库使用strtod()进行转换。 -207 (ECPG_NUMERIC_FORMAT) SQLSTATE 42804 宿主变量是类型numeric而数据库中的数据是另一种类型并且含有不能被解释为numeric的值。 -208 (ECPG_INTERVAL_FORMAT) SQLSTATE 42804 宿主变量是类型interval而数据库中的数据是另一种类型并且含有一个不能被解释为interval的值。 -209 (ECPG_DATE_FORMAT) SQLSTATE 42804 宿主变量是类型date而数据库中的数据是另一种类型并且含有不能被解释为date的值。 -210 (ECPG_TIMESTAMP_FORMAT) SQLSTATE 42804 宿主变量是类型timestamp而数据库中的数据是另一种类型并且含有不能被解释为timestamp的值。 -211 (ECPG_CONVERT_BOOL) SQLSTATE 42804 宿主变量是类型boolean而数据库中的数据既不是't'也不是'f'。 -212 (ECPG_EMPTY) SQLSTATE YE000 发送给SQL服务器的语句是空值(通常在一个嵌入式SQL程序中不会发生,因此它可能指向一个内部错误)。 -213 (ECPG_MISSING_INDICATOR) SQLSTATE 22002 返回了一个空值并且没有提供空值指示符。 -214 (ECPG_NO_ARRAY) SQLSTATE 42804 在要求一个数组的地方使用了一个普通变量。 -215 (ECPG_DATA_NOT_ARRAY) SQLSTATE 42804 在一个要求数组值的地方数据库返回了一个普通变量。 -216 (ECPG_ARRAY_INSERT) SQLSTATE 42804 该值不能被插入到数组中。 -220 (ECPG_NO_CONN) SQLSTATE 08003 程序尝试访问一个不存在的连接。 -221 (ECPG_NOT_CONN) SQLSTATE YE000 程序尝试访问一个存在的连接但是它没有打开(这是一个内部错误)。 -230 (ECPG_INVALID_STMT) SQLSTATE 26000 尝试使用的语句还没有被准备好。 -239 (ECPG_INFORMIX_DUPLICATE_KEY) SQLSTATE 23505 重复键错误,违背唯一约束。 -240 (ECPG_UNKNOWN_DESCRIPTOR) SQLSTATE 33000 没有找到指定的描述符,尝试使用的语句还没有被准备好。 -241 (ECPG_INVALID_DESCRIPTOR_INDEX) SQLSTATE 07009 指定的描述符超出范围。 -242 (ECPG_UNKNOWN_DESCRIPTOR_ITEM) SQLSTATE YE000 请求了一个非法的描述符(这是一个内部错误)。 -243 (ECPG_VAR_NOT_NUMERIC) SQLSTATE 07006 在执行一个动态语句期间,数据库返回了一个numeric值而宿主变量不是numeric类型的。 -244 (ECPG_VAR_NOT_CHAR) SQLSTATE 07006 在执行一个动态语句期间,数据库返回了一个非numeric值而宿主变量是numeric类型的。 -284 (ECPG_INFORMIX_SUBSELECT_NOT_ONE) SQLSTATE 21000 子查询的结果不是单一行。 -400 (ECPG_PGSQL) - SQL服务器导致了某个错误。该消息包含来自SQL服务器的错误消息。 -401 (ECPG_TRANS) SQLSTATE 08007 SQL服务器通知我们不能启动、提交或回滚事务。 -402 (ECPG_CONNECT) SQLSTATE 08001 无法建立数据库连接。 -403 (ECPG_DUPLICATE_KEY) SQLSTATE 23505 重复键错误,违背唯一约束。 -404 (ECPG_SUBSELECT_NOT_ONE) SQLSTATE 21000 子查询的结果不是单一行。 -602 (ECPG_WARNING_UNKNOWN_PORTAL) SQLSTATE 34000 指定了一个非法的游标名。 -603 (ECPG_WARNING_IN_TRANSACTION) SQLSTATE 25001 事务正在进行。 -604 (ECPG_WARNING_NO_TRANSACTION) SQLSTATE 25P01 没有活动(正在进行)的事务。 -605 (ECPG_WARNING_PORTAL_EXISTS) SQLSTATE 42P03 指定了一个现有的游标名。 ecpg为嵌入式SQL新增加的SQLSTATE码有:22002、07001、07002、07006、07009、33000、42601、42804、42P03、YE000、YE001。其余SQLSTATE码沿用内核SQLSTATE码。 SQLSCODE为-400表示ecpg检测到内核服务器返回错误,其SQLSTATE为内核相应错误的SQLSTATE。 父主题: 错误处理
  • 设置回调 设置回调操作,当告警或者错误发生时,直接执行具体操作进行处理,设置回调命令如下: EXEC SQL WHENEVER condition action; condition取值范围: SQLERROR:当在SQL语句执行期间发生错误时,调用指定操作。 SQLWARNING:当在SQL语句执行期间发生告警时,调用指定操作。 NOT FOUND:当SQL语句检索或者影响零行,则调用指定操作。 action取值范围: CONTINUE:忽略回调错误条件,继续执行,通常可以用来停止break包含条件,为缺省值。 GOTO label/GO TO label:跳转到指定标签(使用C语言goto语句)。 SQLPRINT:输出消息到标准错误。 STOP:调用exit(1),终止程序。 DO BREAK:执行C语句break,只有在循环中或者switch语句中使用。 示例如下: /* 当出现一个告警时它打印一个消息,发生一个错误时中止程序。 */ EXEC SQL WHENEVER SQLWARNING SQLPRINT; EXEC SQL WHENEVER SQLERROR STOP; 语句EXEC SQL WHENEVER是SQL预处理器的一个指令,而非一个C语言语句。不管C语言程序的流程如何,该语句设置的错误或告警动作都适用于位于处理程序设置点之后的嵌入式SQL语句,除非第一个EXEC SQL WHENEVER语句和导致错误或告警情况发生的SQL语句之间为同一个情况设置了不同的动作。因此下面的两个C语言程序都不会得到预期的效果: /* * 错误 */ int main(int argc, char *argv[]) { ... if (verbose) { EXEC SQL WHENEVER SQLWARNING SQLPRINT; } ... EXEC SQL SELECT ...; ... } /* * 错误 */ int main(int argc, char *argv[]) { ... set_error_handler(); ... EXEC SQL SELECT ...; ... } static void set_error_handler(void) { EXEC SQL WHENEVER SQLERROR STOP; } 当使用DO BREAK时只能用于while/for/switch场景,且用完需要使用CONTINUE语句忽略。 父主题: 错误处理
  • SQLSTATE与SQLCODE SQLSTATE是一个由五个字符组成的数组。这五个字符包含数字或大写字母,它表示多种错误或告警情况的代码。SQLSTATE具有一种层次模式:前两个字符表示情况的总体分类,后三个字符表示总体情况的子类。例如:代码00000表示成功状态。 SQLCODE是一个简单的整数形式。值为0表示成功,一个正值表示带附加信息的成功,一个负值表示错误。SQL标准只定义了正值+100,它表示上一个命令返回或者影响了零行,且没有特定的负值。 表1 SQLSTATE与SQLCODE对应关系表 SQLCODE值 SQLSTATE值 含义 0 (ECPG_NO_ERROR) SQLSTATE 00000 表示没有错误。 100 (ECPG_NOT_FOUND) SQLSTATE 02000 一种无害情况,它表示上一个命令检索或者处理了零行,或者已到达游标的末尾。 在循环中处理游标时,可以使用这个代码来检测何时中止该循环,示例如下: while (1) { EXEC SQL FETCH ... ; if (sqlca.sqlcode == ECPG_NOT_FOUND) break; } 实际上WHENEVER NOT FOUND DO BREAK也会在内部这样做,所以一般不会直接使用这种方法。 -12 (ECPG_OUT_OF_MEMORY) SQLSTATE YE001 虚拟内存已被耗尽,数字值被定义为-ENOMEM。 -200 (ECPG_UNSUPPORTED) SQLSTATE YE000 预处理器产生了一些该库无法识别的内容。 -201 (ECPG_TOO_MANY_ARGUMENTS) SQLSTATE 07001 或 07002 表示命令指定的宿主变量数量超过该命令预期。 -202 (ECPG_TOO_FEW_ARGUMENTS) SQLSTATE 07001 或 07002 表示命令指定的宿主变量数量低于该命令的预期。 -203 (ECPG_TOO_MANY_MATCHES) SQLSTATE 21000 表示一个查询已经返回了多行,但是该语句只准备存储一个结果行。 -204 (ECPG_INT_FORMAT) SQLSTATE 42804 宿主变量是类型int而数据库中的数据是一种不同的类型并且含有不能被解释为int的值。该库使用strtol()进行转换。 -205 (ECPG_UINT_FORMAT) SQLSTATE 42804 宿主变量是类型unsigned int而数据库中的数据是一种不同的类型并且含有不能被解释为unsigned int的值。该库使用strtoul()进行转换。 -206 (ECPG_FLOAT_FORMAT) SQLSTATE 42804 宿主变量是类型float而数据库中的数据是另一种类型并且含有不能被解释为float的值。该库使用strtod()进行转换。 -207 (ECPG_NUMERIC_FORMAT) SQLSTATE 42804 宿主变量是类型numeric而数据库中的数据是另一种类型并且含有不能被解释为numeric的值。 -208 (ECPG_INTERVAL_FORMAT) SQLSTATE 42804 宿主变量是类型interval而数据库中的数据是另一种类型并且含有一个不能被解释为interval的值。 -209 (ECPG_DATE_FORMAT) SQLSTATE 42804 宿主变量是类型date而数据库中的数据是另一种类型并且含有不能被解释为date的值。 -210 (ECPG_TIMESTAMP_FORMAT) SQLSTATE 42804 宿主变量是类型timestamp而数据库中的数据是另一种类型并且含有不能被解释为timestamp的值。 -211 (ECPG_CONVERT_BOOL) SQLSTATE 42804 宿主变量是类型boolean而数据库中的数据既不是't'也不是'f'。 -212 (ECPG_EMPTY) SQLSTATE YE000 发送给SQL服务器的语句是空值(通常在一个嵌入式SQL程序中不会发生,因此它可能指向一个内部错误)。 -213 (ECPG_MISSING_INDICATOR) SQLSTATE 22002 返回了一个空值并且没有提供空值指示符。 -214 (ECPG_NO_ARRAY) SQLSTATE 42804 在要求一个数组的地方使用了一个普通变量。 -215 (ECPG_DATA_NOT_ARRAY) SQLSTATE 42804 在一个要求数组值的地方数据库返回了一个普通变量。 -216 (ECPG_ARRAY_INSERT) SQLSTATE 42804 该值不能被插入到数组中。 -220 (ECPG_NO_CONN) SQLSTATE 08003 程序尝试访问一个不存在的连接。 -221 (ECPG_NOT_CONN) SQLSTATE YE000 程序尝试访问一个存在的连接但是它没有打开(这是一个内部错误)。 -230 (ECPG_INVALID_STMT) SQLSTATE 26000 尝试使用的语句还没有被准备好。 -239 (ECPG_INFORMIX_DUPLICATE_KEY) SQLSTATE 23505 重复键错误,违背唯一约束。 -240 (ECPG_UNKNOWN_DESCRIPTOR) SQLSTATE 33000 没有找到指定的描述符,尝试使用的语句还没有被准备好。 -241 (ECPG_INVALID_DESCRIPTOR_INDEX) SQLSTATE 07009 指定的描述符超出范围。 -242 (ECPG_UNKNOWN_DESCRIPTOR_ITEM) SQLSTATE YE000 请求了一个非法的描述符(这是一个内部错误)。 -243 (ECPG_VAR_NOT_NUMERIC) SQLSTATE 07006 在执行一个动态语句期间,数据库返回了一个numeric值而宿主变量不是numeric类型的。 -244 (ECPG_VAR_NOT_CHAR) SQLSTATE 07006 在执行一个动态语句期间,数据库返回了一个非numeric值而宿主变量是numeric类型的。 -284 (ECPG_INFORMIX_SUBSELECT_NOT_ONE) SQLSTATE 21000 子查询的结果不是单一行。 -400 (ECPG_PGSQL) - SQL服务器导致了某个错误。该消息包含来自SQL服务器的错误消息。 -401 (ECPG_TRANS) SQLSTATE 08007 SQL服务器通知我们不能启动、提交或回滚事务。 -402 (ECPG_CONNECT) SQLSTATE 08001 无法建立数据库连接。 -403 (ECPG_DUPLICATE_KEY) SQLSTATE 23505 重复键错误,违背唯一约束。 -404 (ECPG_SUBSELECT_NOT_ONE) SQLSTATE 21000 子查询的结果不是单一行。 -602 (ECPG_WARNING_UNKNOWN_PORTAL) SQLSTATE 34000 指定了一个非法的游标名。 -603 (ECPG_WARNING_IN_TRANSACTION) SQLSTATE 25001 事务正在进行。 -604 (ECPG_WARNING_NO_TRANSACTION) SQLSTATE 25P01 没有活动(正在进行)的事务。 -605 (ECPG_WARNING_PORTAL_EXISTS) SQLSTATE 42P03 指定了一个现有的游标名。 ecpg为嵌入式SQL新增加的SQLSTATE码有:22002、07001、07002、07006、07009、33000、42601、42804、42P03、YE000、YE001。其余SQLSTATE码沿用内核SQLSTATE码。 SQLSCODE为-400表示ecpg检测到内核服务器返回错误,其SQLSTATE为内核相应错误的SQLSTATE。 父主题: 错误处理
  • 设置回调 设置回调操作,当告警或者错误发生时,直接执行具体操作进行处理,设置回调命令如下: EXEC SQL WHENEVER condition action; condition取值范围: SQLERROR:当在SQL语句执行期间发生错误时,调用指定操作。 SQLWARNING:当在SQL语句执行期间发生告警时,调用指定操作。 NOT FOUND:当SQL语句检索或者影响零行,则调用指定操作。 action取值范围: CONTINUE:忽略回调错误条件,继续执行,通常可以用来停止break包含条件,为缺省值。 GOTO label/GO TO label:跳转到指定标签(使用C语言goto语句)。 SQLPRINT:输出消息到标准错误。 STOP:调用exit(1),终止程序。 DO BREAK:执行C语句break,只有在循环中或者switch语句中使用。 示例如下: /* 当出现一个告警时它打印一个消息,发生一个错误时中止程序。 */ EXEC SQL WHENEVER SQLWARNING SQLPRINT; EXEC SQL WHENEVER SQLERROR STOP; 语句EXEC SQL WHENEVER是SQL预处理器的一个指令,而非一个C语言语句。不管C语言程序的流程如何,该语句设置的错误或告警动作都适用于位于处理程序设置点之后的嵌入式SQL语句,除非第一个EXEC SQL WHENEVER语句和导致错误或告警情况发生的SQL语句之间为同一个情况设置了不同的动作。因此下面的两个C语言程序都不会得到预期的效果: /* * 错误 */ int main(int argc, char *argv[]) { ... if (verbose) { EXEC SQL WHENEVER SQLWARNING SQLPRINT; } ... EXEC SQL SELECT ...; ... } /* * 错误 */ int main(int argc, char *argv[]) { ... set_error_handler(); ... EXEC SQL SELECT ...; ... } static void set_error_handler(void) { EXEC SQL WHENEVER SQLERROR STOP; } 当使用DO BREAK时只能用于while/for/switch场景,且用完需要使用CONTINUE语句忽略。 父主题: 错误处理
  • sqlca 嵌入式SQL接口提供了sqlca(SQL通信区)的全局变量。sqlca包含告警和错误信息。如果在语句执行期间发生多个告警和错误,那么sqlca将只保存最后一个信息。在一个多线程的程序中,每一个线程会自动得到它的sqlca副本。 数据结构如下: struct { char sqlcaid[8]; long sqlabc; long sqlcode; struct { int sqlerrml; char sqlerrmc[SQLERRMC_LEN]; } sqlerrm; char sqlerrp[8]; long sqlerrd[6]; char sqlwarn[8]; char sqlstate[5]; } sqlca; 如果SQL语句没有发生错误,则sqlca.sqlcode为0,sqlca.sqlstate为"00000"。如果发生了告警或者错误,那么sqlca.sqlcode是负数并且sqlca.sqlstate不同于"00000"。SQLSTATE与SQLCODE的具体值请参见SQLSTATE与SQLCODE。 如果SQL语句正确执行,那么sqlca.sqlerrd[1]包含被处理行的OID,并且sqlca.sqlerrd[2]包含被处理或返回的行数。 在发生错误或告警时,sqlca.sqlerrm.sqlerrmc将包含描述该错误的字符串。sqlca.sqlerrm.sqlerrml包含存储在sqlca.sqlerrm.sqlerrmc中错误消息的长度(strlen()的结果)。注意:一些消息可能无法适应定长的sqlerrmc数组,它们将被截断。 在发生告警时,sqlca.sqlwarn[2]被设置为W。 sqlcaid、sqlabc、sqlerrp、sqlwarn以及sqlerrd的剩余元素目前未包含有用的信息。 示例如下: /* 整合WHENEVER和sqlca实现错误处理 */ EXEC SQL WHENEVER SQLERROR SQLCALL print_sqlca(); void print_sqlca() { fprintf(stderr, "==== sqlca ====\n"); fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode); fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml); fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc); fprintf(stderr, "sqlerrd: %ld %ld %ld %ld %ld %ld\n", sqlca.sqlerrd[0],sqlca.sqlerrd[1],sqlca.sqlerrd[2], sqlca.sqlerrd[3],sqlca.sqlerrd[4],sqlca.sqlerrd[5]); fprintf(stderr, "sqlwarn: %d %d %d %d %d %d %d %d\n", sqlca.sqlwarn[0], sqlca.sqlwarn[1], sqlca.sqlwarn[2], sqlca.sqlwarn[3], sqlca.sqlwarn[4], sqlca.sqlwarn[5], sqlca.sqlwarn[6], sqlca.sqlwarn[7]); fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate); fprintf(stderr, "===============\n"); } 输出结果形如(此处是一个拼写表名错误): ==== sqlca ==== sqlcode: -400 sqlerrm.sqlerrml: 49 sqlerrm.sqlerrmc: relation "pg_databasep" does not exist on line 38 sqlerrd: 0 0 0 0 0 0 sqlwarn: 0 0 0 0 0 0 0 0 sqlstate: 42P01 =============== 父主题: 错误处理
  • 设置回调 设置回调操作,当告警或者错误发生时,直接执行具体操作进行处理,设置回调命令如下: EXEC SQL WHENEVER condition action; condition取值范围: SQLERROR:当在SQL语句执行期间发生错误时,调用指定操作。 SQLWARNING:当在SQL语句执行期间发生告警时,调用指定操作。 NOT FOUND:当SQL语句检索或者影响零行,则调用指定操作。 action取值范围: CONTINUE:忽略回调错误条件,继续执行,通常可以用来停止break包含条件,为缺省值。 GOTO label/GO TO label:跳转到指定标签(使用C语言goto语句)。 SQLPRINT:输出消息到标准错误。 STOP:调用exit(1),终止程序。 DO BREAK:执行C语句break,只有在循环中或者switch语句中使用。 SQLCALL name (args) / DO name (args):调用具有指定参数的指定C语言函数(当前特性是实验室特性,使用时请联系华为技术工程师提供技术支持。)。 示例如下: /* 当出现一个告警时它打印一个消息,发生一个错误时中止程序。 */ EXEC SQL WHENEVER SQLWARNING SQLPRINT; EXEC SQL WHENEVER SQLERROR STOP; 语句EXEC SQL WHENEVER是SQL预处理器的一个指令,而非一个C语言语句。不管C语言程序的流程如何,该语句设置的错误或告警动作都适用于位于处理程序设置点之后的嵌入式SQL语句,除非第一个EXEC SQL WHENEVER语句和导致错误或告警情况发生的SQL语句之间为同一个情况设置了不同的动作。因此下面的两个C语言程序都不会得到预期的效果: /* * 错误 */ int main(int argc, char *argv[]) { ... if (verbose) { EXEC SQL WHENEVER SQLWARNING SQLPRINT; } ... EXEC SQL SELECT ...; ... } /* * 错误 */ int main(int argc, char *argv[]) { ... set_error_handler(); ... EXEC SQL SELECT ...; ... } static void set_error_handler(void) { EXEC SQL WHENEVER SQLERROR STOP; } 当使用DO BREAK时只能用于while/for/switch场景,且用完需要使用CONTINUE语句忽略。 父主题: 错误处理
  • 错误码接管 有时只靠错误码不能快速准确的定位问题,为方便用户分析错误,错误处理模块支持注册错误处理的钩子函数,发生错误时,用户可以调用LOS_ErrHandle接口以执行错误处理函数。 Huawei LiteOS 的错误处理模块为用户提供下面几个接口,接口详细信息可以查看API参考。 接口名 描述 参数 备注 LOS_RegErrHandle 注册错误处理钩子函数 func:错误处理钩子函数 - LOS_ErrHandle 调用钩子函数,处理错误 fileName:存放错误日志的文件名 系统内部调用时,入参为"os_unspecific_file" lineNo:发生错误的代码行号 系统内部调用时,若值为0xa1b2c3f8,表示未传递行号 errnoNo:错误码 - paraLen:入参para的长度 系统内部调用时,入参为0 para:错误标签 系统内部调用时,入参为NULL 系统内部会在某些难以定位的错误处,主动调用注册的钩子函数(目前只在互斥锁模块和信号量模块中主动调用了钩子函数)。