I have a table called result that has no primary key (cannot change that). I want to update all the records that meet a certain condition using Jooq. The following code doesn't work as I expected. It inserts new records instead of updating existing ones, which I don't understand.
我有一个名为Result的表,它没有主键(无法更改)。我想使用Jooq更新满足特定条件的所有记录。下面的代码没有像我预期的那样工作。它插入新的记录,而不是更新现有的记录,这我不明白。
public Mono<Result> update(Result result, String name) {
return Mono.from(ctx.update(RESULT)
.set(RESULT.STATUS, result.getStatus())
.where(RESULT.NAME.eq(name))
.returning()
)
.map(r -> r.into(Result.class));
更多回答
I didn't simplify my example, this is actually the code that I have. It is actually just inserting new records instead of updating the existing ones. At first I thought it had to do with the table not having a primary key, but then I saw this post and I realised that my example should be working stackoverflow.com/questions/73150064/…
我没有简化我的例子,这实际上是我拥有的代码。它实际上只是插入新记录,而不是更新现有记录。起初,我以为这与表没有主键有关,但后来我看到这篇文章,意识到我的示例应该是Stackoverflow.com/Questions/73150064/…
@LukasEder well I just discovered why. I reworked the code and tried with a table with a primary key(I added just an autoincrement id as primary key) and another table without a primary key. If the table has a primary key, it works. If not, it inserts as many records as it is supposed to update. It's not me inventing stuff. I must say that the rest of the code is pretty huge, so I will try to do as you say and make a small example when I have time. Still, if you all say that there is nothing wrong with that code and should be working, then this has to be a bug.
@LukasEder嗯,我刚刚发现了原因。我修改了代码,并尝试使用一个具有主键的表(我只添加了一个自动增量id作为主键)和另一个没有主键的表。如果该表有主键,则它可以工作。如果不是,它会插入尽可能多的应该更新的记录。这不是我发明的东西。我必须说,代码的其余部分相当大,所以我会试着按照您说的做,并在我有时间的时候做一个小例子。尽管如此,如果你们都说代码没有任何错误,应该可以工作,那么这一定是一个错误。
@LukasEder forgot to mention, about what was being inserted, well, the first record that was supposed to be updated is reinserted as many times as the .where(RESULT.NAME.eq(name)) is true. This made my table which contained around 10 records to finish with hundred of records after just a couple of calls of the update function.
@LukasEder忘记提到插入了什么,那么,应该更新的第一条记录被重新插入的次数与.where(RESULT.NAME.eq(Name))为真的次数一样多。这使得我的表(包含大约10条记录)在几次调用UPDATE函数之后就有了数百条记录。
My apologies. I had overlooked the returning()
method, and that this was a MariaDB question, earlier :( MariaDB doesn't have native support for UPDATE .. RETURNING
, so jOOQ runs an INSERT .. ON DUPLICATE KEY UPDATE
statement on the data that is matched by the WHERE
clause, the assumption being that there's indeed a primary key.
我很抱歉。我之前忽略了返回()方法,这是一个MariaDB问题:(MariaDB没有对更新的本机支持。返回,所以jOOQ运行插入..ON DUPLICATE KEY UPDATE语句对与WHERE子句匹配的数据执行UPDATE语句,假设确实存在主键。
@LukasEder I understand, thanks. How should I approach this then if I have no primary key?
@LukasEder我理解,谢谢。如果我没有主键,我应该如何处理呢?
优秀答案推荐
jOOQ 3.18 introduced an emulation for UPDATE .. RETURNING
in MariaDB 10.5, which doesn't support this syntax natively:
JOOQ 3.18引入了更新的模拟。在MariaDB 10.5中返回,该版本本身不支持此语法:
In short, this kind of statement:
简而言之,这种说法:
UPDATE t
SET a = b
WHERE p
ORDER BY o
LIMIT l
RETURNING x;
Can be emulated as follows:
可以按如下方式进行模拟:
INSERT INTO t
SELECT * FROM t WHERE p ORDER BY o LIMIT l
ON DUPLICATE KEY UPDATE SET a = b
RETURNING x;
But obviously, this assumes the presence of a primary key (or unique key) which can be matched by the ON DUPLICATE KEY
clause. In other words, jOOQ can emulate UPDATE .. RETURNING
only if you have some unique constraint, not otherwise.
但显然,这假设存在一个主键(或唯一键),该主键可以与ON DUPLICATE KEY子句匹配。换句话说,jOOQ可以模拟更新。仅当您有一些唯一约束时才返回,否则不返回。
It is debatable whether this requirement should be indicated to the user in form of an error:
这一要求是否应该以错误的形式指示给用户是值得商榷的:
更多回答
我是一名优秀的程序员,十分优秀!