我需要将一个表中的内容复制到自身和相关表中......让我对问题进行模式化。假设我有两张桌子:
Order
OrderID : int
CustomerID : int
OrderName : nvarchar(32)
OrderItem
OrderItemID : int
OrderID : int
Quantity : int
PK是自动增量的。
假设我想将一个客户的内容复制到另一个客户。我该如何有效地做到这一点?
问题是PK。我需要将OrderIDs
的值从原始数据集映射到副本,以便在OrderItem
中创建正确的引用。如果我只选择-Insert,我将无法创建该地图。
建议?
答案 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)
从订单
中删除额外的帮助列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
表。