我已经声明了下表,以供审计触发器使用:

CREATE TABLE audit_transaction_ids (id IDENTITY PRIMARY KEY, uuid VARCHAR UNIQUE NOT NULL, `time` TIMESTAMP NOT NULL);
  1. 触发器将在同一交易中多次调用。

  2. 首次调用扳机时,我希望它使用当前的TransAction_ID()和时间插入新行。

  3. 随后调用触发器,我希望它返回现有的“ ID”(我调用statement.getGeneratedKeys()到该端),而不会更改“ uuid”或“ time”。

当前的模式似乎有两个问题。

  1. 当我调用时 MERGE INTO audit_transaction_ids (uuid, time) KEY(id) VALUES(TRANSACTION_ID(), NOW()) 我得到: org.h2.jdbc.JdbcSQLException: Column "ID" contains null values; SQL statement: MERGE INTO audit_transaction_ids (uuid, time) KEY(id) VALUES (TRANSACTION_ID(), NOW()) [90081-155]

  2. 我怀疑在现有行上调用合并会改变“时间”。

如何解决这两个问题?

有帮助吗?

解决方案

MERGE 类似于 java.util.Map.put(key, value): :如果不存在,它将插入行,并在行更新。话虽如此,您仍然可以合并到包含 AUTO_INCREMENT 只要您将另一列用作键,列就可以。

给出 customer[id identity, email varchar(30), count int] 你可以 merge into customer(id, email, count) key(email) values((select max(id) from customer c2 where c2.email='test@acme.com'), 'test@acme.com', 10). 。含义,如果存在记录,请重复使用ID,否则使用null。

也可以看看 https://stackoverflow.com/a/18819879/14731 对于一种可移植的方法,可以根据一行是否已经存在,以插入或更新。


1.合并到AUDIT_TRANSACTION_IDS(UUID,time)键(id)值(transaction_id(),now())

如果您只想插入新行,请使用:INSERT INTO audit_transaction_ids (uuid, time) VALUES(TRANSACTION_ID(), NOW())

MERGE 不设置列的值 ID 如果没有意义 ID 被用作钥匙,因为这种方式(理论上)永远无法更新现有行。您可以做的是使用另一个密钥列(在上面的情况下,没有可以使用的列)。请参阅文档 MERGE 有关详细信息。

2.在现有行上调用合并将改变“时间”

我不确定您是否谈论列“时间”的价值已更改的事实。如果您使用的话,这是预期的行为 MERGE ... VALUES(.., NOW()), ,因为 MERGE 语句应该更新该列。

或者,您的意思是,较旧版本的H2返回了同一交易中的不同值(与大多数其他数据库不同,在同一事务中返回相同的值)。事实是,但是H2版本1.3.155(2011-05-27),后来,这种不兼容是固定的。另请参阅 更改日志: :“ current_timestamp()等现在返回交易中相同的值。”在您的情况下,这似乎不是问题,因为您似乎确实使用版本1.3.155(错误消息[90081-155]包括构建 /版本号)。

其他提示

简短答案:

合并到AUDIT_TRANSACTION_IDS(UUID,time)键(uuid,time)值(transaction_id(),now());

少量性能提示:确保索引索引

长答案:

MERGE 基本上是一个 UPDATE 哪个 INSERT当没有发现的记录更新时。

维基百科提供了更简洁的标准化语法合并 但是您必须提供自己的更新和插入。 (是否在H2中支持这不是我的回答)

那么如何使用 MERGE 在H2中?您定义要查找的钥匙,如果发现它更新了行(带有您提供的列名,可以定义 DEFAULT 在这里,要将您的列重置为默认值),否则插入行。

现在是什么 Null? Null 意味着未知,未找到,未定义,任何不是您想要的东西。

这就是为什么 Null 作为要查找的关键。因为这意味着找不到记录。

合并到table1(id,col1,col2)键(id)值(null,1,2)

Null 有一个价值。这是一个价值。

现在让我们看看您的SQL。

合并到table1(id,col1,col2)键(id)值(默认为1,2)

那意味着什么?对我来说,它说我有这个[默认值1,2], 找到我 DEFAULT 在列中 id, ,然后更新 col1 到1, col2 至2,如果发现。否则,将默认值插入到 id, ,1至 col1, ,2至 col2.

看看我在那里强调什么?那有什么意思?什么是 DEFAULT?你如何比较 DEFAULTid?

DEFAULT 只是一个关键字。

你可以做类似的事情

合并到table1(id,col1,timestampcol)键(id)值(null,1,默认值)

但是不要将默认值放在密钥列中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top