使用查询从实时环境更新测试 SQL Server 数据库上的表

Ale*_*erK 0 t-sql sql-server sql-server-2016

我需要从我们的生产数据库更新测试环境中的一些表。基本上是同一张表,只是更新了几个月。

所以,这是我试图实现的一个查询:

UPDATE [Server-DEV].[Database].[dbo].[bHRRM] 
SET [Field1] = b.[Field1], 
    [Field2] = b.[Field2], ... ,
    [FieldX] = b.[FieldX]
FROM [Server-PROD].[Database].[dbo].[bHRRM] AS b
Run Code Online (Sandbox Code Playgroud)

我不关心数据被覆盖,因为它是一样的。即使相反也是如此 - 如果有差异,最好测试服务器进行相应更新。但我不想要重复的。

KeyID现在,如果包含列,则存在问题。即使我将其排除在SET- 之外,仍然存在错误:

无法在具有唯一索引“biHRRM”的对象“dbo.bHRRM”中插入重复的键行。重复的键值为 (5, 1000)。

所以,第一个问题是——我做错了什么?

Joe*_*orn 5

我现在看到的问题是更新查询中没有任何内容可以将 PROD 服务器数据与 DEV 服务器数据关联起来。两个表具有相同的架构和键定义是不够的:您需要显式关联作为语句的一部分UPDATE

这意味着它尝试将生产中每一行的值设置为开发中的每一行。这会很,但更重要的是:它会在不同的点创建重复项。

应该起作用的是:

UPDATE dev
SET [Field1] = prod.[Field1], 
    [Field2] = prod.[Field2], ... ,
    [FieldX] = prod.[FieldX]
FROM [Server-PROD].[Database].[dbo].[bHRRM] AS prod
INNER JOIN [Server-DEV].[Database].[dbo].[bHRRM] dev on dev.KeyID = prod.KeyID
Run Code Online (Sandbox Code Playgroud)

或者,如果这是从生产中进行的某种完全刷新,您可能会考虑删除 DEV 表以完全替换它(通过SELECT INTO)。(这也意味着重新定义任何索引/触发器/等)。或者,您可以使用TRUNCATEDEV 表有效地删除所有记录但保留结构,然后执行INSERT ... SELECTwith noWHERE从生产中重新填充数据。

当然,如果不是完全刷新,这些选项可能会删除重要的旧行并插入您不需要的新行(然后仅UPDATE显示查询就足够了)。但如果是的话,这也会处理这些操作,以简化旧流程或覆盖以前遗漏的内容。