2

我需要将内容从一个表复制到自身和相关表...让我将问题图解。假设我有两张桌子:

Order
OrderID : int
CustomerID : int
OrderName : nvarchar(32)

OrderItem
OrderItemID : int
OrderID : int
Quantity : int

PK 是自动增量的。

假设我想将一位客户的内容复制到另一位客户。我如何有效地做到这一点?

问题是PK。我需要将OrderIDs原始数据集的值映射到副本,以便在OrderItem. 如果我只是选择-插入,我将无法创建该地图。

建议?

4

4 回答 4

1

为了复制一个父母和许多孩子的身份作为键,我认为该OUTPUT子句可以使事情变得非常干净(这里是 SqlFiddle):

-- Make a duplicate of parent 1, including children

-- Setup some test data
create table Parents (
      ID int not null primary key identity
    , Col1 varchar(10) not null
    , Col2 varchar(10) not null
)
insert into Parents (Col1, Col2) select 'A', 'B'
insert into Parents (Col1, Col2) select 'C', 'D'
insert into Parents (Col1, Col2) select 'E', 'F'

create table Children (
      ID int not null primary key identity
    , ParentID int not null references Parents (ID)
    , Col1 varchar(10) not null
    , Col2 varchar(10) not null
)
insert into Children (ParentID, Col1, Col2) select 1, 'g', 'h'
insert into Children (ParentID, Col1, Col2) select 1, 'i', 'j'
insert into Children (ParentID, Col1, Col2) select 2, 'k', 'l'
insert into Children (ParentID, Col1, Col2) select 3, 'm', 'n'

-- Get one parent to copy
declare @oldID int = 1

-- Create a place to store new ParentID
declare @newID table (
    ID int not null primary key
)

-- Create new parent
insert into Parents (Col1, Col2)
output inserted.ID into @newID -- Capturing the new ParentID
select Col1, Col2
from Parents
where ID = @oldID -- Only one parent

-- Create new children using the new ParentID
insert into Children (ParentID, Col1, Col2)
select n.ID, c.Col1, c.Col2
from Children c
    cross join @newID n
where c.ParentID = @oldID -- Only one parent

-- Show some output
select * from Parents
select * from Children
于 2013-01-31T21:48:51.180 回答
0
  • 向 Order 添加一个名为 OldOrderID 的额外帮助器列
  • 将所有订单从@OldCustomerID 复制到@NewCustomerID
  • 使用 OldOrderID 列复制所有 OrderItems 以帮助建立关系
  • 从 Order 中删除额外的帮助列

    ALTER TABLE 订单添加 OldOrderID INT NULL

    插入订单 (CustomerID, OrderName, OldOrderID) SELECT @NewCustomerID, OrderName, OrderID FROM Order WHERE CustomerID = @OldCustomerID

    INSERT INTO OrderItem (OrderID, Quantity) SELECT o.OrderID, i.Quantity FROM Order o INNER JOIN OrderItem i ON o.OldOrderID = i.OrderID WHERE o.CustomerID = @NewCustomerID

    更新订单集 OldOrderID = null WHERE OldOrderID 不为空

    ALTER TABLE 订单删除列 OldOrderID

于 2013-01-31T20:57:54.507 回答
0

如果每个客户都是唯一的OrderName,您可以简单地执行以下操作:

INSERT INTO [Order] ([CustomerID], [OrderName])
  SELECT
    2 AS [CustomerID],
    [OrderName]
  FROM [Order]
  WHERE [CustomerID] = 1

INSERT INTO [OrderItem] ([OrderID], [Quantity])
  SELECT
    [o2].[OrderID],
    [oi1].[Quantity]
  FROM [OrderItem] [oi1]
  INNER JOIN [Order] [o1] ON [oi1].[OrderID] = [o1].[OrderID]
  INNER JOIN [Order] [o2] ON [o1].[OrderName] = [o2].[OrderName]
  WHERE [o1].[CustomerID] = 1 AND [o2].[CustomerID] = 2

否则,您将不得不使用临时表或更改现有Order表,如 @LastCoder 建议的那样。

于 2013-01-31T21:05:20.747 回答
0

您是否必须将表 A 中的主键作为表 B 中的主键?如果没有,您可以使用 insert into 执行 select 语句。主键通常是从不断增加的种子(身份)开始的整数。解决这个问题并有问题地声明插入相同数据的缺点是有人认为这是该表上的不同键集,而不是“关系”或外键值。

您可以选择主键以插入其他表,而不是它们自己....除非您设置“身份插入”提示。除非您知道这样做的作用,否则不要这样做,因为如果您不了解后果,您可能会产生比其价值更多的问题。

我只会做 ole:

插入TableB select * from TableA where (criteria)

简单示例(假设 SQL Server 2008 或更高版本)。我的坏我没有看到你没有列出 TSQL 框架。不确定这是否会在 Oracle 或 MySql 上运行。

declare @Order Table ( OrderID int identity primary key, person varchar(8));

insert into @Order values ('Brett'),('John'),('Peter');

declare @OrderItem Table (orderItemID int identity primary key, OrderID int, OrderInfo varchar(16));

insert into @OrderItem
select 
    OrderID  -- I can insert a primary key just fine
,   person + 'Stuff'
from @Order

select *
from @Order

Select *
from @OrderItem
于 2013-01-31T20:28:12.243 回答