如何使用关系数据库管理系统 (RDBMS) 的数据操作语言 (DML) 创建任意错误

huangapple go评论76阅读模式
英文:

How to create arbitrary error with RDBMS DML

问题

背景

  • 我正在编写一个与关系数据库管理系统 (RDBMS) 一起工作的 Java 应用程序。
  • 该应用程序使用 Oracle 和 PostgreSQL 作为数据存储。

问题

目前,我正在为某些 SQLException 测试错误处理例程。例如,我希望将 ORA-00001(唯一约束冲突)或 ORA-00054(无法获取排他锁)视为可恢复的错误。另一方面,我希望将 ORA-00060(死锁)视为不可恢复的错误。

现在,我正在尝试为这个错误处理例程编写 JUnit 测试用例。为了使测试用例尽可能具有可移植性,我正在寻找一种方法来生成任意错误(如 ORA-00001、ORA-00054 等),只需使用类似 SELECT RAISE_ERROR(-54) FROM DUAL 的简单 DML。此外,我希望在测试用例中避免模拟 SQLException 本身,因为 SQLException 的内容可能会在不同版本的 RDBMS 之间发生更改。

问题

是否有任何方法可以在关系数据库管理系统(尤其是 Oracle 和 PostgreSQL)中使用 DML 创建任意 SQL 错误?或者,是否有像 DBUnit 这样的测试框架,具有创建任意 SQLException 的功能?如果能在没有特定表和记录的情况下发生错误,那就更理想了。

英文:

Background

  • I am writing a Java application work with RDBMS.
  • The application uses Oracle and PostgreSQL as datastore.

Problem

Now I am testing an error-handling routine for some SQLException. For example, I want to treat ORA-00001 (Unique constraint violation) or ORA-00054 (Failed to acquire an exclusive lock) as a recoverable error. On the other hand, I want to treat ORA-00060 (Deadlock) as a non-recoverable error.

Now I am trying to write JUnit test cases for this error-handling routine. To make the test cases as portable as possible, I am looking for a way to generate arbitrary errors (ORA-00001, ORA-00054, ...) with a simple DML like SELECT RAISE_ERROR(-54) FROM DUAL. Also, I want to avoid mocking SQLException itself in test cases, because the content of SQLException could be changed between the version of RDBMS.

Question

Is there any way to create arbitrary SQL errors with a DML in RDBMS (especially Oracle and PostgreSQL)? Or, is there any testing framework like DBUnit that has function to create arbitrary SQLException? It is desirable if it can occur an error without specific tables and records.

答案1

得分: 1

在SQL中,没有一种便捷的方法来人为地引发特定的错误,您需要为每个数据库编写相应的代码。

但是我想给您一些建议:

  • 使用标准化的SQLSTATE,而不是像Oracle的ORA-xxxxx数字这样的特定于系统的错误代码。这应该是可移植的。

    所有关系数据库管理系统都应该有一种获取错误消息的SQLSTATE的方法。

  • 我不知道您所说的“可恢复错误”是什么意思,但死锁显然不是持久性错误 - 如果您重复事务,它很可能会成功。

    另一方面,约束违规是一种持久性错误。无论您多少次重试,都将始终收到相同的错误。唯一的“恢复”方式将是运行不同的语句或修改数据库以避免冲突。

英文:

There is no portable way to artificially cause a given error in SQL, you'll have to write code for each database.

But I want to give you some general advice:

  • Use the standardized SQLSTATE rather than a system specific error code like Oracle's ORA-xxxxx numbers. That should be portable.

    All RDBMS should have a way to retrieve the SQLSTATE for an error message.

  • I don't know what you mean with a "recoverable error", but a deadlock is clearly not a persistent error - is you repeat the transaction, it will probably succeed.

    On the other hand, a constraint violation is a persistent error. Retry as often as you want, you will always get the same error. The only way to "recover" would be to either run a different statement or modify the database to avoid the conflict.

huangapple
  • 本文由 发表于 2020年8月19日 00:40:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63473041.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定