相关疑难解决方法(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_timeupdated_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
查看次数