2009-12-29 5 views
1

Je suis nouveau à la conception de ma propre base de données. Mon projet est des commandes/produits/données de type inventaire, en utilisant SQL Server 2005. Au cours de ma lecture, j'ai rencontré plusieurs exemples de type client/commande, et j'ai décidé d'utiliser linking-table (parfois appelé junction ou join table). Order_Details depuis que j'ai eu de nombreuses relations entre ORDERS et PRODUCTS.Comment faire pour INSERT/UPDATE à Linking (Join) table qui a des FK à PK d'identité

Le problème est, je ne suis pas sûr quelle structure ou syntaxe T-SQL je peux utiliser pour insérer/mettre à jour cette ORDER_DETAILS-table de liaison. Les exemples donnent l'impression que vous stockez les détails de la commande séparément, mais je ne sais pas comment les synchroniser avec les tables Orders et Products. J'imaginais une sorte de vue qui les aurait tous réunis, où une mise à jour écrirait à toutes les trois tables, mais j'ai trouvé qu'une vue est seulement autorisée à mettre à jour une table à la fois. J'ai essayé une "solution de contournement" en utilisant un déclencheur "Au lieu de" sur la vue, mais je ne peux pas comprendre comment écrire les instructions INSERT dans le déclencheur, puisque les valeurs FK que je dois insérer dans la table de liaison sont les PK IDENTITY à partir des tables parent, sont donc inconnues à l'avance.

Ensuite, je pensais que ce serait un cas de mettre à jour CASCADE sur les FK à la table de liaison, et juste exécuter mes INSERTS là, mais il semble encore très confus. J'ai acheté un livre et passé beaucoup de temps à apprendre à concevoir une base de données normalisée, mais maintenant je n'arrive pas à comprendre comment y insérer des données. Mon plan est d'écrire plus tard une application VB.NET 2005 avec des DatagridViews, etc. où l'utilisateur peut créer des commandes, mettre à jour des produits, etc. Je suis beaucoup mieux avec les applications, mais cette fois je pensais que je préfèrerais apprendre pour concevoir une base de données appropriée, puis créer des vues qui pourraient simplement être connectées aux contrôles d'application, c.-à-d. laisser SQL faire la plupart du travail. Quelqu'un peut-il faire la lumière sur le JOIN/UPDATE/SPROC/VIEW qui est nécessaire pour maintenir ces tables de liaison? Merci.

Pour expliquer la mise en page, voici quelques détails du schéma:

ORDERS 
---------------- 
OrderID PK 
OrderDate 
EmployeeID fk 
CostCenterID fk 
etc. 


ORDER_DETAILS 
----------------------- 
OrderID CPK/fk 
ProductID CPK/fk 
Qty 
OrderDetailComment 


PRODUCTS 
--------------------- 
ProductID PK 
PartNumber 
ProductName 
etc. 

Voici la définition actuelle de la table de liaison:

CREATE TABLE [Order_Details] (
    [OrderID] INTEGER NOT NULL, 
    [ProductID] INTEGER NOT NULL,  
    [Qty] INTEGER NOT NULL, 
    [OrderDetailComment] VARCHAR(100), 
    CONSTRAINT [CPK_Order_Details] PRIMARY KEY ([OrderID],[ProductID]), 
    CONSTRAINT [Order_Details_Orders] FOREIGN KEY ([OrderID]) REFERENCES [Orders] ([OrderID]), 
    CONSTRAINT [Order_Details_Products] FOREIGN KEY ([ProductID]) REFERENCES [Products] ([ProductID])  
) 
GO 

Répondre

1

Quel type de technologie d'accès client/base de données avez-vous planifier d'utiliser?

Si vous utilisez quelque chose comme Linq-to-SQL ou Entity Framework, vous n'aurez même pas à vous soucier de ces questions - tout est gentiment géré pour vous.

Fondamentalement, les étapes doivent être:

  • insérer l'ordre et obtenir le numéro de commande arrière - nombre de façons de le faire
  • insérer alors tous les détails de la commande, supposant que vous avez l'identifiant de produits de , et maintenant vous avez aussi le numéro de commande

Pour enregistrer la commande, vous pouvez:

  • utilisation comme procédure Tored qui renvoie la OrderID nouvellement créée (utilisez la clause « sortie » sur votre instruction INSERT ou consultez SCOPE_IDENTITY())
  • créer une instruction SQL en ligne qui fait l'une des choses ci-dessus

Alors, utilisez quelque chose comme (comme SQL en ligne directe, ou enveloppé dans une procédure stockée - votre choix):

INSERT INTO dbo.Orders(OrderDate, EmployeeID, CostCenterID) 
OUTPUT Inserted.OrderID 
VALUES (........) 

ou tout simplement faire

INSERT INTO dbo.Orders(OrderDate, EmployeeID, CostCenterID) 
VALUES (........) 

DECLARE @NewOrderID INT 
SET @NewOrderID = SCOPE_IDENTITY() 

Cela aide-t-il?

MISE À JOUR:
Si vous voulez utiliser l'ID nouvellement inséré dans le code T-SQL suivante, votre meilleure option est de les stocker dans une variable de table en mémoire - quelque chose comme ceci:

DECLARE @NewOrderIDs TABLE (NewOrderID INT) 

INSERT INTO dbo.Orders(OrderDate, EmployeeID, CostCenterID) 
OUTPUT INSERTED.OrderID INTO @NewOrderIDs 
VALUES (..........) 

INSERT INTO dbo.Orders(OrderDate, EmployeeID, CostCenterID) 
OUTPUT INSERTED.OrderID INTO @NewOrderIDs 
VALUES (..........) 

INSERT INTO dbo.Orders(OrderDate, EmployeeID, CostCenterID) 
OUTPUT INSERTED.OrderID INTO @NewOrderIDs 
VALUES (..........) 

SELECT * FROM @NewOrderIDs 

Si vous souhaitez insérer un seul ordre, obtient son nouveau OrderID, puis continuer d'insérer les détails de la commande, en utilisant la SCOPE_IDENTITY() pourrait être plus facile:

INSERT INTO dbo.Orders(OrderDate, EmployeeID, CostCenterID) 
VALUES (..........) 

DECLARE @NewOrderID INT 
SET @NewOrderID = SCOPE_IDENTITY() 

INSERT INTO dbo.OrderDetails(.....) 
........ 
+0

Il ne me aide. Au moins, vous avez précisé que cela doit être fait en deux étapes distinctes. Je ne suis pas familier avec le mot-clé OUTPUT là. Pouvez-vous montrer un exemple en SQL de la façon d'accéder à cette valeur dans le code SQL suivant? Merci. –

+0

Merci pour l'exemple OUTPUT. Je suis allé de l'avant et fait une procédure stockée qui accepte tous les paramètres à la fois pour le parent et la table de liaison, et il effectue les deux insertions. J'ai utilisé SCOPE_IDENTITY(), et cela semble fonctionner correctement. Si j'ai besoin d'en insérer plus d'un à la fois, j'essaierai d'utiliser OUTPUT. Encore une fois, merci. –

Questions connexes