在SQL中复制内容

时间:2013-01-31 20:12:52

标签: tsql

我需要将一个表中的内容复制到自身和相关表中......让我对问题进行模式化。假设我有两张桌子:

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

OrderItem
OrderItemID : int
OrderID : int
Quantity : int

PK是自动增量的。

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

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

建议?

4 个答案:

答案 0 :(得分:1)

为了复制一个父级和许多具有身份的子级作为键,我认为OUTPUT子句可以使事情变得非常干净( SqlFiddle here ):

-- 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

答案 1 :(得分:0)

您是否必须将表A中的主键作为表B中的原色?如果不是,您可以执行带有插入的select语句。主键通常是从不断增长的种子(身份)开始的int。绕过这个并声明插入这些相同数据有问题的缺点是有人认为这是该表上的一个独特的键集,而不是“关系”或外键值。

您可以选择主键以插入其他表,而不是自己....除非您设置'标识插入'提示。除非你知道这样做,否则不要这样做,因为如果你不理解其后果,你可以创造更多的问题。

我会做的就是:

插入TableB 选择 * 来自TableA 其中(标准)

简单示例(假定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

答案 2 :(得分:0)

  • 向Order调用OldOrderID
  • 添加一个额外的帮助列
  • 将所有订单从@OldCustomerID复制到@NewCustomerID
  • 使用OldOrderID列复制所有OrderItem以帮助建立关系
  • 从订单

    中删除额外的帮助列

    ALTER TABLE命令ADD OldOrderID INT NULL

    INSERT INTO Order(CustomerID,OrderName,OldOrderID)  SELECT @NewCustomerID,OrderName,OrderID  来自订单  WHERE CustomerID = @OldCustomerID

    INSERT INTO OrderItem(OrderID,Quantity)  SELECT o.OrderID,i.Quantity  FROM订单o INNER JOIN OrderItem i ON o.OldOrderID = i.OrderID  在哪里o.CustomerID = @NewCustomerID

    UPDATE Order SET OldOrderID = null WHERE OldOrderID IS NOT NULL

    ALTER TABLE命令DROP COLUMN OldOrderID

答案 3 :(得分:0)

IF 每位客户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

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