标签: sql-merge

在PostgreSQL中重复更新时插入?

几个月前,我从Stack Overflow的答案中学到了如何使用以下语法在MySQL中一次执行多个更新:

INSERT INTO table (id, field, field2) VALUES (1, A, X), (2, B, Y), (3, C, Z)
ON DUPLICATE KEY UPDATE field=VALUES(Col1), field2=VALUES(Col2);
Run Code Online (Sandbox Code Playgroud)

我现在切换到PostgreSQL,显然这是不正确的.它指的是所有正确的表,所以我认为这是使用不同关键字的问题,但我不确定PostgreSQL文档中的哪个被覆盖.

为了澄清,我想插入几个东西,如果它们已经存在则更新它们.

sql postgresql upsert sql-merge

611
推荐指数
15
解决办法
40万
查看次数

如何在PostgreSQL中UPSERT(MERGE,INSERT ...在DUPLICATE UPDATE上)?

这里一个非常常见的问题是如何进行upsert,这是MySQL调用的INSERT ... ON DUPLICATE UPDATE,标准支持作为MERGE操作的一部分.

鉴于PostgreSQL不直接支持它(在第9.5页之前),你是如何做到这一点的?考虑以下:

CREATE TABLE testtable (
    id integer PRIMARY KEY,
    somedata text NOT NULL
);

INSERT INTO testtable (id, somedata) VALUES
(1, 'fred'),
(2, 'bob');
Run Code Online (Sandbox Code Playgroud)

现在,假设你想"UPSERT"的元组(2, 'Joe'),(3, 'Alan'),因此新表的内容是:

(1, 'fred'),
(2, 'Joe'),    -- Changed value of existing tuple
(3, 'Alan')    -- Added new tuple
Run Code Online (Sandbox Code Playgroud)

这是人们在讨论时所谈论的内容upsert.至关重要的是,任何方法在同一个表上存在多个事务时都必须是安全的 - 通过使用显式锁定,或以其他方式抵御由此产生的竞争条件.

关于PostgreSQL中的重复更新,Insert上广泛讨论了这个主题,但这是关于MySQL语法的替代品,随着时间的推移,它已经成长为一些无关的细节.我正在研究明确的答案.

这些技术对于"插入如果不存在,否则什么都不做"也很有用,即"插入...复制键忽略".

postgresql upsert insert-update sql-merge

246
推荐指数
5
解决办法
18万
查看次数

ORA-30926:无法在源表中获得稳定的行集

我正进入(状态

ORA-30926:无法在源表中获得稳定的行集

在以下查询中:

  MERGE INTO table_1 a
      USING 
      (SELECT a.ROWID row_id, 'Y'
              FROM table_1 a ,table_2 b ,table_3 c
              WHERE a.mbr = c.mbr
              AND b.head = c.head
              AND b.type_of_action <> '6') src
              ON ( a.ROWID = src.row_id )
  WHEN MATCHED THEN UPDATE SET in_correct = 'Y';
Run Code Online (Sandbox Code Playgroud)

我运行table_1它有数据,我也运行内部查询(src)也有数据.

为什么会出现此错误以及如何解决?

oracle sql-merge

124
推荐指数
5
解决办法
37万
查看次数

DBMS级别的管道和过滤器:拆分MERGE输出流

脚本

我们有一个非常标准的数据导入过程,我们在其中加载一个staging表,然后将MERGE其加载 到target表中.

新要求(绿色)涉及将导入数据的子集捕获到单独的queue表中,以进行完全不相关的处理.

场景架构

"挑战"

(1)子集由选择的记录组成:target仅新添加到表中的记录.

(2)子集是一些插入列的投影,但也是至少一个仅存在于源(staging 表)中的列.

(3)该MERGE语句已OUTPUT..INTO严格使用该子句记录所$action采用的MERGE,以便我们可以 为统计目的提供PIVOT结果和COUNT插入,更新和删除的数量.我们并不喜欢像这样缓冲整个数据集的操作,而是希望动态聚合总和.不用说,我们不想在此OUTPUT表中添加更多数据.

(4)我们不想做MERGE 任何原因,甚至部分地执行第二次的匹配工作.该 target表是非常大的,我们不能索引一切,操作通常是相当昂贵的(几分钟,而不是秒).

(5)我们不考虑将任何输出从MERGE客户端传输到客户端,以便客户端可以queue通过立即将其发送回来将其路由到客户端.数据必须保留在服务器上.

(6)我们希望避免在staging和之间的临时存储中缓冲整个数据集queue.

最好的方法是什么?

故障

(a)仅将插入的记录排入队列的要求使我们无法queue直接将表格中的表格置于OUTPUT..INTO其中MERGE,因为它不允许任何WHERE条款.我们可以使用一些 CASE技巧来标记不需要的记录,以便在queue不进行处理的情况下进行后续删除,但这看起来很疯狂.

(b)因为用于表的某些列queue没有出现在 target表中,我们不能简单地在目标表上添加插入触发器来加载queue."数据流分裂"必须尽快发生.

(c)由于我们已经在中使用了一个OUTPUT..INTO子句MERGE,我们不能添加第二个OUTPUT子句并将其 …

sql t-sql sql-server sql-merge azure-sql-database

26
推荐指数
4
解决办法
497
查看次数

SQL MERGE语句中的UPDATE-no-op

我有一个表中包含一些持久性数据.现在,当我查询它时,我还有一个非常复杂的CTE,它计算结果所需的值,我需要将缺少的行插入到持久表中.最后,我想选择由CTE识别的所有行组成的结果,但是如果它们已经在表中,则使用表中的数据,并且我需要有关是否刚刚插入行的信息.

简化这样的工作原理(如果您想尝试以下代码作为普通查询运行):

-- Set-up of test data, this would be the persisted table 
DECLARE @target TABLE (id int NOT NULL PRIMARY KEY) ;
INSERT INTO @target (id) SELECT v.id FROM (VALUES (1), (2)) v(id);

-- START OF THE CODE IN QUESTION
-- The result table variable (will be several columns in the end)
DECLARE @result TABLE (id int NOT NULL, new bit NOT NULL) ;

WITH Source AS (
    -- Imagine a fairly expensive, recursive CTE here
    SELECT * FROM …
Run Code Online (Sandbox Code Playgroud)

t-sql sql-server-2008 sql-update sql-merge

21
推荐指数
1
解决办法
4528
查看次数

SQL合并与目标不匹配,与源不匹配

需要一点帮助,我的SQL几乎不存在......

NOT MATCHED BY SOURCE vs 之间有什么区别?NOT MATCHED BY TARGET

例如:

是否WHEN NOT MATCHED BY SOURCE意味着记录存在于目标中而不是源中?- 所以我们可以删除它们?

并且WHEN NOT MATCHED BY TARGET- 表示记录存在于源中但不存在于目标中?所以我们可以插入它们?

sql sql-server sql-merge

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

在Oracle SQL中执行MERGE时,如何更新SOURCE中不匹配的行?

我有一个main数据库和report数据库,我需要从同步表mainreport.

但是,当一个项目在main数据库中被删除时,我只想IsDeletedreport数据库中设置一个标志.

这样做的优雅方式是什么?

我目前正在使用MERGE语句,如下所示:

MERGE INTO report.TEST target
USING (SELECT * FROM main.TEST) source
   ON (target.ID = source.ID)
WHEN MATCHED THEN
    UPDATE SET (target... = source...)
WHEN NOT MATCHED THEN
    INSERT (...) VALUES (source...)
;
Run Code Online (Sandbox Code Playgroud)

WHEN NOT MATCHED语句为我提供了所有新值main,但我也希望更新所有OLD值report.

我正在使用Oracle PL/SQL.

sql oracle sql-merge

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

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

SQL Server MERGE +加入其他表

我在数据库项目中使用MERGE语句来填充静态值集中的引用数据,如下所示:

    MERGE INTO dbo.[User] AS TARGET
USING (VALUES
    ('me@somewhere.com', 'My Name'))
AS SOURCE(UserName, FullName)
ON SOURCE.UserName = TARGET.UserName
WHEN NOT MATCHED BY TARGET THEN
    INSERT (UserId, UserName, FullName)
    VALUES (NEWID(), UserName, FullName);
Run Code Online (Sandbox Code Playgroud)

当我想根据其他表中的内容填充辅助表时,会出现问题.例如,我的UserPermission表包含用户ID和角色ID,我希望我的静态值设置为('me@somewhere.com','Admin'),并且能够加入User和Permission以获得INSERTing的ID值.不知道该怎么办......

编辑:

用户表(ID,用户名)1,John Smith 2,Mark Wahlerg

角色表(ID,RoleName)1,管理员2,用户3,访客

用户角色表(用户ID,角色ID)

我希望MERGE语句的SQL调整User-Role表,以便我可以指定类似的东西:

USING(VALUES
 ('John Smith', 'Administrator'),
 ('Mark Wahlburg', 'User')
Run Code Online (Sandbox Code Playgroud)

并且它将连接以确定ID,插入不存在的组合(并且可能删除那些但不在MERGE中的组合.

解:

WITH CTE AS
(
   SELECT UserId, RoleId
   FROM (VALUES
      ('John Smith', 'Administrator'),
      ('Mark Wahlburg', 'User'))
      AS SOURCE(UserName, RoleName)
   INNER JOIN User ON SOURCE.UserName = User.UserName
   INNER JOIN Role ON SOURCE.RoleName …
Run Code Online (Sandbox Code Playgroud)

t-sql sql-server merge common-table-expression sql-merge

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

Oracle Merge vs Select然后选择Insert或Update

什么更快?

合并声明

    MERGE INTO table_name 
     USING dual
     ON (row_id = 'some_id')
    WHEN MATCHED THEN
     UPDATE SET col_name = 'some_val'
    WHEN NOT MATCHED THEN
     INSERT (row_id, col_name)
     VALUES ('some_id', 'some_val')
Run Code Online (Sandbox Code Playgroud)

要么

查询select语句然后使用update或insert语句.

    SELECT * FROM table_name where row_id = 'some_id'
Run Code Online (Sandbox Code Playgroud)

如果rowCount == 0

    INSERT INTO table_name (row_id,col_name) VALUES ('some_id','some_val')
Run Code Online (Sandbox Code Playgroud)

其他

    UPDATE table_name SET col_name='some_val' WHERE row_id='some_id'
Run Code Online (Sandbox Code Playgroud)

sql oracle sql-merge

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