2010-09-18 8 views
6

Je veux forcer une clé étrangère constarint sur une table dans une application Android.Les déclencheurs SQLite dans Android?

J'ai cherché que cela peut être fait en utilisant des déclencheurs:

Je l'ai fait comme ceci:

db.execSQL("CREATE TRIGGER dept_id_trigger22+" + 
       " AFTER INSERT "+ 
       " OF EmployeeName ON Employees"+ 
       " BEGIN"+ 
            //Condition 
       " RAISE(ABORT,'error') END;"); 

mais aucune erreur n'a été relevée et les valeurs illégales sont insérées.

Quel est le problème avec cela?

+0

Je n'ai pas le code, mais un déclencheur de base a fonctionné pour moi sur SQLite et (d'après mes tests unitaires), il travaillé sur toutes les versions Android. –

+0

pensez-vous que mon code est correct ou qu'il manque quelque chose? –

+0

Toute personne recherchant une syntaxe de déclenchement avec un exemple de mise en œuvre dans android. http://www.coderconsole.com/2015/02/android-sqlite-trigger-demo.html – nitesh

Répondre

6

Ok je l'ai eu

Android prend en charge les déclencheurs SQLite.

La syntaxe correcte est

db.execSQL("CREATE TRIGGER dept_id_trigger22" + 
       " AFTER INSERT "+ 
       "ON Employees"+ 
       " BEGIN"+ 
            //Condition 
       " SELECT RAISE(ABORT,'error'); END;"); 

J'ai oublié d'ajouter après la virgule instruction raise.

Ceci n'exécute pas l'instruction, mais ne déclenche pas d'exception. encore recherchera comment lancer des exceptions

grâce

0

J'ai découvert que la version de SQLite utilisée ne prend pas en charge les clés étrangères - donc je m'attends à ce que les déclencheurs ne soient pas supportés.

+0

merci pour votre aide, mais pouvez-vous me fournir toute référence à cette question –

+0

Je crois que votre hypothèse est fausse, car il le fait appuyer les déclencheurs –

+0

Il semble que oui. Je l'ai cherché, et d'après ce que j'ai lu, je pense que ces fonctionnalités sont disponibles, mais pas activées par défaut. Je ne sais pas encore comment utiliser les triggers, mais il existe une méthode intéressante dans la classe SQLiteDatabase appelée markTableSyncable (table String, String foreignKey, String updateTable) qui est peut-être ce que vous voulez: http://developer.android.com/ reference/android/base de données/sqlite/SQLiteDatabase.html # markTableSyncable% 28java.lang.String,% 20java.lang.String,% 20java.lang.String% 29 – mreichelt

1

Je ne vous attendez pas à des votes pour cette réponse, juste pour vous faire savoir:

Vous pouvez utiliser une autre base de données, par exemple le H2 database. Disclaimer: Je suis l'auteur principal de H2.

Il y a quelques inconvénients: certaines opérations (pas toutes) sont plus lentes, par exemple l'ouverture et la fermeture d'une base de données. Le fichier jar est relativement gros (environ 1 Mo). Vous devez utiliser l'API JDBC.

Mais l'avantage est que: H2 prend en charge l'utilisation de déclencheurs, de contraintes, etc.

+0

Merci Thomas Je vais envisager de l'utiliser. –

+0

Je devrais probablement ajouter: Selon mes tests (limités), certaines opérations sont plus rapides et certaines sont beaucoup plus lentes. Je travaille sur cela, et vous pouvez vous attendre à ce que la performance de H2 sur Android s'améliore dans les mois à venir. Je veux également implémenter les API Android afin que le passage de SQLite à H2 soit plus facile. –

3

Les clés étrangères ne sont supportées que sur Android Froyo sur (2.2) ou plus récent, pour les versions précédentes, vous pouvez les inclure, mais ne tient pas compte SQLite les. Toutes les versions Android de SQLite prennent en charge les déclencheurs pour produire le même effet.

Les nouvelles versions de SQLite (pour votre PC) ont une commande appelée "genfkey" qui analysera votre base de données SQLite (qui contient des clés étrangères) et produira les triggers équivalents. De cette façon, vous pouvez concevoir vos tables avec des contraintes de clé étrangère tout en prenant en charge toutes les versions du système d'exploitation.

Sous Windows, ouvrez l'outil de ligne de commande SQLite avec votre fichier de base de données en tant que paramètre:

sqlite3 mydatabase.db 
.genfkey --exec 

Cela va générer des déclencheurs pour toutes vos principales contraintes.

1

Pour supprimer 50 dernières lignes lorsque le nombre est supérieur à 100

sqliteDB.execSQL("CREATE TRIGGER IF NOT EXISTS delete_trigger 
    AFTER INSERT ON table1 
    WHEN (SELECT COUNT(*) FROM table1) > 50 " + 
    BEGIN 
     delete From table1 where id not in(select id from table1 order by id desc limit 100; 
    END;" 
);