2009-09-03 8 views
13

Je souhaite transférer cette requête SQL, qui fonctionne parfaitement sur SQL Server, MySQL et Oracle, vers une base de données Access. Comment je fais ça? À l'heure actuelle, cela m'incite à créer un ID_entreprise pour une raison quelconque.Comment effectuer une requête de mise à jour avec sous-requête dans Access?

Modifier: J'ai reçu l'invite car j'ai oublié de créer d'abord la colonne Company_ID dans VendorRegKeys. Maintenant, je reçois une erreur "Opération doit utiliser une requête pouvant être mise à jour".

UPDATE VendorRegKeys 
    SET Company_ID = (SELECT Users.Company_ID 
        FROM Users 
        WHERE Users.User_ID = VendorRegKeys.CreatedBy_ID) 

Mise à jour: Je trouve que cela fonctionne basé sur la réponse de JuniorFlip:

UPDATE VendorRegKeys, Users 
SET VendorRegKeys.Company_ID = Users.Company_ID 
WHERE VendorRegKeys.CreatedBy_ID = Users.User_ID 
+0

Merci, cela m'a beaucoup aidé! –

+0

Remarque: Si les utilisateurs sont une requête par opposition à une table et ne peuvent donc pas être mis à jour, le résultat est "L'opération doit utiliser une requête pouvant être mise à jour". –

Répondre

11

Ce pourrait être parce que Company_id n'est pas un champ existant dans VendorRegKeys ou les utilisateurs.

EDIT:

UPDATE VendorRegKeys 
INNER JOIN Users ON Users.User_ID = VendorRegKeys.CreatedBy_ID 
SET VendorRegKeys.Company_ID = Users.Company_ID 
+0

oops, ID_entreprise n'existait pas dans VendorRegKeys. Mais après l'avoir ajouté, je reçois maintenant "Opération doit utiliser une requête modifiable" – Kip

+0

n'a pas vu que vous aviez édité dans une requête qui fonctionne ... acceptant votre réponse, car il fonctionne réellement. Merci! – Kip

8

vous pouvez essayer celui

update a 
set a.company_id = b.company_id 
from vendorRegkeys a, users b 
where a.createdby_id = b.user_id 
+1

hmm .. qui donne l'erreur: erreur de syntaxe (opérateur manquant) dans l'expression de la requête 'b.company_id de vendorRegkeys un' – Kip

+1

je l'ai eu pour travailler avec une version légèrement modifiée de ce, mis à jour dans la question. Merci! – Kip

8

réponse claire: vous ne pouvez pas. Le moteur de base de données Access simple ne prend pas en charge la syntaxe sous-requête scalaire SQL-92 vanille, même dans son propre mode de requête ANSI-92.

Vous devez utiliser sa propre syntaxe propriétaire qui n'applique pas l'exigence scalaire, c'est-à-dire qui n'est pas sûre, et qui choisit une valeur arbitrairement et silencieusement **. En outre, au-delà des constructions simples cela ne fonctionne pas du tout, notamment lorsque votre sous-requête (si vous pouviez en utiliser une en premier lieu) utilise une fonction set (MAX, SUM, etc) - voir this article pour des solutions de contournement vraiment insatisfaisantes .

Désolé d'être négatif mais c'est une syntaxe vraiment basique et je ne comprends pas pourquoi l'équipe d'Access n'a pas encore réussi à la réparer. C'est la raison numéro un incontestée pour laquelle je ne peux plus prendre le moteur de base de données Access au sérieux.


Pour démontrer le comportement dangereux de la syntaxe d'accès exclusif UPDATE..JOIN..Set

CREATE TABLE Users 
( 
    User_ID CHAR(3) NOT NULL, 
    Company_ID CHAR(4) NOT NULL, 
    UNIQUE (Company_ID, User_ID)); 

CREATE TABLE VendorRegKeys 
    CreatedBy_ID CHAR(3) NOT NULL UNIQUE, 
    Company_ID CHAR(4)); 

INSERT INTO Users VALUES ('Kip', 'MSFT'); 
INSERT INTO Users VALUES ('Kip', 'AAPL'); 

INSERT INTO VendorRegKeys VALUES ('Kip', NULL); 

UPDATE VendorRegKeys 
INNER JOIN Users ON Users.User_ID = VendorRegKeys.CreatedBy_ID 
SET VendorRegKeys.Company_ID = Users.Company_ID; 

Lors de l'exécution de la déclaration de mise à jour dans Access, l'interface utilisateur met en garde contre nous

You are about to update 2 row(s).

malgré le fait qu'il est seulement une rangée dans la table VendorRegKeys! Ce qui se passe en pratique est juste une des valeurs que nous utiliserons pour mettre à jour la colonne dans cette seule ligne, sans un moyen fiable de prédire ce qu'elle sera. Avec la syntaxe de sous-requête scalaire de Standard SQL, vous obtiendriez une erreur et l'instruction échouerait à s'exécuter, ce qui est sans doute la fonctionnalité souhaitée (la syntaxe MERGE du standard SQL se comporte également de cette manière).

+1

merci pour toutes les infos. Je n'ai jamais pris l'accès au sérieux, mais la direction dit que nous devons le soutenir de toute façon. : -/Au moins dans ce cas, il existe une autre syntaxe qui fonctionne. – Kip

+0

+1 pour "mais la direction dit ..." – wkschwartz

Questions connexes