Schéma de table
Nom de la table: file_manager_folder
Lignes: id
, parentId
, name
Ma requête simule le déplacement d'un dossier dans un autre dossier et accepte un tableau utilisant IN (?).
Je souhaite que ma mise à jour ne "déplace" qu'un dossier s'il n'y a pas déjà un dossier avec le même parentId et le même nom. Le type de comportement auquel vous vous attendez sous n'importe quel système de fichiers normal.
Donc par exemple:
UPDATE file_manager_folder set parentId = 54 where id IN( '1','2',3')
Serait une requête qui ne vérifie rien sur le parentId et le nom ... Mais comment puis-je faire fonctionner la jointure gauche.
En voici une que j’ai essayée… qui ne fonctionne pas du tout.
SELECT * FROM
file_manager_folders as a
LEFT JOIN file_manager_folders as b on a.id = b.id
WHERE b.id IS NOT NULL and a.id IN("1","2","3") and a.parentId = 54
UPDATE table1 LEFT JOIN table2 SET t1.x = t2.y ON condition WHERE conditions
Donc, vous voulez déplacer des dossiers uniquement si un dossier du même nom sous le dossier parent cible a not exist:
UPDATE file_manager_folder f1
LEFT OUTER JOIN file_manager_folder f2
ON f1.name = f2.name AND f2.parentId = 54
SET f1.parentId = 54
WHERE f2.name IS NULL AND f1.id IN (1,2,3);
La condition de jointure recherche un dossier du même nom sous le parent cible. La clause WHERE teste qu'aucun dossier de ce type n'existe (f2.name n'est nul que si la jointure externe ne trouve aucune correspondance).
Je pense que cela devrait être résolu en utilisant un unique contrainte/index sur les colonnes parentid
et name
. Sinon, toute personne disposant d'un accès INSERT/UPDATE à la table peut contourner votre règle de gestion.
CREATE UNIQUE INDEX blah_uk ON FILE_MANAGER_FOLDER(parentId, name) USING BTREE
Un peu naïf mais qu'en est-il de cela?
UPDATE file_manager_folder SET parentId = 54
WHERE id IN( '1','2','3')
AND parentId != 54
AND name NOT IN (SELECT name FROM file_manager_folder WHERE id IN ('1', '2', '3'))
Si vous utilisez unNOT IN
au lieu deLEFT join
qui dégrade vos performances.
Exécuter Expliquez avant d'interroger et le problème est évident.