Aller au contenu

Select avec jointure via SQLite


Recommended Posts

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.

Lien vers le commentaire
Partager sur d’autres sites

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 ?

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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é par Tenryû_kara_kita
Lien vers le commentaire
Partager sur d’autres sites

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)," +
Lien vers le commentaire
Partager sur d’autres sites

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.

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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....

Lien vers le commentaire
Partager sur d’autres sites

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.

Lien vers le commentaire
Partager sur d’autres sites

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 ?

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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....

Lien vers le commentaire
Partager sur d’autres sites

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 ;)

Lien vers le commentaire
Partager sur d’autres sites

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.

Lien vers le commentaire
Partager sur d’autres sites

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.

Lien vers le commentaire
Partager sur d’autres sites

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)

Lien vers le commentaire
Partager sur d’autres sites

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 ;)

Lien vers le commentaire
Partager sur d’autres sites

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 ?

Lien vers le commentaire
Partager sur d’autres sites

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); 
}


Lien vers le commentaire
Partager sur d’autres sites

Rejoignez la conversation

Vous pouvez poster maintenant et vous enregistrez plus tard. Si vous avez un compte, connectez-vous maintenant pour poster.

Invité
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

×
×
  • Créer...