mysql 唯一约束 错误码,mysql – 数据库 – 处理唯一约束违规

我有一个用户创建屏幕,其中包含各种用户详细信息以及名字和手机号码.我有一个相应的USER表,其中First Name和Mobile号形成一个复合唯一键.此表还定义了其他完整性约束.

在“创建用户”屏幕上输入违反此约束的用户数据时,需要向用户显示“用户友好”错误消息.

当发生这种违规时,我从MySQL数据库获得的异常是:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1-1' for key `uk_FIRST_NAME__MOBILE_idx`

有两个选项可以显示有意义的消息(例如:“错误:给定手机号码已存在用户名,请更改其中任何一个”).

选项1:在此异常的catch块中,解析MySQL异常的消息并查找“uk_FIRST_NAME__MOBILE_idx”.如果存在,请显示如上所述的用户友好消息.

选项2:编写DAO级API,将名字和手机号码作为唯一的两个参数,触发数据库查询以查看是否存在与此名字/移动组合匹配的现有记录.如果为true,则向用户显示错误消息;否则,运行插入查询以将记录用户插入USER表.

我不喜欢选项1,因为它需要我“解析”异常消息,这不是一个干净的解决方案.我也不喜欢选项2,因为它需要我在数据库上运行“两个查询”,这比选项1(一个查询解决方案)效率低.

问题:还有其他选择比这两个更好吗?如果不是,哪一个是上述两个中的正确方法?

解决方法:

我认为“选项2”(在尝试插入之前手动检查约束)是可怕的,不仅仅是因为种族危险(可以通过locking reads避免),而且(因为你注意到)因为数据库上的额外负载:毕竟,手动检查约束完全否定了在数据库中使用约束的目的和好处.

我同意解析错误消息字符串感觉“脏”,但字符串是well defined.甚至可以引用底层的errmsg.txt或源头文件.

一旦从错误消息中提取了密钥名称,就可以使用KEY_COLUMN_USAGE信息模式来识别违规列:

public static final int ER_DUP_ENTRY = 1062;

public static final int ER_DUP_ENTRY_WITH_KEY_NAME = 1586;

public static final String REGEX_DUP_ENTRY_WITH_KEY_NAME =

"Duplicate entry '(.*)' for key '(.*)'";

// ...

try {

// ...

} catch (MySQLIntegrityConstraintViolationException e) {

switch (e.getErrorCode()) {

case ER_DUP_ENTRY:

case ER_DUP_ENTRY_WITH_KEY_NAME:

Pattern p = Pattern.compile(REGEX_DUP_ENTRY_WITH_KEY_NAME);

Matcher m = p.matcher(e.getMessage());

SQLQuery query = session.createSQLQuery(

" SELECT COLUMN_NAME" +

" FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE" +

" WHERE CONSTRAINT_SCHEMA = :schema" +

" AND CONSTRAINT_NAME = :key"

);

query.setString("schema", "my_schema");

query.setString("key" , m.group(2));

showDuplicateError(query.list());

break;

}

}

标签:mysql,database

来源: https://codeday.me/bug/20190529/1175610.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值