相关疑难解决方法(0)

Postgres UPSERT(INSERT或UPDATE)仅在值不同时才使用

我正在更新Postgres 8.4数据库(来自C#代码),基本任务很简单:要么更新现有行,要么插入一个新行(如果还不存在).通常我会这样做:

UPDATE my_table
SET value1 = :newvalue1, ..., updated_time = now(), updated_username = 'evgeny'
WHERE criteria1 = :criteria1 AND criteria2 = :criteria2
Run Code Online (Sandbox Code Playgroud)

如果0行受到影响,那么执行INSERT:

INSERT INTO my_table(criteria1, criteria2, value1, ...)
VALUES (:criteria1, :criteria2, :newvalue1, ...)
Run Code Online (Sandbox Code Playgroud)

但是有一点点扭曲.我不想更改updated_time和updated_username列,除非任何新值实际上与现有值不同,以避免误导用户更新数据的时间.

如果我只是在进行UPDATE,那么我也可以为这些值添加WHERE条件,但这在这里不起作用,因为如果DB已经是最新的UPDATE将影响0行,那么我会尝试INSERT.

任何人都可以想到一个优雅的方法来做到这一点,除了SELECT,然后更新或插入?

sql postgresql merge upsert

13
推荐指数
3
解决办法
3万
查看次数

PostgreSQL - CTE upsert返回修改的行

我用CTE写了一个'upsert'查询,看起来像这样:

WITH
  new_data (id, value) AS (
    VALUES (1, 2), (3, 4), ...
  ),
  updated AS (
    UPDATE table t set
      value = t.value + new_data.value
    FROM new_data
    WHERE t.id = new_data.id
    RETURNING t.*
  )
INSERT INTO table (id, value)
  SELECT id, value
  FROM new_data
  WHERE NOT EXISTS (
    SELECT 1 FROM updated WHERE updated.id = new_data.id
  )
Run Code Online (Sandbox Code Playgroud)

但是,我需要在我的应用程序中使用新值,但此查询不会返回任何内容.添加returning *到插入的末尾将返回已插入的所有行,但不会返回任何已更新的行.

那么,问题是(如何)我可以扩展它以返回已更新的行和插入的行?

编辑:当然我可以SELECT在一个事务中运行它然后运行,但我很想知道是否有单查询方式.

sql postgresql upsert common-table-expression postgresql-9.1

11
推荐指数
1
解决办法
3778
查看次数

使用PostgreSQL 9.3在CTE UPSERT中生成DEFAULT值

我发现使用可写CTE模拟PostgreSQL中的upsert是一个非常优雅的解决方案,直到我们在Postgres中获得实际的upsert/merge.(见:https://stackoverflow.com/a/8702291/558819)

但是,有一个问题:如何插入默认值?NULL当然,使用将无助于NULL显式插入NULL,与MySQL不同.一个例子:

WITH new_values (id, playlist, item, group_name, duration, sort, legacy) AS (
    VALUES (651, 21, 30012, 'a', 30, 1, FALSE)
    ,      (NULL::int, 21, 1, 'b', 34, 2, NULL::boolean)
    ,      (668, 21, 30012, 'c', 30, 3, FALSE)
    ,      (7428, 21, 23068, 'd', 0, 4, FALSE)
), upsert AS (
    UPDATE playlist_items m
    SET    (playlist, item, group_name, duration, sort, legacy)
       = (nv.playlist, nv.item, nv.group_name, nv.duration, nv.sort, nv.legacy)
    FROM   new_values nv
    WHERE …
Run Code Online (Sandbox Code Playgroud)

sql postgresql merge upsert sql-insert

10
推荐指数
1
解决办法
1787
查看次数

如果一行不存在,则插入else不会在postgres中插入

我需要检查是否存在行.如果它不存在,则应插入.

这是在postgres,我试图通过shell脚本插入行.当我运行脚本时,它不显示错误,但即使没有匹配的行,它也不会插入到表中.

sql postgresql

9
推荐指数
1
解决办法
3万
查看次数

MERGE语法用于在重复UPDATE上进行UPSERT或INSERT

所以我来自MySQL,我可以在DUPLICATE UPDATE进行INSERT:

INSERT INTO table (a,b,c) 
VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
Run Code Online (Sandbox Code Playgroud)

但是现在我正在使用PostgreSQL,并且努力添加UPSERT功能,看起来MERGE可能适用于我想要的但想看看这是否是最优化的语法.示例语法1,我也看过这个,但不明白如何实现.我还没有尝试过这个,因为我认为MERGE用于合并从table1到Table2的数据或者这样的工作?

MERGE
INTO    table
USING   table
ON      c = 1
WHEN MATCHED THEN
UPDATE
SET     c=c+1
WHEN NOT MATCHED THEN
INSERT  (a,b,c)
VALUES  (1,2,3)
Run Code Online (Sandbox Code Playgroud)

还有其他建议吗?

sql postgresql upsert

8
推荐指数
1
解决办法
2万
查看次数

MongoDB Capped集合在PostgreSQL中等效

MongoDB上限集合的基础是它们允许您设置表的最大大小,并且系统将在达到大小限制时清除旧数据.

有没有人想出PostgreSQL中的类似设置并在生产中使用它?

postgresql mongodb database-replication

7
推荐指数
2
解决办法
1801
查看次数

如何在没有 SELECT 的情况下调用 postgres 中的函数?

我为我创建了以下函数postgresql:

CREATE FUNCTION myfunc(param INT) RETURNS VOID AS..
Run Code Online (Sandbox Code Playgroud)

如果没有 ,我该如何调用该函数SELECT?当我运行时SELECT myfunc(1)它会工作,即使它不会按设计返回任何内容。

但我想在没有 select, just 的情况下运行它myfunc(1),这不起作用并告诉我Syntax error at 1。

我正在尝试在 PostgreSQL 中的重复更新中实现插入中的 db_merge 函数?。

我无法SELECT db_merge(..)从 java 运行,因为这会给我一个"A result was returned when none was expected."), PSQLState.TOO_MANY_RESULTS)错误。

java postgresql jdbc

7
推荐指数
1
解决办法
7625
查看次数

Laravel使用Query Builder进行upsert操作

在我的一个工作脚本中,基于某些指标存储聚合计数,我没有使用Eloquent,因为查询有点复杂,并且使用查询构建器很容易编写.我目前从数据库中获取值,我需要在数据库中插入/更新它.使用Query Builder可以实现upsert操作是否可以使用Query Builder实现?或者我是否每次都需要检查此条目是否在数据库中?

我总共有100,000个条目,并希望将其作为日常工作运行.因此,如果我需要检查数据库中是否存在特定条目,我需要多次访问数据库.有替代解决方案吗?

我正在考虑创建两个模型类,一个使用Eloquent,另一个使用查询构建器.我可以在Eloquent模型中使用我的自定义查询吗?

query-builder laravel eloquent laravel-5 laravel-query-builder

7
推荐指数
2
解决办法
5825
查看次数

合并具有相同列名的两个表,添加计数器

我有两个具有相同列的表,第一列是名称,第二列是计数.我想合并这些表,以便每个名称都显示两个表的添加计数:

Table1:           Table2:            Result Table:
NAME   COUNT      NAME   COUNT       NAME   COUNT
name1  1          name3  3           name1  1
name2  2          name4  4           name2  2
name3  3          name5  5           name3  6
name4  4          name6  6           name4  8
                                     name5  5
                                     name6  6
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经创建了一个非常难看的结构来执行此操作,并且想知道是否有可能以更优雅的方式获得结果.

到目前为止我所拥有的(表1是test1,表2是test2):

create table test1 ( name varchar(40), count integer);
create table test2 ( name varchar(40), count integer);
create table test3 ( name varchar(40), count integer);
create table test4 ( name varchar(40), count integer);
create table test5 ( name varchar(40), count …
Run Code Online (Sandbox Code Playgroud)

sql postgresql merge

6
推荐指数
2
解决办法
2万
查看次数

PHP备份整个PostgreSQL数据库然后恢复表的一部分

我目前正在使用pg_dump备份整个数据库:

<?php

include_once("../db.php");

$password = getPGPassword();
$user = getPGUser();
$db = getPGDb();

putenv("PGPASSWORD=" . $password);
$dumpcmd = array("pg_dump", "-i", "-U", escapeshellarg($user), "-F", "c", "-b", "-v", "-f", escapeshellarg('/var/www/backups/backup-'.time().'.sql'), escapeshellarg($db));
exec( join(' ', $dumpcmd), $cmdout, $cmdresult );
putenv("PGPASSWORD");

?>
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用psql来恢复整个数据库,但有没有办法可以使用查询有选择地恢复表的一部分?我能想到的最简单的事情是使用psql创建一个临时数据库,从所需的表中读取行,根据主串行键删除冲突的行,然后插入表中.

有一个更好的方法吗?我需要完整的SQL查询功能.

php database postgresql

6
推荐指数
1
解决办法
1111
查看次数