在 SQL 中导入重复记录时更新数据
update data when importing a duplicate record in SQL
我有一个独特的要求 - 我有一个 excel 格式的数据列表,我将此数据导入 SQL 2008 R2,每年一次,使用 SQL的导入功能。在 table "Patient_Info" 中,我在列 "MemberID" 上设置了一个主键,当我导入没有任何重复的数据时,一切都很好。
但有时,当我获取此数据时,一些患者的信息会重复更新地址/电话等,具有相同的 MemberID,并且由于我将其设置为主键,因此该记录被遗漏了正在导入数据库,因此我没有该患者的更新记录。
编辑
我不确定如何实现这一点,以更新一些可能具有现有 memberID 的行,非常感谢任何指向它的指针。
示例如下:
列表 1:
列表 2:
这不是一个非常独特的要求。
可以用来解决此问题的一种接受table 模式是将数据导入 "staging" table。暂存 table 将具有与您要导入到的目标 table 相同的结构,但它将是一个堆 - 它没有主键。
导入数据后,您将使用查询将较新的数据记录与较旧的数据记录合并 MemberID
。
合并所有相同的 MemberID
记录后,将不会有重复的 MemberID
值,然后您可以将所有临时 table 记录插入目标 table.
编辑
正如@Panagiotis Kanavos 建议的那样,您可以使用 SQL MERGE
语句插入新记录并将现有记录从暂存 table 更新到目标 table.
假设暂存 table 被命名为 Patient_Info_Stage
,目标 table 被命名为 Patient_Info
,并且这些 table 具有相似的架构。还假设字段 MemberId
是 table Patient_Info
的主键。
以下 MERGE
语句会将暂存 table 数据合并到目标 table:
BEGIN TRAN;
MERGE Patient_Info WITH (SERIALIZABLE) AS Target
USING Patient_Info_Stage AS Source
ON Target.MemberId = Source.MemberId
WHEN MATCHED THEN UPDATE
SET Target.FirstName = Source.FirstName
,Target.LastName = Source.LastName
,Target.Address = Source.Address
,Target.PhoneNumber = Source.PhoneNumber
WHEN NOT MATCHED THEN INSERT (
MemberID
,FirstName
,LastName
,Address
,PhoneNumber
) Values (
Source.MemberId
,Source.FirstName
,Source.LastName
,Source.Address
,Source.PhoneNumber
);
COMMIT TRAN;
*注意:T-SQL MERGE
操作不是原子操作,有可能进入竞争条件。为确保它能正常工作,请执行以下操作:
- 确保您的 SQL 服务器是最新的服务包和补丁(SQL Server 2008 R2 的当前版本是 SP3,版本 10.50.6000.34)。
- 将您的
MERGE
包装在一笔交易中(BEGIN TRAN;
、COMMIT TRAN;
)
- 使用
SERIALIZABLE
提示帮助防止 T-SQL MERGE
语句的潜在竞争条件。
我有一个独特的要求 - 我有一个 excel 格式的数据列表,我将此数据导入 SQL 2008 R2,每年一次,使用 SQL的导入功能。在 table "Patient_Info" 中,我在列 "MemberID" 上设置了一个主键,当我导入没有任何重复的数据时,一切都很好。
但有时,当我获取此数据时,一些患者的信息会重复更新地址/电话等,具有相同的 MemberID,并且由于我将其设置为主键,因此该记录被遗漏了正在导入数据库,因此我没有该患者的更新记录。
编辑
我不确定如何实现这一点,以更新一些可能具有现有 memberID 的行,非常感谢任何指向它的指针。
示例如下:
列表 1:
列表 2:
这不是一个非常独特的要求。
可以用来解决此问题的一种接受table 模式是将数据导入 "staging" table。暂存 table 将具有与您要导入到的目标 table 相同的结构,但它将是一个堆 - 它没有主键。
导入数据后,您将使用查询将较新的数据记录与较旧的数据记录合并 MemberID
。
合并所有相同的 MemberID
记录后,将不会有重复的 MemberID
值,然后您可以将所有临时 table 记录插入目标 table.
编辑
正如@Panagiotis Kanavos 建议的那样,您可以使用 SQL MERGE
语句插入新记录并将现有记录从暂存 table 更新到目标 table.
假设暂存 table 被命名为 Patient_Info_Stage
,目标 table 被命名为 Patient_Info
,并且这些 table 具有相似的架构。还假设字段 MemberId
是 table Patient_Info
的主键。
以下 MERGE
语句会将暂存 table 数据合并到目标 table:
BEGIN TRAN;
MERGE Patient_Info WITH (SERIALIZABLE) AS Target
USING Patient_Info_Stage AS Source
ON Target.MemberId = Source.MemberId
WHEN MATCHED THEN UPDATE
SET Target.FirstName = Source.FirstName
,Target.LastName = Source.LastName
,Target.Address = Source.Address
,Target.PhoneNumber = Source.PhoneNumber
WHEN NOT MATCHED THEN INSERT (
MemberID
,FirstName
,LastName
,Address
,PhoneNumber
) Values (
Source.MemberId
,Source.FirstName
,Source.LastName
,Source.Address
,Source.PhoneNumber
);
COMMIT TRAN;
*注意:T-SQL MERGE
操作不是原子操作,有可能进入竞争条件。为确保它能正常工作,请执行以下操作:
- 确保您的 SQL 服务器是最新的服务包和补丁(SQL Server 2008 R2 的当前版本是 SP3,版本 10.50.6000.34)。
- 将您的
MERGE
包装在一笔交易中(BEGIN TRAN;
、COMMIT TRAN;
) - 使用
SERIALIZABLE
提示帮助防止 T-SQLMERGE
语句的潜在竞争条件。