janoka Posté(e) 7 août 2013 Share Posté(e) 7 août 2013 Bonjour, Je souhaite faire un SELECT avec une jointure, mais le logCat me renvoie " java.lang.nullPointerException " Voici une partie de mon code IHM idUtilisateur = 1 // ouverture de ma BDD db = new DBAdapter(getApplicationContext()); //selectionne liste de compte de l'utilisateur cursor = db.SelectCompteUtilisateur(idUtilisateur); Maintenant le code pour la persistance Le but de mon select est de me retourner une liste de compte d'un utilisateur par rapport à son ID String Query = " SELECT * FROM "+ BDD.TABLE_COMPTES + " C INNER JOIN " + BDD.TABLE_UTILISATEURS + " U ON C.COL_ID_UTILISATEUR = U.COL_ID " + " WHERE U.COL_ID = " + idUtilisateur; Cursor mCursor = db.rawQuery(Query, null); //controle du cursor, mais le programme plante avant. if(mCursor == null || mCursor.getCount() == 0){ System.out.println("null"); } et voici le code de mes deux tables pour la BDD, avec clef étrangère pour faire la liaison : Clef étrangère activé lors de l'ouverture. "CREATE TABLE " + TABLE_UTILISATEURS + " (" + "COL_ID INTEGER PRIMARY KEY, " + "COL_NOM TEXT NOT NULL, " + "COL_PASSWORD TEXT NOT NULL, " + "COL_MAIL TEXT NOT NULL, " + "COL_ETAT INTEGER NOT NULL);" + " CREATE TABLE " + TABLE_COMPTES + " (" + "COL_ID_COMPTE INTEGER PRIMARY KEY AUTOINCREMENT, " + "COL_ID_UTILISATEUR INTEGER NOT NULL CONSTRAINT fk_utilisateurs_comptes REFERENCES"+ TABLE_UTILISATEURS + "(COL_ID)," + "COL_BANK TEXT NULL,"+ "COL_TITRE TEXT NOT NULL," + "COL_DESIGNATION TEXT NULL," + "COL_SELECT INTEGER NULL,"+ "COL_TOTAL REAL NULL);" + Merci de votre aide. Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Kajaeshi Posté(e) 8 août 2013 Share Posté(e) 8 août 2013 Essaie String Query = " SELECT * FROM "+ BDD.TABLE_COMPTES + " INNER JOIN " + BDD.TABLE_UTILISATEURS + " ON C.COL_ID_UTILISATEUR Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 8 août 2013 Share Posté(e) 8 août 2013 Tu n'indiques pas la ligne où se produit l'erreur (indication présente dans le LogCat) Est-ce cette ligne ? Cursor mCursor = db.rawQuery(Query, null); Si oui, ce peut être db qui est null. D'où provient cette variable ? Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Kajaeshi Posté(e) 8 août 2013 Share Posté(e) 8 août 2013 D'ici : // ouverture de ma BDDdb = new DBAdapter(getApplicationContext()); Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 8 août 2013 Share Posté(e) 8 août 2013 Le 'db' en question est une instance de DBAdapter, alors que le 'db' utilisé pour le rawQuery (code situé vraisemblablement dans la méthode SelectCompteUtilisateur de cette classe DBAdapter) doit être une instance de SQLiteDatabase. D'où ma question... Attendons le passage de janoka, afin qu'il nous éclaire Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Kajaeshi Posté(e) 8 août 2013 Share Posté(e) 8 août 2013 (modifié) Un autre truc qui me chiffonne (en plus de ce que tu viens d'expliquer qui effectivement ne m'avait pas choqué), c'est sa variable Query. Elle à une valeur du genre : "SELECT * FROM TABLE_COMPTES C INNER JOIN TABLE_UTILISATEURS U ON compte = blablablabla" Je comprends pas trop le C et le U... Edit : Aaaaaaah surement un alias, dans ce cas là il a oublié "AS" avant le C et le U non ? Modifié 8 août 2013 par Tenryû_kara_kita Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 8 août 2013 Share Posté(e) 8 août 2013 Le mot-clef AS est optionnel, normalement... Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Kajaeshi Posté(e) 8 août 2013 Share Posté(e) 8 août 2013 Ok. Il manque un espace je crois, après le REFERENCES de la contrainte de clé étrangère : "COL_ID_UTILISATEUR INTEGER NOT NULL CONSTRAINT fk_utilisateurs_comptes REFERENCES"+ TABLE_UTILISATEURS + "(COL_ID)," + Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
janoka Posté(e) 8 août 2013 Auteur Share Posté(e) 8 août 2013 Oui c'est bien cela, le 'db' en question est une instance de DBAdapter, alors que le 'db' utilisé pour le rawQuery est une instance de SQLiteDatabase. Voici l'extrait plus complet de mon IHM : import java.util.List; import Domaine.Compte; import Domaine.Utilisateur; import Persistance.DBAdapter; import android.app.ListActivity; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.Button; import android.widget.CheckBox; import android.widget.ListView; import android.widget.SimpleCursorAdapter; public class LesComptes extends ListActivity { private Button BtnAjout; private Button BtnSup; private Button BtnApercu; private ListView LvCompte; private DBAdapter db; private Cursor cursor; private int idUtilisateur; private Utilisateur utilisateur; private Compte compte; private Bundle bundle; private List<Compte> listeCompte; public Utilisateur getUtilisateur(){ return utilisateur; } public void setUtilisateur(Utilisateur utilisateur){ this.utilisateur = utilisateur; } public Compte getCompte(){ return compte; } public void setCompte(Compte compte){ this.compte = compte; } protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.les_comptes); System.out.println("on create"); BtnAjout = (Button)findViewById(R.id.BtnAjout); BtnSup = (Button)findViewById(R.id.BtnSup); BtnApercu = (Button)findViewById(R.id.BtnApercu); System.out.println("ok"); db = new DBAdapter(getApplicationContext()); bundle = this.getIntent().getExtras(); utilisateur = new Utilisateur(); compte = new Compte(); //On récupère les données du Bundle idUtilisateur = (Integer) bundle.get("COL_ID"); System.out.println("lescomptes : " + idUtilisateur); //selectionne liste de compte de l'utilisateur cursor = db.SelectCompteUtilisateur(idUtilisateur); if(cursor != null || cursor.getCount() != 0){ System.out.println("ok1"); startManagingCursor(cursor); while(!cursor.isAfterLast()){ compte.setIdCompte(cursor.getColumnIndex("COL_ID_COMPTE")); compte.setBank(cursor.getString(cursor.getColumnIndex("COL_BANK"))); compte.setTitre(cursor.getString(cursor.getColumnIndex("COL_TITRE"))); compte.setTotal((double)cursor.getFloat(cursor.getColumnIndex("COL_TOTAL"))); String montant = Double.toString(compte.getTotal()); String idCompte = Integer.toString(compte.getIdCompte()); SimpleCursorAdapter adapte = new SimpleCursorAdapter(this, R.layout.listeview_compte, cursor, new String[]{compte.getBank(),compte.getTitre(),montant},new int[]{R.id.TvBank,R.id.TvNom,R.id.TvMontant}); LvCompte = (ListView)findViewById(android.R.id.list); getListView().setAdapter(adapte); et ma DBAdapter public class DBAdapter { private static final String TAG = "DBAdapter"; private final Context context; private BDD database; private SQLiteDatabase db; public DBAdapter(Context ctx) { this.context = ctx; database = new BDD (context); } //Open the database public DBAdapter open() throws SQLException { db = database.getWritableDatabase(); return this; } //Close the database public void close() { database.close(); } public Cursor ExecuteQuery(String Query, String[] selectionArgs) { Cursor mCursor = null; // Open Android Database db = database.getWritableDatabase(); mCursor = db.rawQuery(Query, selectionArgs); if (mCursor != null) { mCursor.moveToFirst(); } // Close Android Database database.close(); return mCursor; } public Cursor SelectCompteUtilisateur(int idUtilisateur){ db.execSQL(" FOREIGN_KEYS PRAGMA = ON "); String Query = " SELECT * FROM "+ BDD.TABLE_COMPTES + " C INNER JOIN " + BDD.TABLE_UTILISATEURS + " U ON C.COL_ID_UTILISATEUR = U.COL_ID " + " WHERE U.COL_ID = " + idUtilisateur; Cursor mCursor = db.rawQuery(Query, null); if(mCursor == null || mCursor.getCount() == 0){ System.out.println("null"); } return mCursor; } et voici le magnifique logCat 08-08 12:12:39.388: W/KeyCharacterMap(555): No keyboard for id 0 08-08 12:12:39.388: W/KeyCharacterMap(555): Using default keymap: /system/usr/keychars/qwerty.kcm.bin 08-08 12:12:49.878: I/System.out(555): on create 08-08 12:12:49.878: I/System.out(555): ok 08-08 12:12:49.878: I/System.out(555): lescomptes : 1 08-08 12:12:49.878: D/AndroidRuntime(555): Shutting down VM 08-08 12:12:49.878: W/dalvikvm(555): threadid=3: thread exiting with uncaught exception (group=0x4001b188) 08-08 12:12:49.878: E/AndroidRuntime(555): Uncaught handler: thread main exiting due to uncaught exception 08-08 12:12:49.898: E/AndroidRuntime(555): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.virtualbudget/com.virtualbudget.LesComptes}: java.lang.NullPointerException 08-08 12:12:49.898: E/AndroidRuntime(555): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496) 08-08 12:12:49.898: E/AndroidRuntime(555): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) 08-08 12:12:49.898: E/AndroidRuntime(555): at android.app.ActivityThread.access$2200(ActivityThread.java:119) 08-08 12:12:49.898: E/AndroidRuntime(555): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863) 08-08 12:12:49.898: E/AndroidRuntime(555): at android.os.Handler.dispatchMessage(Handler.java:99) 08-08 12:12:49.898: E/AndroidRuntime(555): at android.os.Looper.loop(Looper.java:123) 08-08 12:12:49.898: E/AndroidRuntime(555): at android.app.ActivityThread.main(ActivityThread.java:4363) 08-08 12:12:49.898: E/AndroidRuntime(555): at java.lang.reflect.Method.invokeNative(Native Method) 08-08 12:12:49.898: E/AndroidRuntime(555): at java.lang.reflect.Method.invoke(Method.java:521) 08-08 12:12:49.898: E/AndroidRuntime(555): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 08-08 12:12:49.898: E/AndroidRuntime(555): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 08-08 12:12:49.898: E/AndroidRuntime(555): at dalvik.system.NativeStart.main(Native Method) 08-08 12:12:49.898: E/AndroidRuntime(555): Caused by: java.lang.NullPointerException 08-08 12:12:49.898: E/AndroidRuntime(555): at Persistance.DBAdapter.SelectCompteUtilisateur(DBAdapter.java:188) 08-08 12:12:49.898: E/AndroidRuntime(555): at com.virtualbudget.LesComptes.onCreate(LesComptes.java:72) 08-08 12:12:49.898: E/AndroidRuntime(555): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 08-08 12:12:49.898: E/AndroidRuntime(555): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459) 08-08 12:12:49.898: E/AndroidRuntime(555): ... 11 more Sachant que ma liste de compte est vide, mon cursor est null. Mais d'apres le logCat c'est lors du select... Soit c'est mon select ou soit ma BDD. Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 8 août 2013 Share Posté(e) 8 août 2013 Tu ne sembles pas faire appel à la méthode open de DBAdapter avant d'appeler SelectCompteUtilisateur, donc la base de données n'est pas ouverte (l'attribut 'db' de DBAdapter est null), et ça doit donc planter sur la première ligne de la méthode Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
janoka Posté(e) 8 août 2013 Auteur Share Posté(e) 8 août 2013 Si, à mon IHM, je fais : db = new DBAdapter(getApplicationContext()); avant de faire appel à ma méthode. J'ai fait comme cela pour mes autres Select et sa marche. Encore une histoire à s'arracher les cheveux.... Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 9 août 2013 Share Posté(e) 9 août 2013 Non, le constructeur de DBAdapter ne fait aucune ouverture de la base. Si tu n'appelles pas la méthode open, getWritableDatabase n'est pas appelée, l'attribut db n'est pas initialisé, et donc ça plante. Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
janoka Posté(e) 9 août 2013 Auteur Share Posté(e) 9 août 2013 En effet, en ajoutant " db.open " j'avance dans mon problème pour cette IHM, merci pour cette aide. Et maintenant le logCat m'indique qu'il ne trouve pas ma table compte et je ne vois pas de faute de frappe. le logCat: 08-09 11:34:23.870: D/AndroidRuntime(218): Shutting down VM 08-09 11:34:23.870: W/dalvikvm(218): threadid=3: thread exiting with uncaught exception (group=0x4001b188) 08-09 11:34:23.870: E/AndroidRuntime(218): Uncaught handler: thread main exiting due to uncaught exception 08-09 11:34:23.960: E/AndroidRuntime(218): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.virtualbudget/com.virtualbudget.LesComptes}: android.database.sqlite.SQLiteException: no such table: TABLE_COMPTES: , while compiling: SELECT * FROM TABLE_COMPTES AS C INNER JOIN TABLE_UTILISATEURS AS U ON C.COL_ID_UTILISATEUR = U.COL_ID WHERE U.COL_ID = 1 08-09 11:34:23.960: E/AndroidRuntime(218): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.app.ActivityThread.access$2200(ActivityThread.java:119) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.os.Handler.dispatchMessage(Handler.java:99) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.os.Looper.loop(Looper.java:123) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.app.ActivityThread.main(ActivityThread.java:4363) 08-09 11:34:23.960: E/AndroidRuntime(218): at java.lang.reflect.Method.invokeNative(Native Method) 08-09 11:34:23.960: E/AndroidRuntime(218): at java.lang.reflect.Method.invoke(Method.java:521) 08-09 11:34:23.960: E/AndroidRuntime(218): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 08-09 11:34:23.960: E/AndroidRuntime(218): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 08-09 11:34:23.960: E/AndroidRuntime(218): at dalvik.system.NativeStart.main(Native Method) 08-09 11:34:23.960: E/AndroidRuntime(218): Caused by: android.database.sqlite.SQLiteException: no such table: TABLE_COMPTES: , while compiling: SELECT * FROM TABLE_COMPTES AS C INNER JOIN TABLE_UTILISATEURS AS U ON C.COL_ID_UTILISATEUR = U.COL_ID WHERE U.COL_ID = 1 08-09 11:34:23.960: E/AndroidRuntime(218): at android.database.sqlite.SQLiteProgram.native_compile(Native Method) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.database.sqlite.SQLiteProgram.compile(SQLiteProgram.java:110) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:49) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1221) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1194) 08-09 11:34:23.960: E/AndroidRuntime(218): at Persistance.DBAdapter.SelectCompteUtilisateur(DBAdapter.java:191) 08-09 11:34:23.960: E/AndroidRuntime(218): at com.virtualbudget.LesComptes.onCreate(LesComptes.java:69) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 08-09 11:34:23.960: E/AndroidRuntime(218): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459) 08-09 11:34:23.960: E/AndroidRuntime(218): ... 11 more 08-09 11:34:24.010: I/dalvikvm(218): threadid=7: reacting to signal 3 08-09 11:34:24.020: I/dalvikvm(218): Wrote stack trace to '/data/anr/traces.txt' 08-09 11:39:24.063: I/Process(218): Sending signal. PID: 218 SIG: 9 Et maintenant la BDD: public class BDD extends SQLiteOpenHelper { private static final String TAG = "BDD"; private static final String DATABASE_NAME = "VirtualBudget"; private static final int DATA_VERSION = 1; public static final String TABLE_UTILISATEURS = "TABLE_UTILISATEURS"; public static final String TABLE_COMPTES = " TABLE_COMPTES "; public static final String TABLE_TRANSACTIONS = "TABLE_TRANSACTIONS"; private static final String CREATE_BDD = "CREATE TABLE " + TABLE_UTILISATEURS + " (" + "COL_ID INTEGER PRIMARY KEY, " + "COL_NOM TEXT NOT NULL, " + "COL_PASSWORD TEXT NOT NULL, " + "COL_MAIL TEXT NOT NULL, " + "COL_ETAT INTEGER NOT NULL);" + " CREATE TABLE " + TABLE_COMPTES + " (" + "COL_ID_COMPTE INTEGER PRIMARY KEY AUTOINCREMENT, " + "COL_ID_UTILISATEUR INTEGER NOT NULL CONSTRAINT fk_utilisateurs_comptes REFERENCES "+ TABLE_UTILISATEURS + "(COL_ID)," + "COL_BANK TEXT NULL,"+ "COL_TITRE TEXT NOT NULL," + "COL_DESIGNATION TEXT NULL," + "COL_SELECT INTEGER NULL,"+ "COL_TOTAL REAL NULL);" + "CREATE TABLE" + TABLE_TRANSACTIONS + " (" + "COL_IDTRANSACTION INTEGER PRIMARY KEY AUTOINCREMENT " + "COL_IDCOMPTE INTEGER NOT NULL CONSTRAINT fk_comptes_transactions REFERENCES " + TABLE_COMPTES + "(COL_ID_COMPTE)," + "COL_LIBELLE TEXT NULL," + "COL_MONTANT REAL NULL," + "COL_DATE DATE NULL," + "COL_FIXE INTEGER NULL," + "COL_DEBIT INTEGER NULL," + "COL_CREDIT INTEGER NULL );"; public BDD(Context context) { super(context,DATABASE_NAME, null, DATA_VERSION); } @Override public void onCreate(SQLiteDatabase db) { //on créé la table à partir de la requête écrite dans la variable CREATE_BDD db.execSQL(CREATE_BDD); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //On peut fait ce qu'on veut ici moi j'ai décidé de supprimer la table et de la recréer //comme ça lorsque je change la version les id repartent de 0 Log.w(TAG, "UPGRADING DATABASE FROM VERSION " + oldVersion + " TO " + newVersion + ", WHICH WILL DESTROY ALL OLD DATA !"); db.execSQL("DROP DATABASE IF EXISTS" + CREATE_BDD + ";"); onCreate(db); } } C'est la construction de ma BDD qui doit etre fausse ? Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 9 août 2013 Share Posté(e) 9 août 2013 Probablement que la table n'a pas été créée lors de la création de la base de données, il y avait d'ailleurs une erreur dans ton script de création de tables, comme l'avait indiqué Tenryû_kara_kita (et il en reste une dans la partie upgrade, il manque là aussi un espace après EXISTS). Etant donné que création de la base et création des tables sont dissociées, une fois la base créée, même si une erreur s'est produite lors de la création des tables, la méthode onCreate ne sera plus appelée, puisque la base existe. Pour forcer la (re)création des tables, tu peux supprimer les données de ton application (Paramètres système/Applications/Gérer les applications/ton appli/Supprimer les données) et voir alors si la création des tables se passe bien Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
janoka Posté(e) 10 août 2013 Auteur Share Posté(e) 10 août 2013 Pour ma base de donnée, j'ai séparé mes tables par des variables et lors de la création de la base cela ma permis de constater qu'il y avait des fautes dans mes requêtes de création des tables et du coup ma table COMPTE n'était pas créé, ni ma table TRANSACTION. Merci pour votre aide ! je vais enfin pouvoir avancer.... Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
KaNa Posté(e) 11 août 2013 Share Posté(e) 11 août 2013 Salut, Un conseil pour une meilleur utilisation des services du SDK d'Android et notamment le contentprovider, je te conseil de jetter un coup d'oeil sur : http://developer.android.com/guide/topics/providers/content-provider-creating.html Après pour ce qui est des JOIN, ce site explique bien comment le faire grâce au ContentProvider: http://martin.cubeactive.com/android-using-joins-with-a-provider-sqlite/ Pour faire une requête ensuite, depuis n'importe quel activité, pas besoin de déclarer quoi que ce soit, juste un appel à getContentResolver() te donne accés à : - query() - insert() - update() - delete() C'est assez lourd à mettre en place, mais une fois fait, il y a a vrai sentiment de satisfaction à utiliser ce système ;) Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 12 août 2013 Share Posté(e) 12 août 2013 Oui, enfin, implémenter un ContentProvider pour accéder à ses propres données, c'est un peu lourd (le principe des ContentProvider, à la base, c'est de rendre disponibles ses données aux autres applications). Et puis cela peut aussi poser des problèmes de sécurité (il faudra bien gérer les permissions) si on ne veut pas que n'importe quelle application puisse potentiellement lire ou modifier nos données. Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
janoka Posté(e) 12 août 2013 Auteur Share Posté(e) 12 août 2013 De retour vers vous pour un nouveau dilemme, toujours sur le même projet. Je souhaite entrer un nouveau compte avec un id Utilisateur. Pour cela je fait un "update" dont voici le code : //insérer un nouveau compte dans la liste des comptes de l'utilisateur public Cursor InsertCompte(Compte compte, int idUtilisateur){ System.out.println("insert compte" + compte.toString()); String query = " UPDATE " + BDD.TABLE_COMPTES + " SET COL_BANK = ?, COL_TITRE = ?, COL_DESIGNATION = ?, COL_SELECT = ? " + " WHERE COL_ID_UTILISATEUR IN ( SELECT COL_ID FROM " + BDD.TABLE_UTILISATEURS + " WHERE COL_ID = ? ) "; String id =Integer.toString(idUtilisateur); Cursor mCursor = db.rawQuery(query, new String []{compte.getBank(),compte.getTitre(),compte.getDesignation(),Integer.toString(compte.getSelect()),id}); if(mCursor != null){ System.out.println("cursor ok"); mCursor.moveToNext(); System.out.println(mCursor.getInt(mCursor.getColumnIndex("COL_ID_COMPTE"))); } else{ System.out.println("null"); } return mCursor; } Je récupère un cursor non null, mais le logCat m'indique Index -1, alors j'ai rajouté "cursor.moveToFirst" et toujours pas de IdCompte... Mais erreur cursor index.... Voici le logCat 08-12 16:48:37.969: I/System.out(220): nouveau compte 1 08-12 16:48:37.969: I/System.out(220): insert compteID : 0 08-12 16:48:37.969: I/System.out(220): Bank : q 08-12 16:48:37.969: I/System.out(220): Titre : q design q 08-12 16:48:37.969: I/System.out(220): cursor ok 08-12 16:48:38.059: W/System.err(220): android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0 08-12 16:48:38.069: W/System.err(220): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580) 08-12 16:48:38.069: W/System.err(220): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214) 08-12 16:48:38.069: W/System.err(220): at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:84) 08-12 16:48:38.069: W/System.err(220): at Persistance.DBAdapter.InsertCompte(DBAdapter.java:200) 08-12 16:48:38.069: W/System.err(220): at com.virtualbudget.UnCompte$1.onClick(UnCompte.java:94) 08-12 16:48:38.069: W/System.err(220): at android.view.View.performClick(View.java:2364) 08-12 16:48:38.069: W/System.err(220): at android.view.View.onTouchEvent(View.java:4179) 08-12 16:48:38.069: W/System.err(220): at android.widget.TextView.onTouchEvent(TextView.java:6541) 08-12 16:48:38.078: W/System.err(220): at android.view.View.dispatchTouchEvent(View.java:3709) 08-12 16:48:38.078: W/System.err(220): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884) 08-12 16:48:38.078: W/System.err(220): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884) 08-12 16:48:38.078: W/System.err(220): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884) 08-12 16:48:38.078: W/System.err(220): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884) 08-12 16:48:38.078: W/System.err(220): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1659) 08-12 16:48:38.078: W/System.err(220): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107) 08-12 16:48:38.078: W/System.err(220): at android.app.Activity.dispatchTouchEvent(Activity.java:2061) 08-12 16:48:38.078: W/System.err(220): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1643) 08-12 16:48:38.078: W/System.err(220): at android.view.ViewRoot.handleMessage(ViewRoot.java:1691) 08-12 16:48:38.078: W/System.err(220): at android.os.Handler.dispatchMessage(Handler.java:99) 08-12 16:48:38.078: W/System.err(220): at android.os.Looper.loop(Looper.java:123) 08-12 16:48:38.078: W/System.err(220): at android.app.ActivityThread.main(ActivityThread.java:4363) 08-12 16:48:38.078: W/System.err(220): at java.lang.reflect.Method.invokeNative(Native Method) 08-12 16:48:38.078: W/System.err(220): at java.lang.reflect.Method.invoke(Method.java:521) 08-12 16:48:38.078: W/System.err(220): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 08-12 16:48:38.078: W/System.err(220): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 08-12 16:48:38.078: W/System.err(220): at dalvik.system.NativeStart.main(Native Method) C'est ma requête "Update" qui est mauvaise ? , ou une clef etrangere qui empeche l'enregistrement ? et comment faire pour y remédier ? Merci pour vos propositions. Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 12 août 2013 Share Posté(e) 12 août 2013 Pour faire un update, tu as la méthode ... update ; pas besoin de passer par un rawQuery, qui de plus, retourne un Cursor qui est fait normalement pour parcourir un ensemble de ligne de résultat, alors qu'un update ne retourne qu'une valeur entière (indiquant le nombre de lignes qui ont été modifiées dans la table) Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
janoka Posté(e) 12 août 2013 Auteur Share Posté(e) 12 août 2013 (modifié) ok merci Modifié 12 août 2013 par janoka Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
KaNa Posté(e) 13 août 2013 Share Posté(e) 13 août 2013 Oui, enfin, implémenter un ContentProvider pour accéder à ses propres données, c'est un peu lourd (le principe des ContentProvider, à la base, c'est de rendre disponibles ses données aux autres applications). Et puis cela peut aussi poser des problèmes de sécurité (il faudra bien gérer les permissions) si on ne veut pas que n'importe quelle application puisse potentiellement lire ou modifier nos données. Suffit d'indiquer que le Provider ne peut pas être exporté dans le manifest et c'est good :) Comment faire sinon, pour utiliser les CursorLoader. De plus c'est lourd à mettre en place, certes mais il existe des générateurs de codes sur Internet qui te permettent de générer une bonne partie du code. Bref, good luck ;) Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
janoka Posté(e) 18 août 2013 Auteur Share Posté(e) 18 août 2013 Bonjour, Je reviens vers vous pour avoir votre avis sur une erreur provoqué par un "SimpleCursorAdapter". Le LogCat me renvoi l"erreur suivante : 08-18 14:00:06.126: W/dalvikvm(432): threadid=3: thread exiting with uncaught exception (group=0x4001b188) 08-18 14:00:06.126: E/AndroidRuntime(432): Uncaught handler: thread main exiting due to uncaught exception 08-18 14:00:06.146: E/AndroidRuntime(432): java.lang.RuntimeException: Unable to resume activity {com.virtualbudget/com.virtualbudget.LesComptes}: java.lang.IllegalArgumentException: column 'no' does not exist 08-18 14:00:06.146: E/AndroidRuntime(432): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2950) 08-18 14:00:06.146: E/AndroidRuntime(432): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2965) 08-18 14:00:06.146: E/AndroidRuntime(432): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1889) 08-18 14:00:06.146: E/AndroidRuntime(432): at android.os.Handler.dispatchMessage(Handler.java:99) 08-18 14:00:06.146: E/AndroidRuntime(432): at android.os.Looper.loop(Looper.java:123) 08-18 14:00:06.146: E/AndroidRuntime(432): at android.app.ActivityThread.main(ActivityThread.java:4363) 08-18 14:00:06.146: E/AndroidRuntime(432): at java.lang.reflect.Method.invokeNative(Native Method) 08-18 14:00:06.146: E/AndroidRuntime(432): at java.lang.reflect.Method.invoke(Method.java:521) 08-18 14:00:06.146: E/AndroidRuntime(432): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 08-18 14:00:06.146: E/AndroidRuntime(432): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 08-18 14:00:06.146: E/AndroidRuntime(432): at dalvik.system.NativeStart.main(Native Method) 08-18 14:00:06.146: E/AndroidRuntime(432): Caused by: java.lang.IllegalArgumentException: column 'no' does not exist 08-18 14:00:06.146: E/AndroidRuntime(432): at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314) 08-18 14:00:06.146: E/AndroidRuntime(432): at android.widget.SimpleCursorAdapter.findColumns(SimpleCursorAdapter.java:339) 08-18 14:00:06.146: E/AndroidRuntime(432): at android.widget.SimpleCursorAdapter.<init>(SimpleCursorAdapter.java:91) 08-18 14:00:06.146: E/AndroidRuntime(432): at com.virtualbudget.LesComptes.onResume(LesComptes.java:242) 08-18 14:00:06.146: E/AndroidRuntime(432): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1149) 08-18 14:00:06.146: E/AndroidRuntime(432): at android.app.Activity.performResume(Activity.java:3763) 08-18 14:00:06.146: E/AndroidRuntime(432): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2937) 08-18 14:00:06.146: E/AndroidRuntime(432): ... 10 more 08-18 14:00:06.167: I/dalvikvm(432): threadid=7: reacting to signal 3 08-18 14:00:06.176: I/dalvikvm(432): Wrote stack trace to '/data/anr/traces.txt' 08-18 14:05:06.227: I/Process(432): Sending signal. PID: 432 SIG: 9 La colonne 'no' n'éxiste pas. En effet la colonne n'éxiste pas, 'no' est la valeur de ma colonne "COL_TITRE" dans ma base de donnée. Voici le code de mon IHM: //selectionne liste de compte de l'utilisateur cursor = db.SelectDesComptesUtilisateur(idUtilisateur); if(cursor.getCount() != 0){ cursor.moveToFirst(); startManagingCursor(cursor); System.out.println("cursor non null et BUG colonne 'no' not exist"); SimpleCursorAdapter adapte = new SimpleCursorAdapter(this, R.layout.listeview_compte, cursor, new String[]{"COL_BANK","COL_TITRE","COL_TOTAL"},new int[]{R.id.TvBank,R.id.TvNom,R.id.TvMontant}); System.out.println("cursor ok3"); LvCompte = (ListView)findViewById(android.R.id.list); System.out.println("cursor ok4"); getListView().setAdapter(adapte); le code pour le select de mon cursor: //liste des comptes utilisateur avec parametres public Cursor SelectDesComptesUtilisateur(int idUtilisateur){ //db = database.getReadableDatabase(); String query = " SELECT _id, COL_BANK, COL_TITRE, COL_TOTAL FROM " + BDD.TABLE_COMPTES + " WHERE COL_ID_UTILISATEUR = ? "; String id = Integer.toString(idUtilisateur); Cursor mCursor = db.rawQuery(query,new String [] {id}); return mCursor; } Enfin le code de ma table : private static final String CREATE_TABLE2 = "CREATE TABLE " + TABLE_COMPTES + " (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT, " + "COL_ID_UTILISATEUR INTEGER NOT NULL CONSTRAINT fk_utilisateurs_comptes REFERENCES " + TABLE_UTILISATEURS + "(COL_ID)," + "COL_BANK TEXT NULL,"+ "COL_TITRE TEXT NULL," + "COL_DESIGNATION TEXT NULL," + "COL_SELECT INTEGER NULL,"+ "COL_TOTAL DOUBLE NULL);"; Le Simple Cursor Adapter prend bien les valeurs pour les colonnes "_id","COL_BANK" mais pas "COL_TITRE". Pour lui, ma valeur est le nom de ma colonne "COL_TITRE". Si quelqu'un a une idée ? Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
KaNa Posté(e) 23 août 2013 Share Posté(e) 23 août 2013 Je vois pas d'erreurs comme ça dans ce que tu as donné. Dans un premier temps essaye de remplacer : //liste des comptes utilisateur avec parametres public Cursor SelectDesComptesUtilisateur(int idUtilisateur){ //db = database.getReadableDatabase(); String query = " SELECT _id, COL_BANK, COL_TITRE, COL_TOTAL FROM " + BDD.TABLE_COMPTES + " WHERE COL_ID_UTILISATEUR = ? "; String id = Integer.toString(idUtilisateur); Cursor mCursor = db.rawQuery(query,new String [] {id}); return mCursor; } Par : //liste des comptes utilisateur avec parametres public Cursor SelectDesComptesUtilisateur(int idUtilisateur){ return db.query( BDD.TABLE_COMPTES, new String[]{"_id","COL_BANK","COL_TITRE","COL_TOTAL"}, "COL_ID_UTILISATEUR = ? ", new String [] {Integer.toString(idUtilisateur)}, null, null, null, null); } Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Recommended Posts
Rejoignez la conversation
Vous pouvez poster maintenant et vous enregistrez plus tard. Si vous avez un compte, connectez-vous maintenant pour poster.