2013-02-14 1 views
1

Pour la requête suivante:Existe-t-il un moyen d'inclure une requête qui ne peut pas être mise à jour dans une requête UPDATE?

UPDATE tempSpring_ASN AS t 
SET t.RECORD_TYPE = (
     SELECT TOP 1 RECORD_TYPE 
     FROM (
      SELECT "A" AS RECORD_TYPE 
      FROM TABLE5 
      UNION ALL 
      SELECT "B" AS RECORD_TYPE 
      FROM TABLE5 
      ) 
     ); 

Je reçois, « L'opération doit utiliser une requête actualisable. » Je ne comprends pas. Je n'essaie pas de mettre à jour une requête d'union. J'essaie juste de mettre à jour un jeu d'enregistrements autrement modifiable avec la sortie (valeur unique) d'une requête d'union.

(La solution fournie à Access SQL Update One Table In Join Based on Value in Same Table (qui est également fournie ci-dessous) ne fonctionne pas de cette situation, contrairement à ce qui est indiqué sur le haut de cette page.)

+0

@invertedSpear, ce n'est pas un _possible_ duplicate. Je l'ai moi-même référencé. Je l'ai fait pour le rendre plus facile à suivre pour les gens. :-) – as9876

+0

Il est marqué comme tel parce que le dépassement de pile n'a pas l'intention d'être un forum avec des liens vers des questions précédentes. Si votre question est différente, c'est une chose, mais si vous fournissez simplement des détails ou des clarifications supplémentaires, comme vous semblez le faire ici, vous devriez apporter des modifications à la question originale. Le fait est que la recherche sur le Web devrait faire apparaître une question, pas une question qui nécessite des liens vers d'autres questions afin de comprendre ce qui se passe. Il ne s'agit pas seulement de vous aider, mais d'aider quelqu'un qui a un problème similaire dans le futur. – invertedSpear

+0

@invertedSpear, on dirait que vous prétendez que je l'ai divisé en 2 threads pour le rendre plus facile pour moi, au détriment de tout le monde utilisant SO. Ironiquement, c'est juste le contraire! Il aurait été plus facile pour moi d'avoir un seul fil, mais j'ai spécifiquement créé un nouveau fil pour le rendre plus facile pour tout le monde. Dans ma situation particulière, il y avait un seul but derrière les deux questions, mais en réalité, les deux questions peuvent fonctionner indépendamment les unes des autres. La réponse de JAGAnalyst en fait, seulement répondu à l'autre poste, pas celui-ci. – as9876

Répondre

2

Cette question est une référence à une question précédente , des exemples de données et le code affiché ici:

Access SQL Update One Table In Join Based on Value in Same Table

Salut AYS,

Dans Access, doit être exécuter une requête de mise à jour sur une table. Comme une requête UNION est une combinaison de plusieurs ensembles d'enregistrements, le jeu de résultats n'est plus une table et ne peut pas faire l'objet d'une requête de mise à jour car les enregistrements du jeu de résultats ne sont plus identifiés même s'ils peuvent théoriquement être). Access est codé en dur pour traiter chaque requête UNION en lecture seule, ce qui est logique lorsqu'il existe plusieurs tables sous-jacentes. Il existe un certain nombre d'autres conditions (telles qu'une sous-requête dans l'instruction SELECT) qui déclenchent également cette condition. Pensez de cette façon: si vous n'utilisiez pas TOP 1 et que votre requête UNION renvoyait plusieurs résultats, comment JET connaîtrait-il le résultat à appliquer à l'enregistrement unique de votre table? En tant que tel, JET traite tous ces cas de la même manière.

Malheureusement, c'est le cas même lorsque toutes les données sont dérivées de la même table. Dans ce cas, il est probable que l'optimiseur JET n'est simplement pas assez intelligent pour réaliser que c'est le cas et reformuler la requête d'une manière qui n'utilise pas UNION.

Dans ce cas, vous pouvez toujours obtenir ce que vous voulez en reformulant votre requête de manière à ce que tout soit référencé par votre table de base. Par exemple, vous pouvez utiliser ce qui suit comme une requête SELECT pour obtenir la valeur de PO_NUM du précédent record de SHP_CUSTOM_5:

SELECT 
t1.SHP_CUSTOM_5 
, t1.PO_NUM 
, t1.SHP_CUSTOM_5 -1 AS PREV_RECORD 

, (SELECT 
t2.PO_NUM 
FROM 
tempSpring_ASN As t2 
WHERE 
t2.SHP_CUSTOM_5 = (t1.SHP_CUSTOM_5 -1) 
) AS PREV_PO 

FROM 
tempSpring_ASN AS t1 
; 

Vous pouvez ensuite phrase cela comme une requête de mise à jour comme suit afin d'effectuer les mises à jour « LIN » :

UPDATE 
tempSpring_ASN AS t1 

SET 
t1.RECORD_TYPE = "LIN" 

WHERE 
t1.PO_NUM= 

(
SELECT 
t2.PO_NUM 

FROM 
tempSpring_ASN As t2 

WHERE 
t2.SHP_CUSTOM_5 = (t1.SHP_CUSTOM_5 -1) 
) 
; 

Ce code a réussi dans les tests que j'ai exécutés avec des données factices. En ce qui concerne vos mises à jour "HDR", vous effectuez réellement deux mises à jour distinctes. 1) Si le PO_NUM correspond à la précédente de PO_NUM de disque, mis record_type à « LIN » 2) Si elle est le premier enregistrement, mis record_type à « HDR »

Il est pas clair pour moi pourquoi il y aurait un avantage à effectuer ces actions dans une requête. Je recommande d'effectuer la mise à jour HDR en utilisant la méthode SHP_CUSTOM_5 "TOP 1" que vous avez utilisée dans votre exemple de requête SELECT d'origine, car il s'agira d'une requête UPDATE relativement simple. Il est possible d'utiliser IIF() dans une requête de mise à jour, mais je ne sais pas quel avantage supplémentaire vous gagneriez du temps et de la complexité supplémentaires qui seraient nécessaires (il serait très probablement beaucoup moins lisible).

Bonne chance!

+0

Il n'y a rien "faux" avec votre requête. L'accès dit simplement que vous ne pouvez pas, alors vous ne pouvez pas. – JAGAnalyst

Questions connexes