2009-06-04 11 views
2

J'ai les tableaux ci-dessous (uniquement des colonnes clés ILLUSTRÉ):stockées proc pour copier les données relationnelles (SQL Server 2000)

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

J'écris une procédure stockée pour « clone » un ordre (prend un OrderId existant en tant que paramètre, copie l'Ordre et tous les éléments associés, puis renvoie le nouvel OrderId). Je suis bloqué sur la table de jointure 'OrderItemDoc' car elle joindra deux ensembles d'enregistrements nouvellement créés. Je pense que je vais devoir boucler une table temporaire qui mappe les anciens ID aux nouveaux. Est-ce la bonne direction à prendre? Il fonctionne sur MS-SQL 2000.

Répondre

2

Il existe de nombreux moyens efficaces de faire cela SQL 2005 et 2008. Voici une façon de le faire en utilisant SQL2000.

Vous devez déclarer une variable pour contenir le OrderId cloné et créer une table temporaire pour contenir les enregistrements clonés qui iront dans la table OrderItemDoc.

Voici un exemple de code sur la façon de procéder. Il s'appuie sur la séquence pour lier les anciens éléments de commande aux nouveaux dans la table OrderItemDoc.

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

Cela devrait faire l'affaire, merci beaucoup. – Nick

1

Oui, une table de mémoire ou une table temporaire sont les meilleures options. Si vos PK sont des colonnes d'identité, vous pouvez également supposer que les ID sont contigus en fonction d'un décalage (par exemple, vous pouvez supposer que votre nouvel OrderItemId est égal au Max (OrderItemId) existant dans la table + le décalage relatif de l'élément dans l'Ordre, mais je n'aime pas faire des suppositions comme ça et ça devient une douleur qui va plus d'un niveau profond).

+0

PKS sont toutes NuméroAuto identités, jamais pensé à les utiliser de cette façon avant, merci. – Nick

1

Zut, j'ai écrit cela, alors vous étiez vu sur 2000 ... (serveur SQL 2005 n'a pas le truc que celui-ci utilise ...)

pas de boucle nécessaire 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 

ne documentent la même façon, faire une nouvelle table de @temp, etc ...

+0

Du point de vue du schéma, il semble que la table de document n'a pas besoin d'être clonée puisque OrderItemDoc est une table plusieurs-à-plusieurs qui relie OrderItem et Document. –

+0

@KM - Merci, nous passerons bientôt à SQL2008. – Nick

Questions connexes