2010-07-05 6 views
4

Pourquoi cet insert ne reçoit pas compilé: -s'insère pas compilé

INSERT INTO dbo.UserGroupsToUsers 
         (UserID , 
          LastUpdated , 
          ID , 
          UserGroupID 
         ) 
         SELECT @MergeToUserID , 
           GETDATE() , 
           MAX(ID) + 1 , 
           UserGroupID 
         FROM dbo.UserGroupsToUsers 
         WHERE UserID = @MergeFromUserID 

Erreur: La colonne « dbo.UserGroupsToUsers.UserGroupID » est invalide dans la liste de sélection, car il ne figure pas dans une fonction d'agrégation et il n'est pas une clause GROUP BY.

Répondre

3

Vous devez créer votre champ ID dans un IDENTITY (champ auto-incrémenté) et l'omettre de la requête.

Si vous ne pouvez pas changer la base de données, vous pouvez essayer ceci:

INSERT INTO dbo.UserGroupsToUsers 
       (UserID , 
        LastUpdated , 
        ID , 
        UserGroupID 
       ) 
       SELECT @MergeToUserID , 
         GETDATE() , 
         (SELECT MAX(ID) + 1 FROM dbo.UserGroupsToUsers), 
         UserGroupID 
       FROM dbo.UserGroupsToUsers 
       WHERE UserID = @MergeFromUserID 

Important: Cela suppose qu'une seule ligne sera retourné. L'insertion échouera par conception si votre sous-requête renvoie plus d'une ligne et ID est une clé primaire ou a une contrainte unique.

+0

Oui, c'est une réponse spécifique à la façon de rendre cette requête correcte. – AlexanderMP

+0

La base de données est déjà conçue comme ça ... ce n'est pas dans mes mains..tout le problème n'est pas avec l'identité, l'erreur est quelque chose d'autre..je ne suis pas capable de comprendre .. J'ai déjà lancé ce genre de requêtes. – teenup

+0

Vérifiez mon commentaire mis à jour dans ce cas. – AlexanderMP

3

MAX(ID) est une fonction d'agrégat. Comme toutes les fonctions agrégées, il faut regrouper sur le reste des champs. Après la clause WHERE, ajoutez une clause group by sur tous les autres champs (alias).

Ceci est général, mais pour ce cas, utilisez la solution Mark Byers.

Une autre idée est de ne pas faire MAX(), mais plutôt comme ceci:

INSERT INTO dbo.UserGroupsToUsers 
         (UserID , 
          LastUpdated , 
          ID , 
          UserGroupID 
         ) 
         SELECT TOP 1 @MergeToUserID , 
           GETDATE() , 
           ID +1, 
           (SELECT UserGroupID FROM dbo.UserGroupsToUsers WHERE UserID = @MergeFromUserID) 
         FROM dbo.UserGroupsToUsers 
         ORDER BY ID DESC 
+0

Cela ne retournera pas la valeur de l'ID comme (Max + 1), une solution précédente postée utilisait la sous-requête pour ID comme (Sélectionnez max (ID) +1 de la table) et c'était correct. Je voulais accepter cette solution mais maintenant ce n'est pas là. – teenup

+0

Il le fera. Commandez-le par ID descendant, prenez le top 1, c'est MAX. Puis ajoutez 1. C'est ce que j'ai écrit. Et comme je l'ai mentionné, obtenez la valeur UserGroupID dans une requête distincte. Peu importe de quelle façon vous allez, il doit juste être une autre requête pour l'une de ces tâches. – AlexanderMP

+0

Hmm effectivement cela ne fonctionne pas, je pense à cause de la clause WHERE ... –

0

Vous utilisez un MAX(ID), cela signifie que la requête utilise le regroupement. Mais vous n'utilisez pas une fonction d'agrégat sur UserGroupID, donc SQL ne sait pas quelle valeur choisir parmi les valeurs (possibles).

Probablement il n'y a qu'une seule valeur, et vous le savez, mais le compilateur SQL ne le sait pas.

Mieux vaut envelopper UserGroupID également dans un MAX, MIN, ou une autre fonction d'agrégation.

Questions connexes