2009-10-19 8 views
3

J'ai quatre tables: Messages, MessageCategory, MessageStatus et MessageLevel. MessageCategory, MessageStatus et MessageLevel ont tous trois champs: Identity (clé primaire), Code et Description.Insertion SQL avec des données provenant de plusieurs tables

Messages se réfère à ces trois champs et a quelques autres champs de données, y compris Identity (clé primaire) MessageText et Order. Les champs Identité sont des champs auto-incrémentés.

J'ai maintenant besoin d'écrire un script SQL pour ajouter des données par défaut aux quatre tables. Le problème est, j'ai besoin de créer un script qui sera envoyé à un client qui va ensuite exécuter ce script. Je ne peux pas écrire un code un peu plus intelligent pour faire toute la mise à jour. Et tandis que trois tables sont simplement des instructions d'insertion simples, c'est la table Messages qui me cause quelques maux de tête supplémentaires.

Je ne peux pas supprimer d'index et je ne peux pas supposer qu'il commence à compter à 1 pour les clés primaires.

Ainsi, à titre d'exemple, elle est des données:

INSERT INTO MessageCategory (Code) Values ('Cat01'); 
INSERT INTO MessageStatus (Code) Values ('Status01'); 
INSERT INTO MessageLevel (Code) Values ('Level01'); 

Et les messages aurait besoin quelque chose comme ceci:

INSERT INTO Messages(Category, Status, Level, MessageText, Order) 
VALUES(
    (SELECT Identity from MessageCategory where Code='Cat01'), 
    (SELECT Identity from MessageStatus where Code='Status01'), 
    (SELECT Identity from MessageLevel where Code='Level01'), 
    'Just some message', 
    1 
); 

Cela ne fonctionnera pas, cependant. Alors, quel est le truc pour que ça marche? (Garder le code lisible aussi ...)

Malheureusement, je n'ai pas accès à l'autre base de données. Je peux le tester, mais une fois qu'il semble fonctionner, il est juste une question d'envoi et prier-it usine ...

Répondre

6
INSERT INTO Messages 
    (Category, Status, Level, MessageText, [Order]) 
SELECT 
    (SELECT TOP 1 [Identity] from MessageCategory where Code='Cat01') AS Category, 
    (SELECT TOP 1 [Identity] from MessageStatus where Code='Status01') AS Status, 
    (SELECT TOP 1 [Identity] from MessageLevel where Code='Level01') AS Level, 
    (SELECT 'Just some message') AS MessageText, 
    (SELECT 1)      AS [Order] 

Ce qui précède travailler pour SQL Server. Notez que les codes Identity et Order sont des mots-clés T-SQL réservés et ne doivent pas être utilisés pour les noms de colonnes. Notez également que les sous-requêtes ne doivent pas renvoyer plus d'une ligne pour que cela fonctionne, pour garantir que j'ai inclus les instructions TOP 1. La chose suivante à noter est que les alias de colonne (AS Category etc.) ne sont pas strictement nécessaires. Leur commande est ce qui compte. Je les inclurais pour la lisibilité, surtout quand la liste SELECT s'allonge.

+0

J'ai tendance à toujours utiliser des crochets [] autour de tous les noms de table et sur le terrain dans mes scripts SQL. Cela résout les conflits possibles. J'ai tendance à utiliser plus de mots réservés que les noms de champs et de tables. Ajouter des parenthèses est une action automatique pour moi. :-) –

+0

Donc, vous devriez avoir fait cela dans votre code d'exemple. ainsi que. ;-) – Tomalak

+0

Oui, je m'attendais à ce que ces crochets en déroutent quelques-uns, donc je les ai effectivement supprimés. :-) –

4

Si c'est un seul script, stocker vos identités dans les variables:

declare MessageCategoryID int; 
declare MessageStatusID int; 
declare MessageLevel int; 
INSERT INTO MessageCategory (Code) Values ('Cat01'); 
set @MessageCategoryID=scope_identity(); 
INSERT INTO MessageStatus (Code) Values ('Status01'); 
set @MessageStatudID=scope_identity(); 
INSERT INTO MessageLevel (Code) Values ('Level01'); 
set @MessageLevelID=scope_identity(); 

INSERT INTO Messages(Category, Status, Level, MessageText, Order) 
    VALUES(
     @MessageCAtegoryID, 
     @MessageStatusID, 
     @MessageLevelID, 
     'Just some message', 
     1); 
+0

Il s'agit d'un script unique mais il y aura plusieurs dizaines d'enregistrements dans la table Messages. –

+4

N'utilisez jamais @@ identity use scope_identity à la place. L'identité @@ peut provoquer des problèmes majeurs d'intégrité des données si un déclencheur est ajouté à votre table. – HLGEM

+0

Jamais utilisé scope_identity(), mais à partir de maintenant.Merci pour le conseil! – Kendrick

Questions connexes