Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
复制TSQL中的内容_Tsql - Fatal编程技术网

复制TSQL中的内容

复制TSQL中的内容,tsql,Tsql,我需要将内容从一个表复制到自身和相关表。。。让我来计划一下这个问题。假设我有两张桌子: Order OrderID : int CustomerID : int OrderName : nvarchar(32) OrderItem OrderItemID : int OrderID : int Quantity : int PK是自动递增的 假设我想将一个客户的内容复制到另一个客户。我如何有效地做到这一点 问题在于PKs。我需要将OrderIDs的值从原始数据集映射到副本,以便在OrderI

我需要将内容从一个表复制到自身和相关表。。。让我来计划一下这个问题。假设我有两张桌子:

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

OrderItem
OrderItemID : int
OrderID : int
Quantity : int
PK是自动递增的

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

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


建议?

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

您可以为插入到其他表中选择主键,但不能选择主键本身。。。。除非您设置了“标识插入打开”提示。除非你知道这会造成什么,否则不要这样做,因为如果你不理解其后果,你可能会制造更多的问题

我只想做ole:

插入表B 挑选* 从表格 其中(标准)

简单示例(假设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
  • 向Order添加一个名为OldOrderID的额外帮助器列
  • 将所有订单从@OldCustomerID复制到@NewCustomerID
  • 使用OldOrderID列复制所有OrderItems以帮助建立关系
  • 从订单中删除额外的帮助器列

    ALTER TABLE Order ADD OldOrderID INT NULL

    插入订单(CustomerID、OrderName、OldOrderID) 选择@NewCustomerID、OrderName、OrderID 从命 其中CustomerID=@OldCustomerID

    插入到OrderItem(OrderID、数量) 选择o.OrderID,即数量 从订单o内部连接o.OldOrderID=i.OrderID上的OrderItem i 其中o.CustomerID=@NewCustomerID

    更新订单集OldOrderID=null,其中OldOrderID不为null

    ALTER TABLE Order DROP列OldOrderID

如果每个客户的订单名都是唯一的,您只需执行以下操作:

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建议的那样。

对于复制一个父级和多个以身份为键的子级,我认为该子句可以使事情变得非常干净():


您可以使用temp table和store proc来解决此问题。SQL Server/Sybase的哪个版本?每个客户的订单名是唯一的吗?那么,一个客户是否有过多个相同订单名的订单?宾果!这就是我正在寻找的动态构建映射的方法。以前从未听说过这个“输出子句”。也从未见过SQL小提琴!谢谢很高兴听到这个消息。请向上投票和/或标记为答案,以帮助未来的访客。另外,@MikaelEriksson与多位家长有着很好的联系。我忘了提到这不是一次性的,而是应用程序中的“正常”(虽然有点罕见)事件。我可以把这个列留在那里,但它在模式上有点争议。@Vincent Philippe Lauzon-答案中的代码删除了额外的列。您可以使用临时表而不是更改表,但这是最简单的解决方案。
-- 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