可用版本:Dev (3.21) | 最新 (3.20) | 3.19 | 3.18

使用 SQLExceptionLoggerListener 进行日志记录

适用于 ❌ 开源版   ✅ Express 版   ✅ 专业版   ✅ 企业版

除了 LoggerListener(它将 DEBUG 日志记录添加到您的开发环境中)之外,还有一个额外的 SQLExceptionLoggerListener,默认情况下启用它以将额外的异常上下文添加到您的日志中。

许多 RDBMS 在出现问题时都以出了名的吝啬于调试日志信息。例如

-- Depending on the dialect, use DECIMAL or NUMBER, instead
CREATE TABLE t (n1 numeric(3) NOT NULL, n2 numeric(3) NOT NULL);
INSERT INTO t (n1, n2) VALUES (123, null);
INSERT INTO t (n1, n2) VALUES (1234, 123);

很明显,这有两个原因是不对的

  • 第一行尝试将 NULL 插入到 NOT NULLn2 中。
  • 第二行尝试将精度为 4 的数字插入到 NUMERIC(3) 列中。

但是 RDBMS 报告了什么?

-- Db2
SQL Error [23502]: Assignment of a NULL value to a NOT NULL column "TBSPACEID=2, TABLEID=4, COLNO=1" is not allowed..
  SQLCODE=-407, SQLSTATE=23502, DRIVER=4.29.24
SQL Error [22003]: Overflow occurred during numeric data type conversion..
  SQLCODE=-413, SQLSTATE=22003, DRIVER=4.29.24

-- MySQL:
SQL Error [1048] [23000]: Column 'n2' cannot be null
SQL Error [1264] [22001]: Data truncation: Out of range value for column 'n1' at row 1

-- Oracle:
SQL Error [1400] [23000]: ORA-01400: cannot insert NULL into ("TEST"."T"."N2")
SQL Error [1438] [22003]: ORA-01438: value larger than specified precision allowed for this column

-- PostgreSQL:
SQL Error [23502]: ERROR: null value in column "n2" of relation "t" violates not-null constraint
  Detail: Failing row contains (123, null).
SQL Error [22003]: ERROR: numeric field overflow
  Detail: A field with precision 3, scale 0 must round to an absolute value less than 10^3.

-- SQL Server:
SQL Error [515] [23000]: Cannot insert the value NULL into column 'n2', table 'test.dbo.t';
  column does not allow nulls. INSERT fails.
SQL Error [8115] [S0008]: Arithmetic overflow error converting int to data type numeric.

虽然在本例中,MySQL 显示了所有有用的信息,但其他数据库总是至少在一个错误消息中省略列名。 对于多行 INSERT 语句,情况会变得更糟,因为大多数 RDBMS 只报告其中一行的错误,这使得在大容量插入场景中进行调试变得更加困难(例如,当您导入数据时)。

这就是 jOOQ 的 SQLExceptionLoggerListener 可以派上用场的地方。使用这个多行 INSERT 语句

create.insertInto(T)
      .columns(T.N1, T.N2)
      .values(new BigDecimal("123"), null)
      .values(new BigDecimal("1234"), new BigDecimal("123"))
      .execute();

将生成以下日志

NOT NULL column "public"."t"."n2" cannot have an explicit NULL value in row 1 with values: (123, null)
Column "public"."t"."n1" of type numeric(3) cannot accept number of precision 4: 1234 in row 2 with values: (1234, 123)

这些错误不应被视为正式验证,而应仅作为辅助调试信息。某些语句无法产生这些错误,包括基于表达式的 UPDATE 语句,例如。 只有 INSERT 语句UPDATE 语句,其中要设置的值是一个 绑定值才能被记录。

此记录器依赖于类型信息来查询元数据,这意味着使用 代码生成器将是一个先决条件。

如果您希望使用自己的记录器(例如,避免打印出敏感数据),您可以使用您的自定义设置停用 jOOQ 的记录器,并实现您自己的 execute listener logger

反馈

您对此页面有任何反馈吗? 我们很乐意听到!

The jOOQ Logo