2009-06-04 14 views
2

:私は「クローン」するために、ストアドプロシージャを書いてストアドプロシージャ(SQL Server 2000の)

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

を(取ります既存のOrderIdをパラメータとして使用して、Orderおよびすべての関連アイテムをコピーし、新しいOrderIdを返します)。新しく作成されたレコードの2つのセットを結合するので、私は 'OrderItemDoc'結合テーブルについていません。私は古いIDを新しいテーブルにマッピングする一時テーブルをループする必要があると思っています。それは正しい方向ですか? MS-SQL 2000で動作しています。

答えて

2

このSQL 2005と2008を行うには、効率的な方法がたくさんあります。SQL2000を使用してこれを行う方法があります。

複製されたOrderIdを保持する変数を宣言し、OrderItemDocテーブルに入る複製されたレコードを保持する一時テーブルを作成する必要があります。

ここでは、その方法に関するサンプルコードを示します。 OrderItemDocテーブルの古いOrderItemと新しいOrderItemをリンクするためにシーケンスに依存しています。

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

これは、非常にありがとう、トリックを行う必要があります。 – Nick

1

はい、メモリテーブルまたは一時テーブルが最適です。あなたのPKがアイデンティティ列であれば、オフセットに基づいてIDが連続していると仮定することもできます(つまり、新しいOrderItemIdがテーブル内の既存のMax(OrderItemId)+ Item内の相対オフセット秩序、しかし私はそれのような前提を作るのが好きではなく、それは1つ以上の深さの痛みになります)。

+0

...など、文書を同じように行う新しい@tempテーブルを作成し、その道の前に感謝をそれらを使用する方法について考えたことはありません。 – Nick

1

drats、私は

(SQL Server 2005は、これが...使用するトリックを持っていない)...これは、あなたが2000年にあった見た、SQLに必要な一切のループを書いていません2005 ..

INSERT INTO Order  ----assuming OrderID is an identity 
     VALUES (.....) 
    SELECT 
     ..... 
    FROM Order 
    WHERE [email protected] 

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 [email protected] 

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

はPKのは、すべてのオートナンバー型のアイデンティティです

+0

スキーマの外観からは、OrderItemDocがOrderItemとDocumentをリンクする多対多の表であるため、Document Tableをクローンにする必要はありません。 –

+0

@KM - どうもありがとう、私たちはいつかすぐにSQL2008に移行します。 – Nick

関連する問題