Sql server 复制关系数据的存储过程(SQL Server 2000)

Sql server 复制关系数据的存储过程(SQL Server 2000),sql-server,tsql,sql-server-2000,Sql Server,Tsql,Sql Server 2000,我有以下表格(仅显示关键列): 订单项目订单项目文档 ======= =========== ============ ========== OrderId OrderItemId OrderItemId DocumentId --etc--OrderId DocumentId--etc-- --等-- 我正在编写一个存储过程来“克隆”订单(将现有OrderId作为参数,复制订单和所有相关项目,然后返回新的OrderId)。我被“OrderItemDoc”连接表卡住了,因为它将连接两

我有以下表格(仅显示关键列):

订单项目订单项目文档 ======= =========== ============ ========== OrderId OrderItemId OrderItemId DocumentId --etc--OrderId DocumentId--etc-- --等--
我正在编写一个存储过程来“克隆”订单(将现有OrderId作为参数,复制订单和所有相关项目,然后返回新的OrderId)。我被“OrderItemDoc”连接表卡住了,因为它将连接两组新创建的记录。我想我需要循环一个临时表,将旧ID映射到新ID。这是正确的方向吗?它正在MS-SQL 2000上运行。

是的,内存表或临时表是您的最佳选择。如果您的PK是标识列,那么您还可以根据偏移量假设ID是连续的(即,您可以假设新的OrderItemId等于现有的Max(OrderItemId)在表中+顺序中项目的相对偏移量,但我不喜欢这样做,这会让人感到痛苦,而且会深入到多个层面。)

在SQL 2005和2008中有很多有效的方法。这里有一种使用SQL2000的方法

您需要声明一个变量来保存克隆的OrderId,并创建一个临时表来保存OrderItemDoc表中的克隆记录

下面是一些关于如何实现这一点的示例代码。它依赖于顺序将旧OrderItems链接到OrderItemDoc表中的新OrderItems

CREATE PROCEDURE CloneOrder
(
  @OrderId int
)
AS
DECLARE @NewOrderId int

--create the cloned order
INSERT Order(...OrderColumnList...)
SELECT ...OrderColumnList... FROM ORDER WHERE OrderId = @OrderId;

-- Get the new OrderId
SET @NewOrderId = SCOPE_IDENTITY();

-- create the cloned OrderItems
INSERT OrderItem(OrderId,...OrderItemColumns...)
SELECT @NewOrderId, ...OrderItemColumns... 
FROM OrderItem WHERE OrderId = @OrderId

-- Now for the tricky part
-- Create a temp table to hold the OrderItemIds and DocumentIds
CREATE TABLE #TempOrderItemDocs
(
   OrderItemId int,
   DocumentId int   
)

-- Insert the DocumentIds associated with the original Order
INSERT #OrderItemDocs(DocumentId)
SELECT
    od.DocumentId
FROM
    OrderItemDoc od
    JOIN OrderItem oi ON oi.OrderItemId = od.OrderItemId
WHERE
    oi.OrderId = @OrderId
ORDER BY 
    oi.OrderItemId

-- Update the temp table to contain the newly cloned OrderItems
UPDATE #OrderItemDocs
SET 
   OrderItemId = oi.OrderItemId
FROM 
   OrderItem oi
WHERE 
   oi.OrderId = @NewOrderId
ORDER BY 
   oi.OrderItemId

-- Now to complete the Cloning process
INSERT OrderItemDoc(OrderItemId, DocumentId)
SELECT 
      OrderItemId, DocumentId
FROM 
      #TempOrderItemDocs

drats,我写了这个,然后看到你在2000年。。。(sql server 2005没有它使用的技巧…)

sql 2005中不需要循环

INSERT INTO Order        ----assuming OrderID is an identity
        VALUES ( .....)
    SELECT
        .....
    FROM Order
    WHERE OrderId=@OrderId

DECLARE @y TABLE (RowID int identity(1,1) primary key not null, OldID int, NewID int)

INSERT INTO OrderItem               ---assuming OrderItemId is an identity
        VALUES (OrderId ......)
    OUTPUT OrderItems.OrderItemId, INSERTED.tableID
    INTO @y
    SELECT
        OrderId .....
    FROM OrderItems
        WHERE OrderId=@OrderId

INSERT INTO OrderItemDoc
        VALUES (OrderItemId  ....)  ---assuming DocumentId is an identity
    SELECT
        y.NewID .....
        FROM OrderItem
            INNER JOIN @Y  y ON OrderItem.OrderItemId=y.OldId

以同样的方式编写文档,创建一个新的@temp表,等等。

PK都是自动编号标识,以前从未想过用这种方式使用它们,谢谢。从架构的外观来看,似乎不需要克隆文档表,因为OrderItemDoc是链接OrderItem和文档的多对多表。
INSERT INTO Order        ----assuming OrderID is an identity
        VALUES ( .....)
    SELECT
        .....
    FROM Order
    WHERE OrderId=@OrderId

DECLARE @y TABLE (RowID int identity(1,1) primary key not null, OldID int, NewID int)

INSERT INTO OrderItem               ---assuming OrderItemId is an identity
        VALUES (OrderId ......)
    OUTPUT OrderItems.OrderItemId, INSERTED.tableID
    INTO @y
    SELECT
        OrderId .....
    FROM OrderItems
        WHERE OrderId=@OrderId

INSERT INTO OrderItemDoc
        VALUES (OrderItemId  ....)  ---assuming DocumentId is an identity
    SELECT
        y.NewID .....
        FROM OrderItem
            INNER JOIN @Y  y ON OrderItem.OrderItemId=y.OldId