【问题标题】:SQL - How to use the output from an insert to update a tableSQL - 如何使用插入的输出来更新表
【发布时间】:2015-06-10 15:57:17
【问题描述】:

问题信息

详细问题

解释我的问题的最佳方式是解释我想要的结果。我正在尝试获取一组办公室,将其数据插入到 dbo.DeliveryLocation 表中,然后获取输出 inserted.DeliveryLocationId 并更新相应办公室的 DeliveryLocationId 字段用那个 id。

期望的结果示例

之前的办公室数据

OfficeId | DeliveryLocationId
-----------------------------
1        | null

2        | null

3        | null

运行 SQL 语句

之后的办公室数据

OfficeId | DeliveryLocationId
-----------------------------
1        | 5

2        | 6

3        | 7
  • DeliveryLocationId 为 5 的交付位置是用 OfficeId为1的Office数据

  • DeliveryLocationId 为 6 的交付位置是使用 OfficeId为2的Office数据

  • DeliveryLocationId 为 7 的交付位置是使用 OfficeId为3的Office数据

问题

根据下面我当前的 SQL 脚本,您可以看到我已经完成了第一部分(将 Office 数据插入到交付位置表)。第二部分(使用创建的交付位置的相应 DeliveryLocationId 更新 Office)不完整,我不确定如何去做。

我最初的想法/解决方案

如果有办法存储相关的 OfficeId 和 DeliveryLocationId,也许我们可以遍历它们并在第二个 SQL 语句中更新 office,而不是尝试创建一个 SQL 语句来处理所有事情。

参考文献

dbo.DeliveryLocation

    [DeliveryLocationId] [int] IDENTITY(1,1) NOT NULL,
    [LocationName] [nvarchar](max) NULL,
    [ShortName] [nvarchar](max) NULL,
    [ValidatedAddressId] [int] NOT NULL,
    [DropoffInstruction] [nvarchar](max) NULL,
    [PickupInstruction] [nvarchar](max) NULL,
    [TaxRate] [decimal](18, 2) NOT NULL,
    [Active] [bit] NOT NULL,
    [DisableOffices] [bit] NOT NULL

dbo.Office

    [OfficeId] [int] IDENTITY(1,1) NOT NULL,
    [OfficeName] [nvarchar](max) NULL,
    [ValidatedAddressId] [int] NOT NULL,
    [ReferralSource] [nvarchar](max) NOT NULL,
    [NumberOfEmployees] [int] NOT NULL,
    [DeliveryLocationId] [int] NULL

当前 SQL

insert into
    dbo.DeliveryLocation
(LocationName, ShortName, ValidatedAddressId, Active, DisableOffices)
output
    inserted.DeliveryLocationId
select 
    OfficeName, OfficeName, ValidatedAddressId, 0, 0 
from
    dbo.Office as o
where
    OfficeId in
    (
    select distinct 
        OfficeId 
    from 
        dbo.[User] as u
    where
        u.DeliveryLocationId is null
    and
        u.OfficeId is not null
    )

【问题讨论】:

  • 这是一个一劳永逸的过程。从高层的角度来看,这是数据迁移计划的开始。
  • 您能否在其中修改表结构?一种解决方案是临时向DeliveryLocation 表添加一个新列,允许您将OfficeId 插入其中。然后使用它来更新Office.DeliveryLocationId 列。完成后,从 DeliveryLocation 中删除新列。
  • @MartinParkin 我拥有执行上述解决方案的全部权限和能力。我的犹豫来自于数据库是从实体框架(CodeFirst)生成的事实。对于不熟悉前者的人来说,长话短说,数据库的结构是由外部管理的,我不确定手动修改结构会有什么影响,即使是暂时的。
  • 您可以使用 CURSOR。无论如何,这是一次性事件,没有相关的性能问题,而且很容易做到......

标签: sql sql-server sql-update sql-insert


【解决方案1】:

我不确定在 INSERT 语句中执行此操作,但如果您使用使用 Office(或基于 Office 的查询)作为源的 MERGE 语句,您将能够参考源.OfficeId 以及 OUTPUT 子句中的inserted.DeliveryLocationId。您可以简单地跳过MERGE 的更新和删除用法,而只使用ON NOT MATCHED 子句。

当我做这样的事情时,我把输出放到一个临时表中,然后从那里执行我需要做的任何进一步的更新或插入。

如果您之前没有使用过 MERGE 语句(或者甚至对于尚未使用所有功能的人),这是一个非常棒的资源,可以帮助您了解如何使用它们以及如何使用它们嗯:http://www.made2mentor.com/2012/07/got-the-urge-to-merge/

【讨论】:

    【解决方案2】:

    您可以在插入交​​货位置后进行更新加入

    update dbo.Office
    set o.DeliveryLocationID = dl.DeliveryocationID
    from Office o
    JOIN DeliveryLocation dl on dl.LocationName = o.OfficeName
    

    假设办公室名称是唯一的。如果不是,您可能希望将 OfficeID 添加到 DeliveryLocations 表中,至少是暂时的,然后加入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-04
      • 2022-01-07
      • 1970-01-01
      相关资源
      最近更新 更多