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

 Delphi Discussion :

Utilisation d'une séquence Oracle


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Par défaut Utilisation d'une séquence Oracle
    Bonjour à tous,

    J'ai un petit problème de connaissance. Voilà j'ai une table SUIVISAV oracle, avec une sequence SEQ_NUMSUIVI me permettant d'avoir un clé primaire dans ma table SUIVISAV autoimplémenté...
    Cependant je ne sais pas comment m'en servir sous Delphi pour faire mon ajout dans ma table ...
    Voici mon code :

    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
    procedure TFrmAjoutSAV.btnOkClick(Sender: TObject);
    var
      nomDuScan : String;
    begin
    nomDuScan := '';
    nomDuScan := lblNomScan.Caption;
    
    oqAjoutSav.Close;
    oqAjoutSav.SQL.Clear;
    oqAjoutSav.SQL.Add('INSERT INTO suivisav (numsuivi, numrma, datedepart, dateretour, nomscan, commentaire) VALUES (:numerosuivi, :numerorma, :datededepart, :datederetour, :lenomscan, :com)');
    oqAjoutSav.DeclareAndSet('numerosuivi', otInteger, seq_numsuivi.nextval);
    oqAjoutSav.DeclareAndSet('numerorma', otString, zsNumRma.Text);
    oqAjoutSav.DeclareAndSet('datededepart', otString, zsDateDep.Text);
    oqAjoutSav.DeclareAndSet('datederetour', otString, zsDateRetour.Text);
    oqAjoutSav.DeclareAndSet('lenomscan', otString, nomDuScan);
    oqAjoutSav.DeclareAndSet('com', otString, zsCommentaires.Text);
    oqAjoutSav.Execute;
    oqAjoutSav.Session.Commit;
    
    FrmHistoSav.OracleDataSetHisto.Close;
    FrmHistoSav.OracleDataSetHisto.SQL.Clear;
    FrmHistoSav.OracleDataSetHisto.SQL.Text := 'SELECT * FROM suivisav WHERE nomscan = :nomduscan';
    FrmHistoSav.OracleDataSetHisto.DeclareAndSet('nomduscan', otString, nomDuScan);
    FrmHistoSav.DataSourceHisto.DataSet := FrmHistoSav.OracleDataSetHisto;
    FrmHistoSav.DBGridHisto.DataSource := FrmHistoSav.DataSourceHisto;
    FrmHistoSav.OracleDataSetHisto.Open;
    
    end;
    C'est sur la zone en rose que j'aimerai faire mon ajout et utiliser mon auto implémentation mais comment puis-je faire il faut que je déclare seq_numsuivi ? Il me dit qu'il n'est pas déclaré...

    Help ! Je ne connais pas cette méthode et ne voit pas comment faire malgré mes recherches internet...

    Merci d'avance

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Par défaut
    Après presque une après midi à chercher sur le net j'ai trouvé la solution : je fais auparavant une fonction me permettant de chercher la valeur suivante grâce à un select ... Voici mon code :

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    procedure TFrmAjoutSAV.btnOkClick(Sender: TObject);
    var
      nomDuScan : String;
      nextval : integer;
    begin
    nomDuScan := '';
    nomDuScan := lblNomScan.Caption;
    nextval := RechercheValSuivante(oqRechercheNextVal);
     
     
    oqAjoutSav.Close;
    oqAjoutSav.SQL.Clear;
    oqAjoutSav.SQL.Add('INSERT INTO suivisav (numsuivi, numrma, datedepart, dateretour, nomscan, commentaire) VALUES (:numerosuivi, :numerorma, :datededepart, :datederetour, :lenomscan, :com)');
    oqAjoutSav.DeclareAndSet('numerosuivi', otInteger, nextval);
    oqAjoutSav.DeclareAndSet('numerorma', otString, zsNumRma.Text);
    oqAjoutSav.DeclareAndSet('datededepart', otString, zsDateDep.Text);
    oqAjoutSav.DeclareAndSet('datederetour', otString, zsDateRetour.Text);
    oqAjoutSav.DeclareAndSet('lenomscan', otString, nomDuScan);
    oqAjoutSav.DeclareAndSet('com', otString, zsCommentaires.Text);
    oqAjoutSav.Execute;
    oqAjoutSav.Session.Commit;
     
    FrmHistoSav.OracleDataSetHisto.Close;
    FrmHistoSav.OracleDataSetHisto.SQL.Clear;
    FrmHistoSav.OracleDataSetHisto.SQL.Text := 'SELECT numsuivi, nomscan, numrma, datedepart, dateretour, commentaire FROM suivisav WHERE nomscan = :nomduscan';
    FrmHistoSav.OracleDataSetHisto.DeclareAndSet('nomduscan', otString, nomDuScan);
    FrmHistoSav.DataSourceHisto.DataSet := FrmHistoSav.OracleDataSetHisto;
    FrmHistoSav.DBGridHisto.DataSource := FrmHistoSav.DataSourceHisto;
    FrmHistoSav.OracleDataSetHisto.Open;
     
    zsNumRma.Text := '';
    zsCommentaires.Text := '';
    zsDateDep.Text := '  /  /    ';
    zsDateRetour.Text := '  /  /    ';
     
    end;
     
    function RechercheValSuivante(oqRechercheNextVal : TOracleQuery) : integer;
    begin
    oqRechercheNextVal.Close;
    oqRechercheNextVal.SQL.Clear;
    oqRechercheNextVal.SQL.Text := 'Select SEQ_NUMSUIVI.NEXTVAL FROM Dual';
    oqRechercheNextVal.Execute;
     
    RechercheValSuivante := oqRechercheNextVal.FieldAsInteger(0);
     
    end;

  3. #3
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 002
    Par défaut
    En utilisation concurrentielle, tu pourrais avoir des doublons !

    Tu devais pouvoir écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    oqAjoutSav.SQL.Add('INSERT INTO suivisav (numsuivi, numrma, datedepart, dateretour, nomscan, commentaire) VALUES ((Select SEQ_NUMSUIVI.NEXTVAL FROM Dual), :numerorma, :datededepart, :datederetour, :lenomscan, :com)');
    oqAjoutSav.DeclareAndSet('numerorma', ...
    ou même

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    oqAjoutSav.SQL.Add('INSERT INTO suivisav (numsuivi, numrma, datedepart, dateretour, nomscan, commentaire) VALUES ( SEQ_NUMSUIVI.NEXTVAL, :numerorma, :datededepart, :datederetour, :lenomscan, :com)');
    oqAjoutSav.DeclareAndSet('numerorma', ...
    J'ai fait quelques chose de simailaire en Sybase 10, dans mon INSERT, j'appelle une procédure stockée qui reproduit le comportement du Sequence d'Oracle dont je n'ai pas trouvé d'équivalent


    Le mieux serait d'avoir un TRIGGER ON INSERT, dans lequel tu affectes le SEQUENCE !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #4
    Membre Expert

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    En utilisation concurrentielle, tu pourrais avoir des doublons !
    Non, le NextVal d'Oracle ne renvoie jamais deux fois la même valeur, même dans un contexte concurrentiel. Ensuite les appels suivants à CurrVal retournent la valeur qui a été générée lors du dernier NextVal de la même session.
    De plus, la séquence n'est pas transactionnelle. Si tu annules la transaction qui a appelé le NextVal, le compteur ne retourne pas en arrière pour autant, ce qui évite à Oracle de devoir poser des verrous sur la séquence.

    Celà dit, ça ne change rien au fait qu'il est préférable d'appeler la séquence directement dans l'INSERT ou avec un trigger.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Par défaut
    Youpi !! Merci je l'ai fait directement dans le insert aucun soucis ça fonctionne ^^ merci pour votre aide :

    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
    procedure TFrmAjoutSAV.btnOkClick(Sender: TObject);
    var
      nomDuScan : String;
      nextval : integer;
    begin
    nomDuScan := '';
    nomDuScan := lblNomScan.Caption;
    nextval := RechercheValSuivante(oqRechercheNextVal);
     
     
    oqAjoutSav.Close;
    oqAjoutSav.SQL.Clear;
    oqAjoutSav.SQL.Add('INSERT INTO suivisav (numsuivi, numrma, datedepart, dateretour, nomscan, commentaire) VALUES (SEQ_NUMSUIVI.NEXTVAL, :numerorma, :datededepart, :datederetour, :lenomscan, :com)');
    //oqAjoutSav.DeclareAndSet('numerosuivi', otInteger, nextval);
    oqAjoutSav.DeclareAndSet('numerorma', otString, zsNumRma.Text);
    oqAjoutSav.DeclareAndSet('datededepart', otString, zsDateDep.Text);
    oqAjoutSav.DeclareAndSet('datederetour', otString, zsDateRetour.Text);
    oqAjoutSav.DeclareAndSet('lenomscan', otString, nomDuScan);
    oqAjoutSav.DeclareAndSet('com', otString, zsCommentaires.Text);
    oqAjoutSav.Execute;
    oqAjoutSav.Session.Commit;
     
    FrmHistoSav.OracleDataSetHisto.Close;
    FrmHistoSav.OracleDataSetHisto.SQL.Clear;
    FrmHistoSav.OracleDataSetHisto.SQL.Text := 'SELECT numsuivi, nomscan, numrma, datedepart, dateretour, commentaire FROM suivisav WHERE nomscan = :nomduscan';
    FrmHistoSav.OracleDataSetHisto.DeclareAndSet('nomduscan', otString, nomDuScan);
    FrmHistoSav.DataSourceHisto.DataSet := FrmHistoSav.OracleDataSetHisto;
    FrmHistoSav.DBGridHisto.DataSource := FrmHistoSav.DataSourceHisto;
    FrmHistoSav.OracleDataSetHisto.Open;
     
    zsNumRma.Text := '';
    zsCommentaires.Text := '';
    zsDateDep.Text := '  /  /    ';
    zsDateRetour.Text := '  /  /    ';
     
    end;

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 002
    Par défaut
    Citation Envoyé par Franck SORIANO Voir le message
    Non, le NextVal d'Oracle ne renvoie jamais deux fois la même valeur, même dans un contexte concurrentiel.
    D'accord, à chaque récupération, la valeur est consommée, tu peux donc avoir des "trous" si tu n'utilises pas la valeur.
    Chez un de mes anciens employeurs, le SQL était ré-interprété et le NextVal était simulé car les applis tournait sur Oracle 9/10 et SQL Server 2000, c'était une fonction très lente qui renvoyait la dernière valeur utilisée d'où ma méprise !
    Comme quoi ré-inventer la roue carrée ... c'est pas une bonne idée !
    Merci de m'avoir corriger

    Ce qui différent de la fonction que j'ai reproduit en Sybase car elle renvoie la première valeur libre (donc bouche les trous, comme il n'y pas bcp d'enregistrement, cela reste rapide, je n'ai pas choisi cette méthode d'indexation numérique, c'est le comportement standard de l'appli que je maintiens, je respecte ses conventions)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre Expert

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Ce qui différent de la fonction que j'ai reproduit en Sybase car elle renvoie la première valeur libre (donc bouche les trous, comme il n'y pas bcp d'enregistrement, cela reste rapide, je n'ai pas choisi cette méthode d'indexation numérique, c'est le comportement standard de l'appli que je maintiens, je respecte ses conventions)
    Ca dépend de ce dont tu as besoin. Pour un identifiant interne, on se fiche des trous dans la numérotation. Donc une séquence en Oracle, ou un Identity en SQL Server conviennent parfaitement.
    Si tu veux un compteur pour des numéros de facture, il ne doit pas y avoir de trou dans la numérotation (et l'ordre des numéros doit respecter l'ordre des dates de facturation...).
    La séquence n'est plus une solution acceptable puisqu'il faut qu'elle reparte en arrière en cas de rollback de la transaction.

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

Discussions similaires

  1. Utiliser une séquence Oracle
    Par robinson50 dans le forum Développement de jobs
    Réponses: 3
    Dernier message: 14/08/2009, 22h29
  2. Accès à une séquence oracle
    Par coco21 dans le forum JDBC
    Réponses: 2
    Dernier message: 10/05/2007, 12h07
  3. utilisation d'une séquence
    Par marcusien dans le forum Oracle
    Réponses: 3
    Dernier message: 27/02/2007, 13h14
  4. Gestion d'une séquence oracle
    Par mikky dans le forum Hibernate
    Réponses: 2
    Dernier message: 18/01/2007, 11h15
  5. [Oracle] utilisation d'une séquence
    Par magic charly dans le forum Langage SQL
    Réponses: 4
    Dernier message: 20/04/2006, 09h39

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