2010-04-04 3 views
2

J'apprécierais de l'aide avec une instruction SQL Je ne peux vraiment pas comprendre. Ce que je veux faire est assez simple, j'ai besoin de prendre les valeurs de deux tables différentes et de les copier dans une table maître lorsqu'une nouvelle ligne est insérée dans l'une des deux tables.SQL: Comment puis-je INSERT des valeurs de clé primaire à partir de deux tables INTO une table principale

Le problème est peut-être mieux expliqué comme ceci:

J'ai trois tables, et regioncategories, catégories de produit MasterTable.

  --------------------------- 
TABLE: PRODUCTCATEGORIES 
     --------------------------- 
COLUMNS: CODE  | DESCRIPTION 
     --------------------------- 
VALUES: BOOKS  | Books 
     --------------------------- 

     --------------------------- 
TABLE: REGIONCATEGORIES 
     --------------------------- 
COLUMNS: CODE  | DESCRIPTION 
     --------------------------- 
VALUES: EU   | European Union 
     --------------------------- 

     ------------------------------------------ 
TABLE: MASTERTABLE 
     ------------------------------------------ 
COLUMNS: REGION  | PRODUCT  | ACCOUNT 
     ------------------------------------------ 
VALUES: EU   | BOOKS   | NULL 
     ------------------------------------------ 

Je souhaite que les valeurs soient insérées de la sorte lorsqu'une nouvelle ligne est créée dans des catégories de produits ou des catégories de régions.

Une nouvelle ligne est créée.

  --------------------------- 
TABLE: PRODUCTCATEGORIES 
     --------------------------- 
COLUMNS: CODE  | DESCRIPTION 
     --------------------------- 
VALUES: BOOKS  | Books 
     --------------------------- 
VALUES: DVD  | DVDs 
     --------------------------- 

Et une instruction SQL copie les nouvelles valeurs dans la table principale.

  ------------------------------------------ 
TABLE: MASTERTABLE 
     ------------------------------------------ 
COLUMNS: REGION  | PRODUCT  | ACCOUNT 
     ------------------------------------------ 
VALUES: EU   | BOOKS  | NULL 
     ------------------------------------------ 
VALUES: EU   | DVD   | NULL 
     ------------------------------------------ 

Il en va de même si une ligne est créée dans les catégories de régions.

Nouvelle rangée.

  --------------------------- 
TABLE: REGIONCATEGORIES 
     --------------------------- 
COLUMNS: CODE  | DESCRIPTION 
     --------------------------- 
VALUES: EU   | European Union 
     --------------------------- 
VALUES: US   | United States 
     --------------------------- 

Copié dans la table principale.

  ------------------------------------------ 
TABLE: MASTERTABLE 
     ------------------------------------------ 
COLUMNS: REGION  | PRODUCT  | ACCOUNT 
     ------------------------------------------ 
VALUES: EU   | BOOKS   | NULL 
     ------------------------------------------ 
VALUES: EU   | DVD   | NULL 
     ------------------------------------------ 
VALUES: US   | BOOKS   | NULL 
     ------------------------------------------ 
VALUES: US   | DVD   | NULL 
     ------------------------------------------ 

J'espère que cela a du sens.

Merci,

Stefan

+0

Quelle SGBDR utilisez-vous? – Quassnoi

+0

Microsoft SQL Server – unitario

Répondre

0

Très bien, merci pour vos réponses et suggestions.

Je travaille avec un projet d'accès connecté à la base de données MsSQL. J'ai essayé de résoudre ceci en utilisant un déclencheur de table, mais aucune des suggestions n'a fait l'affaire pour moi. Par conséquent j'ai décidé de résoudre ceci du côté de client avec le code de VBA à la place.

Ce n'est probablement pas la bonne façon de le résoudre, mais il peut être utile de le savoir pour quiconque lit.

La structure de la table est la même, mais j'ai fait un formulaire correspondant à la fois pour le produit et la table de la région. Sur les formes AfterInsert événement je le code suivant:

Table Région:

Private Sub Form_AfterInsert() 

Dim varRegion As String 
Dim strSQL As String 

varRegion = Me![code] 
strSQL = "INSERT INTO master([region], [product]) SELECT '" & varRegion & "', & _ 
      [code] FROM product;" 

    DoCmd.RunSQL strSQL 

End Sub 

table de produit:

Private Sub Form_AfterInsert() 

Dim varProduct As String 
Dim strSQL As String 

varProduct = Me![code] 
strSQL = "INSERT INTO master([region], [product]) SELECT [code], & _ 
      '" & varProduct & "' FROM region;" 

    DoCmd.RunSQL strSQL 

End Sub 

EDIT: recherche que la question soit un peu plus, j'ai trouvé que c'est le code que vous devez utiliser pour le déclencheur si vous utilisez SQL Server, si vous ne souhaitez pas utiliser la configuration côté client.

Apparemment, dans SQL Server, vous devez référencer une table cachée appelée "inserted" lorsque vous souhaitez obtenir les valeurs de la ligne insérée. Voir ce lien pour plus d'informations: Multirow Considerations for DML Triggers

Great!

table de produit:

-- Trigger statement 
CREATE TRIGGER "name-of-trigger" 
ON producttable 
FOR INSERT AS 

    -- Insert statement 
INSERT INTO mastertable ([region],[product]) 
SELECT regiontable.[code], inserted.[code] 
FROM regiontable, inserted; 

table Région:

-- Trigger statement 
CREATE TRIGGER "name-of-trigger" 
ON regiontable 
FOR INSERT AS 

    -- Insert statement 
INSERT INTO mastertable ([product],[region]) 
SELECT producttable.[code], inserted.[code] 
FROM producttable, inserted; 
1

Il existe deux manières d'insérer les informations supplémentaires dans le MasterTable.

  1. Utilisation déclenche - quand un insert se produit en catégories de produit ou REGIONCATEGORIES, un feu de déclenchement d'insertion et vérifie si la rangée existe dans le MasterTable. Sinon, il est ajouté.

  2. Créez une procédure stockée pour insérer des données dans la table PRODUCTCATEGORIES et REGIONCATEGORIES. La procédure stockée est alors chargée de vérifier le MASTERTABLE et de l'insérer si nécessaire.

La 2ème approche a l'avantage qu'il est évident pour quelqu'un d'autre de maintenir votre code. Les déclencheurs peuvent cacher des fonctionnalités importantes. Les procédures stockées sont généralement préférées pour transact SQL pour des raisons de performances.

+0

Wow - C'était rapide. D'accord, créer une procédure stockée semble être la voie à suivre. Cependant, je suis un peu perplexe de la façon dont la déclaration SQL devrait ressembler, tout point dans la bonne direction serait très apprécié. – unitario

2

Vous pouvez facilement construire votre « table maître » dans l'exécution:

SELECT * 
FROM regiontable 
CROSS JOIN 
     producttable 

Il sera plus efficace, puisque, contrairement à la table principale matérialisée, les deux tables seront probablement entrer dans le cache.

Si pour une raison quelconque, vous aurez besoin de l'avoir matérialisée, puis il suffit d'écrire les déclencheurs sur les deux tables:

INSERT 
INTO mastertable 
SELECT r.code, NEW.code 
FROM regiontable t 

sur mastertable et

INSERT 
INTO mastertable 
SELECT NEW.code, p.code 
FROM producttable p 

sur producttable.

+0

J'ai trouvé que ".NEW" est une fonction que MsSQL ne comprend pas (contrairement à Oracle), donc je n'ai pas réussi à faire ce travail, cependant je l'ai résolu en déclarant une variable et en exécutant le SQL dans VBA comme indiqué ci-dessous . – unitario

1

Votre table principale semble être une jointure croisée de toutes les combinaisons potentielles. Ainsi, lorsque vous ajoutez une nouvelle région, vous devez ajouter tous les produits potentiels dans cette région. Cela représente beaucoup d'efforts pour les données qui peuvent simplement être déduites de toutes les régions potentielles et de toutes les catégories potentielles.

Je sais que vous mentionnez qu'il existe des colonnes supplémentaires. Que contiennent ces colonnes supplémentaires? En général, je ne conserverais pas une telle table dans une base de données normalisée - à moins que les colonnes supplémentaires auxquelles vous faites allusion n'aient besoin d'être affectées d'une manière particulière à la création et ensuite modifiées dans une sorte de maintenance - même dans ce cas, une table clairsemée (c'est-à-dire seulement des écarts par rapport aux valeurs par défaut) avec les valeurs par défaut appropriées peut bien fonctionner. J'ai une jointure croisée similaire dans l'un de mes systèmes et il contient environ 25m lignes et nous permet de remplacer la logique très complexe sur un grand-livre 2-Dimensional 2500 comptes x 10000 centres de coûts espace où il y a des «lignes» et des "colonnes" de logique identique, mais des "îlots" de logique.

+0

Salut - peut-être que je devrais expliquer un peu plus sur mes intentions avec cette configuration particulière. J'ai besoin de la table principale pour contenir toutes les variations possibles parce que je veux assigner une valeur à chacun d'eux manuellement plus tard. La valeur représente un compte de vente qui doit être utilisé lorsqu'une commande est enregistrée dans le système. Disons que nous avons un client des États-Unis qui achète un LIVRE, je voudrais que l'utilisateur puisse le configurer dans le système afin que la commande soit enregistrée dans 3030, qui est le compte de vente international. – unitario

+0

@Stefan: pourquoi ne pas insérer un enregistrement seulement quand vous voulez assigner une valeur? – Quassnoi

+0

@Quassnoi: Question valide. Le système ne permet pas qu'une variation soit omise. C'est-à-dire que si vous ajoutez une nouvelle catégorie de produit ou une catégorie de région, vous devrez entrer une valeur pour chaque nouvelle variation. – unitario