IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQLite Discussion :

Insert bdd "SQL error: no such function: read"


Sujet :

SQLite

  1. #1
    Membre confirmé
    Inscrit en
    Juin 2006
    Messages
    96
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 96
    Par défaut Insert bdd "SQL error: no such function: read"
    Bonjour à toutes et à tous

    J'essaye depuis maintenant plusieurs jours (4 ou 5) à faire une insertion dans une base de données sqlite (celle des SMS du iPhone). il me sort l'erreur :

    SQL error: no such function: read
    Quand j'essaye de touvher à la table "message" alors que les autres table RAS

    Il me semble que cela vient d'un trigger (grâce a l'aide que j'ai vu sur le net) .

    Quelqu'un à une idée pour faire l'insert dans la base???

    Merci de vos réponse ou de vos indice.

  2. #2
    Membre expérimenté

    Inscrit en
    Décembre 2004
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 169
    Par défaut
    Bonjour,

    ta question est trop vague, je n'ai pas la base dont tu parles donc je ne peux t'aider sans plus d'information.

    Mais, bon, disons que tu tentes d'écrire dans la base suivante :
    /var/mobile/Library/SMS/sms.db

    Si c'est le cas, alors je te conseille de dumper totalement la base à l'aide de la commande ".dump" depuis une session DOS (si tu extrais la base vers un Windows) ou un shell sous Linux. Ainsi tu auras la structure des tables et le source des triggers.

    Dernière chose, l'erreur sur le read n'est-elle pas une erreur sur la commande ".read" ? Sinon, je ne vois pas.

    Ha, au fait, si la table est du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    create table message (
      ROWID integer primary key,
      adress text,
      date integer,
      'text' text,
      flags integer
    );
    Alors tentes un insert du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    insert into message (adress,date,text,flags)
    values ('moi',1205535790,'Un essai', 2);
    Si tu as des exemples sous la main, utilises des valeurs plus proches de la réalité pour faire tes tests.

    a+

  3. #3
    Membre confirmé
    Inscrit en
    Juin 2006
    Messages
    96
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 96
    Par défaut
    Salut merci pour le ".dump" sa peu aider

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    CREATE TABLE message (
    ROWID INTEGER PRIMARY KEY AUTOINCREMENT,
    address TEXT,
    date INTEGER,
    text TEXT,
    flags INTEGER,
    replace INTEGER,
    svc_center TEXT,
    group_id INTEGER,
    association_id INTEGER,
    height INTEGER,
    UIFlags INTEGER,
    version INTEGER);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    INSERT INTO message VALUES(
    7,
    'Le téléphone',
    1222242268,
    'Message',
    3,
    0,
    NULL,
    2,
    1222242268,
    38,
    0,
    0);
    Il me donne toujours l'erreur "SQL error: no such function: read"
    je ne comprend pas pourquoi?

    Je donne les triggers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CREATE TRIGGER insert_unread_message AFTER INSERT ON message WHEN NOT read(new.flags) BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) + 1 WHERE ROWID = new.group_id; END;
     
    CREATE TRIGGER mark_message_unread AFTER UPDATE ON message WHEN read(old.flags) AND NOT read(new.flags) BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) + 1 WHERE ROWID = new.group_id; END;
     
    CREATE TRIGGER mark_message_read AFTER UPDATE ON message WHEN NOT read(old.flags) AND read(new.flags) BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) - 1 WHERE ROWID = new.group_id; END;
     
    CREATE TRIGGER delete_message AFTER DELETE ON message WHEN NOT read(old.flags) BEGIN UPDATE msg_group SET unread_count = (SELECT unread_count FROM msg_group WHERE ROWID = old.group_id) - 1 WHERE ROWID = old.group_id; END;
     
    CREATE TRIGGER insert_newest_message AFTER INSERT ON message WHEN new.ROWID >= IFNULL((SELECT MAX(ROWID) FROM message WHERE message.group_id = new.group_id), 0) BEGIN UPDATE msg_group SET newest_message = new.ROWID WHERE ROWID = new.group_id; END;
    En fait je développe un programme pour envoyer des SMS depuis le PC vers le iPhone en SSH donc c'est dommage car il n'est pas possible de voir les SMS qui ont été envoyé depuis le programme.

  4. #4
    Membre expérimenté

    Inscrit en
    Décembre 2004
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 169
    Par défaut
    Ho, désolé je n'avais pas remarqué que personne n'avait répondu...

    Bon, tu as la réponse à ta question dans les triggers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TRIGGER insert_unread_message 
    AFTER INSERT ON message WHEN NOT READ(new.flags) 
    BEGIN 
      UPDATE msg_group SET unread_count = (
        SELECT unread_count 
        FROM msg_group 
        WHERE ROWID = new.group_id
      ) + 1 WHERE ROWID = new.group_id; 
    END;
    Ainsi, le trigger fait appel à une fonction externe READ.
    On pourrait la résumer en C de cette façon :
    int READ( int flag) {
    if ( flag == 1 ) {
    return true;
    }
    return false;
    }
    Evidemment j'ai mis n'importe quoi dans la fonction mais c'est un exemple. Je pense que la fonction READ vérifie si le flag contient une certaine valeur lorsque le message a été lu par l'utilisateur du portable et retourne vrai si c'est le cas.

    Tu dois donc étudier les données de la base pour comprendre les valeurs du flag et trouver le cas où il signale que le message a été lu.
    Ensuite tu devras créer une fonction READ() ou read() que tu intégreras dans les sources de SQLite. Cette fonction peut être aussi basique que celle que je t'ai écrite. Il y a de nombreux exemples en ligne, alors l'écriture de cette fonction devrait être très rapide et facile.
    Pour finir, soit tu intègreras les nouveaux sources dans ton projet, soit tu créeras une dll selon ta méthode de travail.

    Tu pourras alors tester la base avec tes outils et vérifier la réaction du téléphone.

    Tu peux également créer une fonction externe que tu lieras à l'exécutable SQLite3.exe ou son équivalent sous Linux avec la commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    .load FILE ?ENTRY?     Load an extension library
    Ainsi, tu pourras charger la fonction READ() depuis une DLL et tester la base en simulant le comportement de READ.

    Dernière solution : tu shuntes la fonction READ en réécrivant les triggers.
    Supposons que le bit du flag qui détermine si le message est lu est le premier de l'entier, soit le bit n° 0 (donc flag and (1<<0) doit donner 1 si il le message est lu).
    READ(new.flags) devient ( (new.flag & 1) == 1 ). Si c'est le bit numéro 3, on aurait :
    ( (new.flag & (1<<3) ) == 1 )

    Voyons ce que cela donne dans les triggers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    DROP TRIGGER insert_unread_message;
    CREATE TRIGGER insert_unread_message AFTER INSERT ON message 
    -- WHEN NOT READ(new.flags) 
    WHEN NOT ((new.flag & (1<<3)) == 1)
    BEGIN 
      UPDATE msg_group SET unread_count = (
        SELECT unread_count FROM msg_group WHERE ROWID = new.group_id) + 1 
        WHERE ROWID = new.group_id; 
    END;
     
    DROP TRIGGER mark_message_unread;
    CREATE TRIGGER mark_message_unread AFTER UPDATE ON message 
    -- WHEN READ(old.flags) AND NOT READ(new.flags) 
    WHEN ((old.flag & (1<<3)) == 1) AND NOT ((new.flag & (1<<3)) == 1)
    BEGIN UPDATE msg_group SET unread_count = (
      SELECT unread_count FROM msg_group 
      WHERE ROWID = new.group_id
      ) + 1 WHERE ROWID = new.group_id; 
    END;
     
    DROP TRIGGER mark_message_read;
    CREATE TRIGGER mark_message_read AFTER UPDATE ON message 
    -- WHEN NOT READ(old.flags) AND READ(new.flags) 
    WHEN NOT ((old.flag & (1<<3)) == 1) AND ((new.flag & (1<<3)) == 1)
      BEGIN UPDATE msg_group SET unread_count = (
        SELECT unread_count FROM msg_group WHERE ROWID = new.group_id
        ) - 1 WHERE ROWID = new.group_id; 
    END;
     
    DROP TRIGGER delete_message;
    CREATE TRIGGER delete_message AFTER DELETE ON message 
    -- WHEN NOT READ(old.flags) 
    WHEN NOT ((old.flag & (1<<3)) == 1)
    BEGIN 
      UPDATE msg_group SET unread_count = (
        SELECT unread_count FROM msg_group WHERE ROWID = old.group_id
        ) - 1 WHERE ROWID = old.group_id; 
    END;
    Voilà, voilà,
    Bon amusement,
    a+

  5. #5
    Membre confirmé
    Inscrit en
    Juin 2006
    Messages
    96
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 96
    Par défaut
    Merci beaucoup de ta réponse qui me sera très utile dans un futur proche (maintant dodo ) je teste demain et je te dit. sinon j'avais penser a effacer les triger, faire l'insertion puis les remettre.

    Mais ce n'est pas propres.

    J'approfondis sa demain.

    A bientôt

  6. #6
    Membre confirmé
    Inscrit en
    Juin 2006
    Messages
    96
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 96
    Par défaut
    Re en rajoutant un trigger cela fonctionne.(je comprend pas oute la structure de la table mais bon je me débrouille).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE TRIGGER hack_svc_center AFTER INSERT ON message BEGIN UPDATE message SET svc_center=NULL WHERE ROWID=new.ROWID; END;
    J'ai trouvé ce code il y a 2 ou 3 jours il fonctionne pour les inserts. Maintenant reste le programme à développer.

    Merci de ton aide à bientôt.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Encore et toujours: odbc_connect() [function.odbc-connect]: SQL error: [Oracle][ODBC][Ora]ORA-12705
    Par dufeu.celine dans le forum Connexions aux bases de données
    Réponses: 7
    Dernier message: 27/07/2011, 23h36
  2. Problème Insertion BDD SQL Server
    Par drake56 dans le forum C#
    Réponses: 13
    Dernier message: 19/07/2011, 11h20
  3. Réponses: 1
    Dernier message: 01/07/2010, 10h50
  4. Réponses: 4
    Dernier message: 13/04/2004, 19h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo