Comment faire une MISE À JOUR en joignant des tables sur SQLite?

92

J'ai essayé :

UPDATE closure JOIN item ON ( item_id = id ) 
SET checked = 0 
WHERE ancestor_id = 1

Et:

UPDATE closure, item 
SET checked = 0 
WHERE ancestor_id = 1 AND item_id = id

Les deux fonctionnent avec MySQL, mais ceux-ci me donnent une erreur de syntaxe dans SQLite.

Comment faire fonctionner cette UPDATE / JOIN avec SQLite version 3.5.9?

e-satis
la source
C'est déjà répondu par stackoverflow.com/questions/3845718/…
Ivelin Nikolaev

Réponses:

128

Vous ne pouvez pas. SQLite ne prend pas en charge les JOIN dans les instructions UPDATE .

Mais vous pouvez probablement le faire avec une sous-requête à la place:

UPDATE closure SET checked = 0 
WHERE item_id IN (SELECT id FROM item WHERE ancestor_id = 1);

Ou quelque chose comme ça; on ne sait pas exactement quel est votre schéma.

Andrew Watt
la source
20
Là où cela devient poilu, c'est lorsque vous devez copier une colonne d'une table à une autre afin d'inverser le sens d'une association. où dans MySQL vous pourriez faire quelque chose comme, créer la colonne foos.bar_id update foos join bars on bars.foo_id = foos.id set foos.bar_id = bars.id, puis déposer la colonne bars.foo_id ... comment cela pourrait-il être fait dans SQLite? Si quelqu'un sait, je pourrais certainement l'utiliser.
hoff2
@ hoff2 En fait, c'est probablement le moyen le plus simple de le faire. Dans mon cas, je n'avais même pas besoin de la pièce WHERE EXISTS: stackoverflow.com/a/3845931/847201
ACK_stoverflow
6

Vous pouvez également utiliser REPLACE puis vous pouvez utiliser la sélection avec des jointures. Comme ça:

REPLACE INTO clusure 
 SELECT sel.col1,sel.col2,....,sel.checked --checked should correspond to column that you want to change
FROM (
 SELECT *,0 as checked FROM closure LEFT JOIN item ON (item_id = id) 
 WHERE ancestor_id = 1) sel
Roman Nazarevych
la source