GaussDB(DWS)维护宝典:异常数据的快速捕获

举报
你是猴子请来的救兵吗 发表于 2024/04/18 19:55:16 2024/04/18
3.1k+ 0 0
【摘要】 现网作业千千万,当你需要在大量数据中定位某条异常数据时,不要再一条一条去找了;对于如何在千军万马中快速定位出害群之马,异常捕获不失为一个好办法,今天就来带你实践一下。

一句话重点

如何利用异常捕获机制定位问题数据

案例背景

某局点DWS使用copy from执行跨库导数作业,从编码为SQL_ASII编码的数据库,导入到编码为UTF8编码的数据库,作业过程报错,导致业务中断,无数据导入。

ERROR: invalid byte sequence for encoding "UTF8": 0x82

image.png

构造场景

1,建表,灌数据
2,构造个别数据行执行报错场景,这里为编码转换错误的场景

CREATE TABLE t1(name text,val int);
INSERT INTO t1(name, val) VALUES('id1', 0),('id2', 1),(E'\x7f', 2),(E'\x9f', 3);
select convert_from(name::bytea,'utf8') from t1;

image.png

问题数据定位

1,构造存储过程,验证业务逻辑,通过捕获异常区分问题数据

CREATE or replace FUNCTION encoding_check(val text) RETURNS boolean
AS $$
DECLARE
  u_val text;
BEGIN
  u_val = convert_from(val::bytea,'utf8'); --1,自定义检测的业务逻辑
  return true;
EXCEPTION
  WHEN character_not_in_repertoire THEN --2,自定义检测的错误类型
    RETURN false;
END;$$
LANGUAGE plpgsql;

2,通过诊断函数定位异常问题数据,单点分析处理

select *,encoding_check(name) from t1;
select * from t1 where encoding_check(name) = false;

image.png

举一反三

1,构造除数为0错误的场景

select 100/val from t1;

image.png

2,构造检测存储过程进行定位

CREATE or replace FUNCTION div_check(val int) RETURNS boolean
AS $$
DECLARE
  u_val int;
BEGIN
  u_val = 100/val; --1,自定义检测的业务逻辑
  return true;
EXCEPTION
  WHEN division_by_zero THEN --2,自定义检测的错误类型
    RETURN false;
END;$$
LANGUAGE plpgsql;

select *,div_check(div) from t1;
select * from t1 where div_check(div) = false;

image.png

知识点

1,数据库编码一旦创建无法修改,文档链接

CREATE DATABASE database_name
    [ [ WITH ] { [ OWNER [=] user_name ] |
               [ TEMPLATE [=] template ] |
               [ ENCODING [=] encoding ] |
               [ LC_COLLATE [=] lc_collate ] |
               [ LC_CTYPE [=] lc_ctype ] |
               [ DBCOMPATIBILITY [=] compatibilty_type ] |
               [ CONNECTION LIMIT [=] connlimit ]}[...] ];

2,存储过程异常捕获,指定业务逻辑+错误类型,文档链接

[<<label>>]
[DECLARE
    declarations]
BEGIN
    statements
EXCEPTION
    WHEN condition [OR condition ...] THEN
        handler_statements
    [WHEN condition [OR condition ...] THEN
        handler_statements
    ...]
END;

3,当不知道对应报错的错误类型怎么办,使用以下办法捕获对应的错误码,然后在第4步中进行查阅,也可以直接使用OTHERS替代

CREATE or replace FUNCTION encoding_check(val text) RETURNS boolean
AS $$
DECLARE
  u_val text;
  _sqlstate text;
  _message text;
  _context text;
BEGIN
  u_val = convert_from(val::bytea,'utf8'); --1,自定义检测的业务逻辑
  return true;
EXCEPTION WHEN OTHERS THEN
  GET STACKED DIAGNOSTICS
    _sqlstate = returned_sqlstate,--2,错误码打印
    _message = message_text,
    _context = pg_exception_context;
  RAISE NOTICE 'sqlstate: [%], message: [%], context: [%]', _sqlstate, _message, _context;
  RETURN false;
END;$$
LANGUAGE plpgsql;

image.png
image.png

4,常见的错误类型列表,文档链接
部分错误类型举例:

错误码SQLSTATE值 错误码含义
22000 数据异常(DATA_EXCEPTION)
2202E 数组下标错误(ARRAY_SUBSCRIPT_ERROR)
22021 字符不被计算机命令系统识别(CHARACTER_NOT_IN_REPERTOIRE)
22008 日期时间字段溢出(DATETIME_FIELD_OVERFLOW)
22012 被零除(DIVISION_BY_ZERO)
22005 赋值中出错(ERROR_IN_ASSIGNMENT)
2200B 转义字符冲突(ESCAPE_CHARACTER_CONFLICT)
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。