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

Bases de données Delphi Discussion :

filtre dbgrid avec sql


Sujet :

Bases de données Delphi

  1. #1
    Membre à l'essai
    Homme Profil pro
    retraité
    Inscrit en
    Octobre 2011
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Octobre 2011
    Messages : 87
    Points : 21
    Points
    21
    Par défaut filtre dbgrid avec sql
    Bonjour
    pouvez vous m'orienter (aide) svp
    je viens de m'intersser à delphi pour réaliser une application de gestion, mais là je bute sur sql, et ce pour filtrer une dbgrid sur 02 champs: voila le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ADOQuery1.Active := false ;
    ADOQuery1.SQL.Text := 'SELECT * FROM table1 WHERE année='+QuotedStr(combobox3.Text)+ 'and situation ='+QuotedStr(edit3.Text);
    ADOQuery1.Active := true ;
    form1.Edit1.Text := IntToStr(ADOQuery1.RecordCount);
    une fois compilé aucun résultas, même pas un message d'erreur...!
    merci pour votre aide.

  2. #2
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Bonjour,
    Citation Envoyé par kasrimus Voir le message
    une fois compilé aucun résultas, même pas un message d'erreur...!
    C'est à dire ? Rien ne s'affiche ? Avez vous tracé le code pour être sur qu'il est réellement exécuté ?
    Sinon, j'éviterais de construire votre requête comme vous l'avez fait. J'utiliserais des paramètres, cela éviterait tout problème de conversion de type lors de l'évaluation de la requête et peut être des résultats autres que ceux attendus...
    J'écrirais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ADOQuery1.Active := False;
    ADOQuery1.SQL.Text := 'SELECT * FROM table1 WHERE année = :PAnnee  and situation = :PSituation';
    ADOQuery1.Parameters.ParamValues['PAnnee'] := ComboBox3.Text;
    ADOQuery1.Parameters.ParamValues['PSituation'] := Edit3.Text;
    ADOQuery1.Active := True ;
    // form1.Edit1.Text := IntToStr(ADOQuery1.RecordCount);
    // Le code est très certainement dans une méthode de la classe TForm1,
    // aussi, éviter d'appeler une variable d'instanciation de cette classe,
    // mais utiliser Self
    Self.Edit1.Text := IntToStr(ADOQuery1.RecordCount);
    La colonne "année", c'est pour l'exemple car je ne suis pas sur qu'ADO apprécie....
    Dernière chose, n'oubliez pas à l'avenir de préciser quelle moteur de base de données vous utilisez.
    Philippe.

  3. #3
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Salut

    Essai ceci :

    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
    With ADOQuery do
    begin
      Sql.Clear;
      Sql.Add('SELECT * FROM table1 ');
      Sql.Add('Where Année= :xAnnée ');
      Sql.Add('And Situation= :xSituation ');
      Parameters.ParamByName('xAnnée').DataType := ftString;
      Parameters.ParamByName('xSituation').DataType := ftString;
      Parameters.ParamByName('xAnnée').Value := combobox3.Text;
      Parameters.ParamByName('xSituation').Value := edit3.Text;
      Try
       Open;
       Edit1.Text := IntToStr(RecordSet.RecordCount);
      Finally
       Close;
      end;
     
    end;

    Grillé par Ph. lloll

  4. #4
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Citation Envoyé par BuzzLeclaire Voir le message
    Grillé par Ph. lloll
    Meuh non...
    De plus, l'approche sur les paramètres est plus précise que celle que j'avais donnée.
    Philippe.

  5. #5
    Membre à l'essai
    Homme Profil pro
    retraité
    Inscrit en
    Octobre 2011
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Octobre 2011
    Messages : 87
    Points : 21
    Points
    21
    Par défaut filtre dbgrid avec sql
    Bonsoir
    Oh...! Merci pour vos réponse, je suis vraiment très touché c'est gentil de votre part.
    S'agissant de mon problème, je effectué les corrections (code) toujour le même problème rien ne s'affiche, par contre quand je filtre sur un seul champ ca marche :
    code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ADOQuery1.Active := false ;
    ADOQuery1.SQL.Text := 'SELECT * FROM table1 WHERE année='+QuotedStr(combobox3.Text);
    ADOQuery1.Active := true ;
    form1.Edit1.Text := IntToStr(ADOQuery1.RecordCount);
    base de donnée access 2007 delphi 2010
    merci encore pour l'aide.

  6. #6
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Citation Envoyé par kasrimus Voir le message
    S'agissant de mon problème, je effectué les corrections (code) toujour le même problème rien ne s'affiche, par contre quand je filtre sur un seul champ ca marche :
    Quand vous filtrez seulement sur l'autre colonne ? ça fonctionne ?
    Êtes vous sur que le jeu d'essai doit renvoyer une réponse à vos conditions de filtre ?
    Philippe.

  7. #7
    Membre à l'essai
    Homme Profil pro
    retraité
    Inscrit en
    Octobre 2011
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Octobre 2011
    Messages : 87
    Points : 21
    Points
    21
    Par défaut filtre dbgrid avec sql
    Bonsoir
    effectivement, quand je filtre uniquement sur un champ cela fonctionne.
    je vous remercie bien pour l’intérêt que vous accorder à mon problème
    Merci

  8. #8
    Membre actif
    Inscrit en
    Décembre 2004
    Messages
    390
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 390
    Points : 288
    Points
    288
    Par défaut
    Peut être qu'il n y a aucun enregistrement qui reponde aux 2 critères en même temps !

    Vérifiez votre jeu d'essai comme ç'a été dit par Ph.B

  9. #9
    Membre à l'essai
    Homme Profil pro
    retraité
    Inscrit en
    Octobre 2011
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Octobre 2011
    Messages : 87
    Points : 21
    Points
    21
    Par défaut Filtre dbgrid avec sql
    Bonsoir,
    oui c'est vérifié, le code ne répond pas.
    SVP, comment déclarer les paramètres.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ADOQuery1.Parameters.ParamValues['PAnnee'] := ComboBox3.Text;
    ADOQuery1.Parameters.ParamValues['PSituation'] := Edit3.Text;
    pouvez vous svp m'expliquer ces lignes merci
    Merci.

  10. #10
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Bonjour,
    Citation Envoyé par kasrimus Voir le message
    SVP, comment déclarer les paramètres.
    Reprenez mon message antérieur, il y a la requête SQL correspondant à ces paramètres...
    Citation Envoyé par kasrimus Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ADOQuery1.Parameters.ParamValues['PAnnee'] := ComboBox3.Text;
    ADOQuery1.Parameters.ParamValues['PSituation'] := Edit3.Text;
    pouvez vous svp m'expliquer ces lignes merci
    Une requête avec des paramètres évite de la reconstruire (ainsi que son plan d’exécution par le moteur de bases de données) à chaque changement de valeur de ces paramètres. Elle évite également les attaques par injection de code SQL.
    les 2 lignes servent à définir le contenu des paramètres qui seront transmis au moteur de bases de données.
    Exemple:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    select NOM, PRENOM from PERSONNE where DATE_NAIS = :DateNais
    Au lieu de réécrire la requête à chaque changement de valeur de date de naissance, on se contentera de transmettre la nouvelle valeur du paramètre puis on ré-exécutera la requête sans la ressaisir d'où l'instruction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ADOQuery1.Parameters.ParamValues['DateNais'] := MaVariableDate;
    Philippe.

  11. #11
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    en plus des avantages sus-cités par Phillipe , je rajouterais qu'avec une requête paramétrée on ne se souciera plus du format de la date (dans le cas de son dernier SQL)
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  12. #12
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2010
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2010
    Messages : 192
    Points : 71
    Points
    71
    Par défaut Filtre dbgrid avec sql
    Salut tous le monde et merci pour l'aide précieuse que vous nous données!

    je suis d’accord avec Kasrimus sur le fait que la requette ne marche pas, il ne reconnait pas le annee, il vous demande de déclaré ses variables.

    pour information j'utilise des base de donnée oracle avec delphi 7 et 10, en à besoin de l'aide des professionnelles

  13. #13
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    et un pro vous demandera de nous fournir la structure de la table que vous voulez interroger via SQL .

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    'SELECT * FROM table1 WHERE année = :PAnnee  and situation = :PSituation';
    si année est un INTEGER combobox3.text lui est un string , est-ce que cela vous mets la puce à l'oreille ?

    comme l'a suggéré BuzzLeclair , un typage du paramètre peu rendre des services
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Parameters.ParamByName('PAnnee').DataType := ftInteger;
    aurait lever une erreur lorsque à ligne suivante vous faites ceci (enfin je pense je ne maitrise pas ADO)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ADOQuery1.Parameters.ParamValues['PAnnee'] := ComboBox3.Text;
    rapidement corrigé par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ADOQuery1.Parameters.ParamValues['PAnnee'] := StrToIntDef(ComboBox3.Text,0);
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  14. #14
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2010
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2010
    Messages : 192
    Points : 71
    Points
    71
    Par défaut Filtre dbgrid ans sql
    Salut,

    SergioMaster j'ai utiliser ses exemples donner par les amis mais lors du lancement du programme il génere des erreur ou il dit de ne pas reconnaitre année par exemple parsqu'il n'est pas déclarer, es possible d'avoir un exemple déja essaier et executé sans erreur, pour information je travail en DELPHI avec une base de donnée oracle et tous mes champs son en STRING.

  15. #15
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Les codes fournis par Ph.B. ou BuzzLeclair sont parfaitement fonctionnels . Un seul reproche peut être l'utilisation de caractères accentués ce que personnellement je ne fait jamais (sauf pour les affichages et éditions Utilisateurs) .

    Je l'ai déjà dit , pour pouvoir corriger d'éventuelles erreurs , il faut davantage de renseignements
    on connait le SGDB : ORACLE
    mais la version de Delphi ?
    la structure de la table ?

    tous mes champs sont en STRING.
    outre le fait que cela me semble une faute de conception pour un champ ANNEE et que le type STRING n'existe pas en ORACLE , du moins en built-in ou encore aux normes ANSISQL , que dire .....
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  16. #16
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2010
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2010
    Messages : 192
    Points : 71
    Points
    71
    Par défaut Filtre dbgrid avec sql
    Salut,

    Alors voila j'utilise oracle comme base de donnée à distance via un client j'ai tous les privilèges, Delphi 2010 Français comme langage de programmation, un exemple de ma chaîne SQL :

    'Select Numassure,nom,prenom,naissance,centre from linc.secu_Ass where numassure='
    Tous ses champs sont en [STRING]

    je voudrais utilisé Parameters.ParamValues['Numassure'] := Edit1.Text;

    mon bute et d'évité l'utilisation des quoted ' ' ' ' ' ' avec Edit1.text

    Merci de votre aide!!!!!

  17. #17
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    la syntaxe est différente selon les composants , au départ cette discussion était avec un ADOQuery avec un TQuery cela pourrait donner quelque chose de ce genre avec un TQuery posé sur la fiche.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Query1.Active:=False;
    Query1.SQL.Clear;
    Query1.SQL.Add('SELECT Numassure,nom,prenom,naissance,centre');
    Query1.SQL.Add('from linc.secu_Ass');
    Query1.SQL.Add('where numassure=:n'); 
    Query1.ParamByName('n').asString:=Edit1.text;
    Query1.Active:=True;
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  18. #18
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2010
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2010
    Messages : 192
    Points : 71
    Points
    71
    Par défaut Filtre dbgrid avec sql
    Salut tous le monde, est je remercie tous qui ont participé ce se sujet.

    Je remercie surtout [SergioMaster] et [Buzleclair] de leur aide précieuse et je confirme que cette solution donnée par les amis et après le test que j'ai fait elle marche très bien, il y'a qu'il faut faire la différence entre ADOQUERY et TQUERY elle change au niveau des Paramètre exemple :

    1 - Pour ADOQUERY il faut mettre:
    ADOQUERY1.Parameters.ParamByName('xnom').Value := edit1.Text;
    2 - pour TQUERY ca change faite attention:
    Qry1.ParamByName('xnom').asString := edit1.text;

    Il faut ne pas oublier les guillemets à mettre dans parambyname de la variable. ici dans l'exemple 'xnom', bonne chance à tous.

  19. #19
    Membre à l'essai
    Homme Profil pro
    retraité
    Inscrit en
    Octobre 2011
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Octobre 2011
    Messages : 87
    Points : 21
    Points
    21
    Par défaut Filtre dbgrid avec sql
    Bonsoir
    j'ai toujours pas réglé mon problème, svp est ce possible de m'orienter svp
    merci d'avance

  20. #20
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2010
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2010
    Messages : 192
    Points : 71
    Points
    71
    Par défaut Filtre dbgrid avec sql
    Salut,

    donne t'a requête pour voir ou sa ne va pas?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Filtre glissant en SQL avec la fonction decode
    Par jerem7w dans le forum SQL
    Réponses: 4
    Dernier message: 09/01/2012, 12h06
  2. DBgrid avec champs de recherche et filtre
    Par thered dans le forum Composants VCL
    Réponses: 9
    Dernier message: 20/06/2009, 03h19
  3. Réponses: 4
    Dernier message: 26/02/2008, 09h55
  4. Alimenter DBgrid avec requete SQL ?
    Par La_Bande_A_Zozo dans le forum C++Builder
    Réponses: 5
    Dernier message: 31/05/2006, 17h51
  5. Delete on cascade avec SQL server
    Par fadoua dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 14/01/2004, 11h02

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