使用 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 NULL
列n2
中。 - 第二行尝试将精度为 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。
反馈
您对此页面有任何反馈吗? 我们很乐意听到!