存储过程以复制关系数据(SQL Server 2000)

时间:2009-06-04 16:39:33

标签: sql-server tsql sql-server-2000

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

Order     OrderItem     OrderItemDoc   Document
=======   ===========   ============   ==========
OrderId   OrderItemId   OrderItemId    DocumentId
--etc--   OrderId       DocumentId     --etc--
          --etc--

我正在编写一个存储过程来“克隆”一个Order(将现有的OrderId作为参数,复制Order和所有相关项,然后返回新的OrderId)。我坚持使用'OrderItemDoc'连接表,因为它将连接两组新创建的记录。我想我需要循环一个临时表,将旧ID映射到新ID。这是正确的方向吗?它在MS-SQL 2000上运行。

3 个答案:

答案 0 :(得分:2)

有许多有效的方法来执行此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

答案 1 :(得分:1)

是的,内存表或临时表是您的最佳选择。如果您的PK是标识列,那么您还可以基于偏移量假设ID是连续的(即,您可以假设您的新OrderItemId等于表中的现有Max(OrderItemId)+ Item中的相对偏移量)秩序,但我不喜欢做那样的假设,它会变成一个超过一个层次的痛苦。)

答案 2 :(得分:1)

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表等...