AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题

问题[merge](dba)

Martin Hope
Daniel C.
Asked: 2022-06-21 05:34:21 +0800 CST

为什么 MERGE 不会将超过 277 条记录插入配置有时态表和历史表上的非聚集索引的表中

  • 26

我再次发现 SQL Server 和 MERGE 语句存在问题,需要一些确认。

我可以在 Azure 数据库上不断重现我的问题(但不能在本地 SQL Server 2017/2019 上)。

请执行以下步骤(一步一步,而不是一个命令执行)!

1) 架构脚本:

    CREATE TABLE [dbo].[ImpactValueHistory]
    (
        [Rn] BIGINT NOT NULL,

        [ImpactId] UNIQUEIDENTIFIER NOT NULL,
        [ImpactValueTypeId] INT NOT NULL,

        [Date] DATE NOT NULL,
        [Value] DECIMAL(38, 10) NOT NULL,

        [ValidFrom] DATETIME2 NOT NULL CONSTRAINT [DF_ImpactValueHistory_ValidFrom] DEFAULT CONVERT(DATETIME2, '0001-01-01'),
        [ValidTo] DATETIME2 NOT NULL CONSTRAINT [DF_ImpactValueHistory_ValidTo] DEFAULT CONVERT(DATETIME2, '9999-12-31 23:59:59.9999999'),

        [ImpactPeriodId] INT NOT NULL,

        [NormalizedValue] DECIMAL(38, 10) NOT NULL,
    )
    GO

    CREATE CLUSTERED COLUMNSTORE INDEX [COLIX_ImpactValueHistory]
        ON [dbo].[ImpactValueHistory];
    GO

    CREATE NONCLUSTERED INDEX [IX_ImpactValueHistory_ValidFrom_ValidTo_ImpactId_DimensionItemId]
        ON [dbo].[ImpactValueHistory] ([ValidFrom], [ValidTo], [ImpactId], [ImpactValueTypeId], [Date]);
    GO


    CREATE TABLE [dbo].[ImpactValue]
    (
        [Rn] BIGINT NOT NULL IDENTITY(1,1),

        [ImpactId] UNIQUEIDENTIFIER NOT NULL,
        [ImpactValueTypeId] INT NOT NULL,

        [Date] DATE NOT NULL,
        [Value] DECIMAL(38, 10) NOT NULL,

        [ValidFrom] DATETIME2 GENERATED ALWAYS AS ROW START NOT NULL CONSTRAINT [DF_ImpactValue_ValidFrom] DEFAULT CONVERT(DATETIME2, '0001-01-01'),
        [ValidTo] DATETIME2 GENERATED ALWAYS AS ROW END NOT NULL CONSTRAINT [DF_ImpactValue_ValidTo] DEFAULT CONVERT(DATETIME2, '9999-12-31 23:59:59.9999999'),

        [ImpactPeriodId] INT NOT NULL,

        [NormalizedValue] DECIMAL(38, 10) NOT NULL,

        PERIOD FOR SYSTEM_TIME ([ValidFrom], [ValidTo]),

        CONSTRAINT [PK_ImpactValue] PRIMARY KEY NONCLUSTERED ([ImpactId], [ImpactValueTypeId], [Date], [ImpactPeriodId])
    )
    WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[ImpactValueHistory]))
    GO

    CREATE UNIQUE CLUSTERED INDEX [IX_ImpactValue_Id] ON [dbo].[ImpactValue]([Rn])
    GO

    CREATE COLUMNSTORE INDEX [CIX_ImpactValue] ON [dbo].[ImpactValue] ([ImpactId], [ImpactValueTypeId], [Date], [Value], [NormalizedValue])
    GO

2) 插入一些随机数据的脚本

DECLARE @inserted0 TABLE ([Date] DATE, [ImpactId] uniqueidentifier, [ImpactPeriodId] int, [ImpactValueTypeId] int);
MERGE [dbo].[ImpactValue] USING (
SELECT TOP 278 -- <-- this number is critical
        DATEADD(MONTH, ROW_NUMBER() OVER(ORDER BY [Name]) - 1, '2000-01-01') AS [Date],
        NEWID() AS [ImpactId], 
        1 AS [ImpactPeriodId], 
        1 AS [ImpactValueTypeId], 
        99 AS [Value], 
        99 AS [NormalizedValue]
    FROM [sys].[all_columns]
) AS i ([Date], [ImpactId], [ImpactPeriodId], [ImpactValueTypeId], [Value], [NormalizedValue]) ON 1=0
WHEN NOT MATCHED THEN
INSERT ([Date], [ImpactId], [ImpactPeriodId], [ImpactValueTypeId], [Value], [NormalizedValue])
VALUES (i.[Date], i.[ImpactId], i.[ImpactPeriodId], i.[ImpactValueTypeId], i.[Value], i.[NormalizedValue])
OUTPUT INSERTED.[Date], INSERTED.[ImpactId], INSERTED.[ImpactPeriodId], INSERTED.[ImpactValueTypeId]
INTO @inserted0;

SELECT * FROM @inserted0

这一步应该返回所有插入的行!

3)从步骤2中删除数据) 这一步正在填充配置的历史表

DELETE [dbo].[ImpactValue]

4)再次插入一些随机数据 您可以使用步骤2中的脚本)

我必须注意,步骤 1) - 4) 应该单独执行,而不是在GO.

这一步应该再次返回所有插入的行!但事实并非如此! 在我这边,我总是得到一个空的结果。这可以在我们的三个生产数据库上重现:(

MERGE 语句由 EF Core 生成,目前我正在通过设置 Max Batch Size 来解决此问题。但这不可能是最终的解决方案。

它必须与在时态表上配置了非聚集索引的时态表有关。

也可以看看:

在过去,我已经偶然发现了这个问题:

  • https://stackoverflow.com/questions/70734060/why-does-a-merge-into-a-temporal-table-with-a-nonclustered-index-in-the-history。
  • https://github.com/dotnet/efcore/issues/22852

但是我当前的问题只能在 Azure SQL 数据库上重现,并且不会引发任何错误。

有趣的旁注:

  1. 如果我暂时禁用临时表->它正在工作
  2. 如果我删除非聚集索引 [IX_ImpactValueHistory_ValidFrom_ValidTo_ImpactId_DimensionItemId] -> 它正在工作
  3. 如果我在步骤 2 中使用 SELECT TOP (@BatchSize) -> 它正在工作
  4. 如果我只使用 OUTPUT 而不是 OUTPUT INTO @inserted0 --> 它正在工作

如果没有历史表上的 COLUMNSTORE 索引,它就可以工作。通过仅删除主表上的 COLUMNSTORE 索引,我看到了同样的问题。

TOP 278(a) 重现问题和 (b) 不重现的情况的实际执行计划TOP (@BatchSize)可在https://1drv.ms/u/s!AsOa6e9ukBWQlIRg9_9eySDFp5hvEA?e=KBQBsP获得。我还添加了批量大小为 277 的实际执行计划。两者都使用这个大小!

azure-sql-database merge
  • 1 个回答
  • 2016 Views
Martin Hope
HeyJude
Asked: 2022-02-15 14:07:10 +0800 CST

MERGE 与 MERGE INTO 有什么区别?

  • 2

MERGE 与 MERGE INTO 有什么区别?
每个的用例是什么?

令人惊讶的是,我找不到任何关于这种差异的现有问题。

MERGE的文档也没有解释这一点,而且它只在一个似乎与该差异无关的情况下使用一次(如果有的话)。

sql-server merge
  • 1 个回答
  • 539 Views
Martin Hope
TMilliman
Asked: 2019-12-15 20:52:13 +0800 CST

跨 TabName 为每个 PersonID 合并表记录

  • 0

考虑下表,

CREATE TABLE temp (
    [TabName] VARCHAR(255),
    [PersonID] VARCHAR(255),
    [FirstName] VARCHAR(255), 
    [Gender] VARCHAR(255),
    [BenefitType] VARCHAR(255),
    [HealthStatus] VARCHAR(255));

  INSERT INTO temp VALUES 
    ('TAB1', 'C103','John', 'M', 'Benefit Type 1', NULL),
    ('TAB2', 'C103','John', 'M', NULL, 'Healthy'),
    ('TAB3', 'C103', 'John', 'M', NULL, 'Healthy'),
    ('TAB1', 'C104', 'Mary', 'M', 'Benefit Type 2', NULL),
    ('TAB2', 'C104', 'Mary', 'M', NULL, 'Sick'),
    ('TAB3', 'C104', 'Mary', 'M', NULL, NULL)  
TabName     PersonID     FirstName    BenefitType      HealthStatus 
TAB1        C103         John         Benefit Type 1   NULL   
TAB2        C103         John         NULL             Healthy
TAB3        C103         John         NULL             Healthy
TAB1        C104         Mary         Benefit Type 2   NULL   
TAB2        C104         Mary         NULL             Sick   
TAB3        C104         Mary         NULL             NULL   

我想将跨 TabName 的信息合并到一个新表中,以便新表包含每个 PersonID 的所有唯一信息。

例如,根据上表,我想找到新的表

PersonID   FirstName    BenefitType      HealthStatus   
C103       John         Benefit Type 1   Healthy  
C104       Mary         Benefit Type 2   Sick   

我不太确定从哪里开始解决这个问题。

sql-server merge
  • 1 个回答
  • 19 Views
Martin Hope
SorryEh
Asked: 2019-11-01 17:22:17 +0800 CST

如何在 CRM 系统中对合并的组成记录进行用户验收测试?

  • 1

我一直在谷歌上搜索并了解 UAT 是什么以及如何执行它们,但我不太了解如何在这种情况下应用它。

我的接受标准是来自重复配置文件的所有历史数据,这些数据是交易、交互和自定义字段,例如booleans并strings合并到主记录中。

我对 UAT 的“测试”部分感到困惑……有什么要测试的?我们不只是查看配置文件并确认数据存在吗?这算不算测试?

我正在努力制定测试计划,因为我真的不知道要测试什么。

非常感谢任何帮助/建议/阅读/文章。


背景:我们有大约 300 万条记录(记录是 CRM 中的组成资料),我们已经确定至少四分之一的记录是重复的(常见情况是一个人有 5 个以上的资料)。

我们已经完成了建立标准并确定哪些重复项将被标记为主记录的活动,然后将重复记录合并到主记录中。

我们的下一步是验证主记录,以确保来自重复记录的历史配置文件数据保持不变(事务、交互以及任何自定义字段,如作为注册的一部分添加的布尔值和字符串,并合并到主记录中)。

任务:我要为多个团队制定一个 UAT 计划以验证合并(我确实表示我的背景与所询问的内容无关......但我会尝试,因为公司中没有其他人有任何想法在这一点上做什么,预算真的很紧张,所以不能雇用承包商)

duplication merge
  • 1 个回答
  • 53 Views
Martin Hope
Evan Carroll
Asked: 2018-04-08 01:12:45 +0800 CST

UPSERT 和 MERGE 的区别?

  • 5

从 PostgreSQL 维基,

MERGE通常用于合并两个表,并在 2003 年的 SQL 标准中引入。语句(REPLACEMySQL 扩展)或UPSERT序列尝试UPDATE, 或失败时, INSERT。这类似于UPDATE,然后对于不匹配的行,INSERT。并发访问是否允许可能导致行丢失的修改与实现无关。

进一步的 PostgreSQLINSERT ... ON CONFLICT DO NOTHING/UPDATE以UPSERT销售,并在 9.5 中添加

那是MERGE什么?它是如何融入其中的?

postgresql merge
  • 1 个回答
  • 10653 Views
Martin Hope
bayer
Asked: 2018-03-23 10:20:11 +0800 CST

如何在 MERGE INSERT 语句中获取类似标识的值

  • 1

我想将一个表合并bar到另一个表foo中,同时我必须为列分配一个唯一值messagenr。这是我这样做的尝试(sql-server):

MERGE foo AS target 
using bar AS source 
ON target.message LIKE source.message 
WHEN NOT matched BY target THEN 
INSERT (messagenr, 
        language, 
         message) 
VALUES ((SELECT Max(messagenr) 
         FROM   foo) 
       + 1, 
       'EN', 
       source.message); 

当然这是行不通的。messagenr对于插入的每个新数据集,我都得到完全相同的值。我不能修改表结构本身,所以我必须使用给定的结构。

如何messagenr在目标表中的每个新数据集中获取 UNIQUE 值?

sql-server merge
  • 2 个回答
  • 1370 Views
Martin Hope
Zach Smith
Asked: 2018-02-15 03:29:31 +0800 CST

更新 MERGE 语句中的许多列是否对性能不利?

  • 0

我有一个合并语句,需要插入大约 65 行的数据,或更新行。目前,当找到匹配项时,我正在更新所有列。但我不需要。

WHEN MATCHED THEN UPDATE如果我只更新几列而不是更新所有列,性能会有显着提高吗?

sql-server-2012 merge
  • 1 个回答
  • 140 Views
Martin Hope
hagubear
Asked: 2017-10-19 04:01:51 +0800 CST

SQL Server - 使用 NULLable 列合并连接条件

  • 1

我正在尝试合并我的两个表(相同的定义)。

MERGE INTO xx.dbo.acc_s AS Target 
 USING yy.dbo.acc_s AS Source 
 ON (Target.acc_id= Source.acc_id AND Target.s_id= Source.s_id AND a_code= Source.a_code) 
WHEN NOT matched BY Target THEN
INSERT (acc_id,s_id,a_code)
VALUES (Source.acc_id,Source.s_id,Source.a_code);

我所期望的是“如果目标没有该行,则插入它” - 没有别的。

我在其中一行上出现“违反主键”错误。如果它是按目标匹配的行,它不应该首先尝试插入它。

之后我所做的是:

MERGE INTO xx.dbo.acc_s AS Target 
 USING yy.dbo.acc_s AS Source 
 ON (Target.acc_id= Source.acc_id AND Target.s_id= Source.s_id AND ISNULL(a_code, '')= ISNULL(Source.a_code, '') 
WHEN NOT matched BY Target THEN
INSERT (acc_id,s_id,a_code)
VALUES (Source.acc_id,Source.s_id,Source.a_code);

它正确拾取。由此,我认为当我合并时,如果我有两个 NULL 列加入 - SQL Server 无法正确解决这个问题。我在这里遇到了预期的行为吗?

我知道我应该更愿意使用

WHEN matched THEN
UPDATE SET a_code = Source.a_code

但在那种情况下,我可能不得不更改很多东西,因为我正试图找到一种通过创建模板查询来更新其他表的通用方法。但是,我知道这可能不实用。

sql-server-2012 merge
  • 1 个回答
  • 6769 Views
Martin Hope
zlon
Asked: 2017-03-29 22:47:17 +0800 CST

合并来自 2 个数据库的 2 对表。初学者

  • 0

我有两个 MySql 数据库 DB1 和 DB2。他们每个人都有表 tbl1 和 tbl2。这两个表具有相同的主键 (Column1)。DB1 中的表有 N 行。我想创建新的数据库和表,如下所示:

DB1.tbl1.Col1   | DB1.tbl1.Col2 | ... | DB1.tbl1.ColK | DB1.tbl2.Col2 | DB1.tbl2.ColZ
    ...         |    ...        | ... |     ...       |    ...        |      ...   
DB2.tbl1.Col1+N | DB2.tbl1.Col2 | ... | DB2.tbl1.ColK | DB2.tbl2.Col2 | DB2.tbl2.ColZ
    ...         |    ...        | ... |     ...       |    ...        |      ...   

但是,我无法使用 MERGE,因为我需要新表中 DB2.tbl1.Col1 中的索引DB3.tbl.Col1=DB1.tbl1.Col1, DB2.tbl1.Col1+N。

我现在如何在客户端(在 Python 上)执行此操作,但是是否可以通过服务器端的一些 MySql 脚本来执行此操作?

谢谢你。

mysql merge
  • 1 个回答
  • 140 Views
Martin Hope
Govind
Asked: 2016-03-03 03:08:44 +0800 CST

当行已经存在时更新值

  • 2

我在模式'USER'中有表'A'。此表共有三列。以下是列的名称:

  • id(主键)
  • 姓名
  • 年龄

我想在这个表中插入一行,但是如果该行已经存在(具有相同的 id),那么应该更新名称和年龄,而不是给出错误 sqlcode -803。

有没有办法在一个查询中做到这一点?

db2 merge
  • 1 个回答
  • 2725 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve