在这个关于实体框架和MERGE的SO答案中,如何编写代码的示例如下:
public void SaveOrUpdate(MyEntity entity)
{
if (entity.Id == 0)
{
context.MyEntities.AddObject(entity);
}
else
{
context.MyEntities.Attach(entity);
context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
}
}
Run Code Online (Sandbox Code Playgroud)
这假设您已经知道要嵌入的实体是否存在; 在这种情况下,你检查entity.Id.但是,如果您不知道该项目是否存在,该怎么办?例如,在我的情况下,我将来自供应商的记录导入我的数据库,并且可能已经或可能没有导入给定记录.我想更新记录,如果它存在,否则添加它.但两种情况下都已设置供应商的ID.
除非我只是询问数据库是否已经存在记录,否则我无法看到任何方法这样做,这违背了MERGE的全部目的.
我正在尝试使用jOOQ库在PostgreSQL中执行UPSERT.
为此,我目前正在尝试在jOOQ中实现以下SQL语句:https://stackoverflow.com/a/6527838
到目前为止我的代码看起来像这样:
public class UpsertExecutor {
private static final Logger logger = LoggerFactory.getLogger(UpsertExecutor.class);
private final JOOQContextProvider jooqProvider;
@Inject
public UpsertExecutor(JOOQContextProvider jooqProvider) {
Preconditions.checkNotNull(jooqProvider);
this.jooqProvider = jooqProvider;
}
@Transactional
public <T extends Record> void executeUpsert(Table<T> table, Condition condition, Map<? extends Field<?>, ?> recordValues) {
/*
* All of this is for trying to do an UPSERT on PostgreSQL. See:
* https://stackoverflow.com/a/6527838
*/
SelectConditionStep<Record1<Integer>> notExistsSelect = jooqProvider.getDSLContext().selectOne().from(table).where(condition);
SelectConditionStep<Record> insertIntoSelect = jooqProvider.getDSLContext().select(recordValues).whereNotExists(notExistsSelect);
try {
int[] result = jooqProvider.getDSLContext().batch(
jooqProvider.getDSLContext().update(table).set(recordValues).where(condition),
jooqProvider.getDSLContext().insertInto(table).select(insertIntoSelect) …Run Code Online (Sandbox Code Playgroud) 我有类似的文档,具有唯一索引bars.name:
{ name: 'foo', bars: [ { name: 'qux', somefield: 1 } ] }
.我想更新子文档在哪里{ name: 'foo', 'bars.name': 'qux' }和$set: { 'bars.$.somefield': 2 },或者用{ name: 'qux', somefield: 2 }under 创建一个新的子文档{ name: 'foo' }.
是否可以使用带有upsert的单个查询来执行此操作,还是必须发出两个单独的查询?
相关:嵌入式文档中的"upsert"(建议更改模式以将子文档标识符作为键,但这是两年前的事情,我想知道现在是否有更好的解决方案.)
如何在pymongo中进行批量upsert?我想更新一堆条目,一次做一个是非常慢的.
几乎完全相同的问题的答案在这里:MongoDB中的批量更新/ upsert?
接受的答案实际上没有回答这个问题.它只是提供了一个指向mongo CLI的链接,用于执行导入/导出.
我也愿意向某人解释为什么做大量upsert是不可能/没有最佳做法,但请解释这类问题的首选解决方案是什么.
我正在编写一个数据挖掘程序,它批量插入用户数据.
当前的SQL只是一个普通的批量插入:
insert into USERS(
id, username, profile_picture)
select unnest(array['12345']),
unnest(array['Peter']),
unnest(array['someURL']),
on conflict (id) do nothing;
Run Code Online (Sandbox Code Playgroud)
如果发生冲突,我该如何更新?我试过了:
...
unnest(array['Peter']) as a,
unnest(array['someURL']) as b,
on conflict (id) do
update set
username = a,
profile_picture = b;
Run Code Online (Sandbox Code Playgroud)
但它会引发There is a column named "a" in table "*SELECT*", but it cannot be referenced from this part of the query.错误.
编辑:
表USERS非常简单:
create table USERS (
id text not null primary key,
username text,
profile_picture text
);
Run Code Online (Sandbox Code Playgroud) ActiveRecord是否具有内置的upsert功能?我知道我可以自己写,但我显然不想,如果这样的事情已经存在.
用postgresql 9.5正确语法upsert,下面的查询显示column reference "gallery_id" is ambiguous错误,为什么?
var dbQuery = `INSERT INTO category_gallery (
category_id, gallery_id, create_date, create_by_user_id
) VALUES ($1, $2, $3, $4)
ON CONFLICT (category_id)
DO UPDATE SET
category_id = $1,
last_modified_date = $3,
last_modified_by_user_id = $4
WHERE gallery_id = $2`;
Run Code Online (Sandbox Code Playgroud)
我试图改变WHERE gallery_id = $2;到 WHERE category_gallery.gallery_id = $2;随后显示的错误there is no unique or exclusion constraint matching the ON CONFLICT specification,但我不希望设置gallery_id或CATEGORY_ID独特监守我要确保两个列相同,那么请更新....
如何在postgres 9.5中正确进行upsert?
如果ON CONFLICT需要唯一的列,我应该使用其他方法,如何?
我想确保多列冲突然后更新,什么是正确的用法
var dbQuery = …Run Code Online (Sandbox Code Playgroud) 我写了一个函数为一个简单的博客引擎创建帖子:
CREATE FUNCTION CreatePost(VARCHAR, TEXT, VARCHAR[])
RETURNS INTEGER AS $$
DECLARE
InsertedPostId INTEGER;
TagName VARCHAR;
BEGIN
INSERT INTO Posts (Title, Body)
VALUES ($1, $2)
RETURNING Id INTO InsertedPostId;
FOREACH TagName IN ARRAY $3 LOOP
DECLARE
InsertedTagId INTEGER;
BEGIN
-- I am concerned about this part.
BEGIN
INSERT INTO Tags (Name)
VALUES (TagName)
RETURNING Id INTO InsertedTagId;
EXCEPTION WHEN UNIQUE_VIOLATION THEN
SELECT INTO InsertedTagId Id
FROM Tags
WHERE Name = TagName
FETCH FIRST ROW ONLY;
END;
INSERT INTO Taggings (PostId, TagId) …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个脚本,将新用户记录添加到ElasticSearch,如果用户已经存在则更新任何信息,并将新的PaymentInfo对象附加到用户的Payments数组(如果它存在于更新对象中).这是我目前使用的简化版本:
curl -XPOST 'http://localhost:9200/usrtest/usr/1/_update' -d '
{
"doc_as_upsert": true,
"doc": {
"customerId": "1",
"firstName": "Mark",
"lastName": "Z",
"emailAddress": "foo.bar@gmail.com",
"paymentInfo": {
"pid": "1",
"amt": "10"
}
}
}'
Run Code Online (Sandbox Code Playgroud)
这几乎可以满足我的需求,因为它可以正确地插入文档,或者如果用户存在具有相同ID的情况下更新文档,但是如果用户已经存在,则缺少将此paymentInfo添加到用户的paymentInfos数组的方面.就像现在一样,它只是覆盖了paymentInfo对象.我已经尝试将此脚本添加到更新JSON:
"script": "if (ctx._source.containsKey(\"paymentInfos\")) {ctx._source.paymentInfos += paymentInfo;} else {ctx._source.paymentInfos = paymentInfo}"
Run Code Online (Sandbox Code Playgroud)
但是弹性搜索doc在script指定元素时忽略元素.
我觉得我在这里错过了一些愚蠢的东西,但我不确定.这里有人可以帮帮我吗?
编辑: 我也尝试了以下内容:
curl -XPOST 'http://localhost:9200/usrtest/usr/1/_update' -d '
{
"script": "if (ctx._source.containsKey(\"paymentInfos\")) {ctx._source.paymentInfos += paymentInfo;} else {ctx._source.paymentInfos = paymentInfo}",
"upsert": {
"customerId": "1",
"firstName": "Mark",
"lastName": "Z",
"emailAddress": "foo.bar@gmail.com",
"paymentInfo": {
"pid": "1",
"amt": "10"
} …Run Code Online (Sandbox Code Playgroud) 可写CTE被认为是9.5之前的UPSERT的解决方案,如插入,PostgreSQL中的重复更新中所述?
可以执行带有以下信息的UPSERT,无论它是以UPDATE还是INSERT与以下可写CTE惯用语:
WITH
update_cte AS (
UPDATE t SET v = $1 WHERE id = $2 RETURNING 'updated'::text status
),
insert_cte AS (
INSERT INTO t(id, v) SELECT $2, $1 WHERE NOT EXISTS
(SELECT 1 FROM update_cte) RETURNING 'inserted'::text status
)
(SELECT status FROM update_cte) UNION (SELECT status FROM insert_cte)
Run Code Online (Sandbox Code Playgroud)
此查询将返回"已更新"或"已插入",或者可能(很少)因违反约束而失败,如https://dba.stackexchange.com/questions/78510/why-is-cte-open-to中所述-lost-更新
使用PostgreSQL 9.5+新的"UPSERT"语法可以实现类似的功能,从优化中获益并避免可能的约束违规吗?
upsert ×10
postgresql ×5
sql ×4
mongodb ×2
.net ×1
activerecord ×1
concurrency ×1
java ×1
jooq ×1
nosql ×1
plpgsql ×1
pymongo ×1
python ×1