Utiliser SQL correctement

samirsamir Membre
juin 2015 modifié dans API UIKit #1

Hello,


 


J'utilise pour la première fois SQLite dans une application. Mon problème est le suivant :


 


Mon objet modèle :



@interface SGMarque
@property (nonatomic, copy) NSString *codeMarque;
@property (nonatomic, copy) NSArray *offres; // List of SGOffre objects
@end

@interface SGOffre 
@property (nonatomic, copy) NSString *codeOffre;
@property (nonatomic, copy) NSArray *voitures; // List of SGVoiture objects
@end

@interface SGVoiture
@property (nonatomic, copy) NSString *codeVoiture;
@end

Et bien sur dans ma base SQLite j'ai les tables correspondantes.


 


Mon problème est lors de la récupération des données de la base et la construction des objets modèles.


Par exemple je veux récupérer toutes les marques enregistrées dans ma base :


 


Voila un pseudo code comment je procède :



{

//  Récupérer les marques
SQL 1 : SELECT * FROM Marque *;

// Ici je boucle pour récupérer chaque Offre de la marque et ça me génère plusieu// rs requiers SQL
SELECT * FROM Offre WHERE codeMarque = codeMark;

 // Je boucle aussi ici .....
 SELECT * FROM Voiture WHERE codeMarque = codeMark  AND codeOffre = ...
}

Bon ça marche mais je pense que je suis entrain de faire n'importe quoi et que y a un raisonnement à  faire en SQL pour ne pas boucler ainsi et récupérer les données correctement.


 


Aidez moi svp a utiliser SQL correctement :). Merci


 


 


PS : J'utilise le  wrapper FMDB pour SQLite mais ça ne facilite pas les choses à  ce niveau.

Réponses

  • AliGatorAliGator Membre, Modérateur
    J'ai pas tout compris de ce que tu veux faire, mais pour le "je veux récupérer toutes les marques enregistrées dans ma base", pourquoi ne pas utiliser "SELECT DISTINCT(codeMarque) FROM Marque" ?
  • samirsamir Membre
    juin 2015 modifié #3

    Merci pour ta réponse.


     


    Mais avec seulement une seule requête je ne peux pas construire mon object modèle correctement, parce que chaque marque à  une liste d'offres et chaque offre......Je ne sais pas si c'est clair ou pas ? :)


     


    "SELECT DISTINCT(codeMarque) FROM Marque"


     


    Cette requête vas juste me renvoyer les données de la table Marque, concrètement :


     


    Marque :


    codeMarque  


    1                     


    2                     


    .....


     


    Donc pour chaque Marque je dois refaire une autre requête pour récupérer la liste de l'offre


     


    Donc pour chaque marque :


    SELECT * FROM Offre WHERE codeMarque = ...


     


    Cela me permettra de construire mon array offres. 


     


    Offre


    codeOffre   codeMarque ( clé étrangère)


    1                  1


    2                  1


    3                  2


    ...


     


    et pour chaque offre la même chose pour voiture.....


     


     


    Peut être je devrais monter mon schéma base de données pour voir plus mon problème.? 


  • Joanna CarterJoanna Carter Membre, Modérateur
    Core Data ?
  • samirsamir Membre


    Core Data ?




     


     Oui mais on a déjas discuté de ça sur ce forum et j'avais pas le choix :).


     


    J'aurais aimé voir les requêtes SQL générées pas CoreData quand on fait un fetch avec des objets complexes (qui ont des relations vers d'autres entités).

  • AliGatorAliGator Membre, Modérateur
    Bah fait des jointures alors (JOIN)
  • Une sélection multiple ?



    SELECT * FROM marque as m, voiture as v, ...
    WHERE m.codeMarque = codeMark
    AND ...

    J'ai pas compris sinon.


  • AliGatorAliGator Membre, Modérateur


    Une sélection multiple ?


    SELECT * FROM marque as m, voiture as v, ...
    WHERE m.codeMarque = codeMark
    AND ...

    J'ai pas compris sinon.
    Un JOIN fait la même chose en + efficace et + adéquat.
  • C'est pas faux. Une proposition.


  • LarmeLarme Membre
    juin 2015 modifié #10


    Un JOIN fait la même chose en + efficace et + adéquat.




    ça fait longtemps que je n'ai pas vraiment fait de SQL (si on exempt les analogies qu'on peut retrouver sur du CoreData), mais je pense que la solution de Magiic semble meilleure dans le sens où elle est plus simple à  comprendre dans un premier temps.

    Je veux dire que samir a plus de soucis sur l'algorithmie des requêtes SQL qu'autre chose. Donc commencer par l'exemple de Magiic pour comprendre et ensuite passer par un JOIN serait-il plus adéquat ?


     


    À titre d'exemple, j'ai commencé par faire des requêtes du type de celles de Magiic, basiques, avant d'avoir les cours sur les autres JOIN.


  • samirsamir Membre
    juin 2015 modifié #11

    Merci pour vos réponses.


     


    J'ai l'habitude avec CoreData + MagicalRecord qui me facilitent vraiment la vie, en une seule ligne j'ai mon modèle bien construit à  partir des données de ma base.


     


    Je vais revoir toutes ces notions d'une manière approfondie. 


     


    Quelqu'un a déjas travaillé sur un projet complexe en SQLite ? J'aurais aimé voir comment vous avez architecturé toute la partie requête a la base et alimentation du modèle (une simple explication suffira :))


  • muqaddarmuqaddar Administrateur

    SELECT marque.* FROM marque
    ... [selection des autres champs des 2 autres tables offre et voiture si nécessaire]...
    INNER JOIN offre ON marque.codeMarque = offre.codeMarque // INNER JOIN associe les éléments de la table2
    INNER JOIN voiture ON marque.codeMarque = voiture.codeMarque // INNER JOIN associe les éléments de la table3
    GROUP BY marque.codeMarque // GROUP BY a toujours été 10 fois plus rapide que DISTINCT dans mes tests.


    Il me faudra plus d'infos (schéma des tables, ce que tu veux vraiment récupérer dans la requête) si tu veux plus d'aide.

  • Merci @muqaddar


     


    Une autre petite question :)


     


    Avec une seule requête SQL tu auras un seul FMResultSet ( je suppose que tu travaille avec FMDB ?)


     


    Un truc de genre :



    NSString *query = ....
    FMResultSet *resultSet = [database executeQuerry:query]; 

    Le result set retourné contient les résultats de toute les tables, comment peux-tu reconstruire le modèle avec un seul result set ? 



    while ([resultSet next]) {
       // Je dois créer les marques

      // Pour chaque marque je dois luis associée sa liste d'offre

      // Et pour chaque offre je dois lui associé sa liste de voiture 
    }
  • muqaddarmuqaddar Administrateur

    Dans chaque modèle j'ai créé des constructeurs de commodités.



    + (id)typeFoundInDBWithPrimaryKey:(NSString*)anID;
    - (id)initFoundInDBWithPrimaryKey:(NSString*)anID;

    + (id)typeWithRows:(FMResultSet*)dbRows;
    - (id)initWithRows:(FMResultSet*)dbRows;

    ou bien dans ton cas, il faut lui envoyer chaque paramètre (propriété) du modèle récupéré par la seule requête:



    - (id)initWithCodeMarque(int)codeMarque nom:(NSStrong*)nom... etc

    La question, c'est: as-tu besoin de reconstruire les données du modèle ? Ne peux-tu pas mettre tous les champs dans un array de dicos ? ça dépend vraiment de tes besoins.

  • CéroceCéroce Membre, Modérateur

    Je n'ai pas d'expertise sur le sujet, mais il est abordé très largement dans ce livre: 


    Patterns of Enterprise Application Architecture.


Connectez-vous ou Inscrivez-vous pour répondre.