2009-04-21 5 views
0

Autant que je sache, il n'y a pas de possibilité directe d'avoir des contraintes de clé étrangère dans SQLite 3. J'ai une table many-to-many qui en a besoin, alors ' m créer un déclencheur qui déclenche un ABORT lorsque la contrainte de clé étrangère est violée. Ma déclaration ressemble à ceci:Comment créer un déclencheur sur plusieurs clés sur sqlite3

CREATE TRIGGER fkFooBar 
    BEFORE INSERT ON Foo_Bar 
    FOR EACH ROW BEGIN 
    SELECT RAISE (ABORT, 'Insert on Foo_Bar violates foreign key') 
    WHERE ((SELECT id as fId FROM FOO WHERE fId = NEW.fooId) IS NULL) || ((SELECT id as bId FROM BAR WHERE bId = NEW.barId) IS NULL); 
    END; 

Mais ceci ne fait que contraindre le barId étant présent, pas le fooId. Je ne suis que vaguement familier avec SQL, et je n'ai pas traité de déclencheurs avant, donc je suis un peu perdu sur ça. Pourquoi ça ne marche pas? Est-ce que je vais à ce sujet dans le mauvais sens? Est-ce que cela devrait être beaucoup plus simple? (c'est-à-dire dans une instruction SELECT)

Répondre

0

Comme personne d'autre a répondu en fait la question je demandais:

|| n'est pas un OR binaire en sqlite. Utilisez simplement un seul |

0

Prenez l'indice.

Les déclencheurs sont généralement une mauvaise idée. Vous avez découvert encore une autre raison pour laquelle les déclencheurs sont souvent une erreur.

La raison principale est que les déclencheurs décomposent votre programmation en deux parties. Le code qui est le code - et est facile à trouver et à maintenir - et le code qui est caché dans la base de données et est beaucoup plus difficile à trouver et à maintenir.

Si c'est vraiment difficile à faire, vous n'utilisez pas le bon outil.

+0

Alors, quel est l'outil RIGHT? –

+0

Code. Plain ancien code. Dans quelle langue votre application est-elle écrite? Utilisez cette langue. Si vous disposez d'une couche Object-Relational Mapping (ORM), votre code "trigger" s'y trouve, pas la base de données. –

Questions connexes