Précédent   Forum des professionnels en informatique > Bases de données > Firebird > SQL
SQL Forum d'entraide sur le SQL pour Firebird
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 20/11/2007, 17h54   #1
Membre chevronné
 
Avatar de luta
 
Inscription : novembre 2003
Messages : 1 038
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 1 038
Points : 691
Points : 691
Envoyer un message via MSN à luta
Par défaut creation d un generateur via une procedure

Bonsoir je souhaite pouvoir creer un générateur dans une procédure sql
type
Code :
1
2
3
4
5
6
7
8
9
CREATE PROCEDURE NEW_PROCEDURE1(
  GENNAME VARCHAR(80),
  INCREMENT SMALLINT)
AS
BEGIN
  CREATE GENERATOR GENANME;
  SUSPEND;
END
;
voir meme s il est possible de tester l existence de ce générateur et de le créer si ce n est pas le cas puis de l interroger.
Est ce possible via sql?

merci beaucoup j y connais rien du tout a firebird...Et puis c est pas très documenté faut dire
luta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2007, 18h08   #2
Modérateur
 
Avatar de Cl@udius
 
Homme Claude Renouleaud
Développeur informatique
Inscription : février 2006
Messages : 4 760
Détails du profil
Informations personnelles :
Nom : Homme Claude Renouleaud
Âge : 49
Localisation : France, Hautes Pyrénées (Midi Pyrénées)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2006
Messages : 4 760
Points : 6 790
Points : 6 790
Salut

C'est possible via un EXECUTE STATEMENT:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
SET TERM ^ ;
 
CREATE PROCEDURE NEW_PROCEDURE1 (
    GENNAME VARCHAR(80),
    INCREMENT SMALLINT)
AS
BEGIN
  EXECUTE STATEMENT 'CREATE GENERATOR ' || :GENNAME;
  EXECUTE STATEMENT 'SET GENERATOR ' || :GENNAME || ' TO ' || :INCREMENT;
END^
 
SET TERM ; ^
Nota:
Le suspend n'est d'aucune utilité puisque que ta PS n'a pas de paramètres de sortie.

Pour tester la présence du générateur, tu peux faire un select sur la table système RDB$GENERATORS.

@+ Claudius
__________________
A la question technique que par MP/MV tu formuleras, la réponse aux oubliettes finira.
Cl@udius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2007, 18h18   #3
Membre chevronné
 
Avatar de luta
 
Inscription : novembre 2003
Messages : 1 038
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 1 038
Points : 691
Points : 691
Envoyer un message via MSN à luta
si je fais un select alors que le generateur n existe pas, le script ne va pas planter j espere...
merci beaucoup pour t on aide je vais implémenter cela de suite )

petite question au passage...SET TERM ^ca sert a quoi?
luta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2007, 18h36   #4
Modérateur
 
Avatar de Cl@udius
 
Homme Claude Renouleaud
Développeur informatique
Inscription : février 2006
Messages : 4 760
Détails du profil
Informations personnelles :
Nom : Homme Claude Renouleaud
Âge : 49
Localisation : France, Hautes Pyrénées (Midi Pyrénées)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2006
Messages : 4 760
Points : 6 790
Points : 6 790
Citation:
Envoyé par luta Voir le message
petite question au passage...SET TERM ^ca sert a quoi?
qi130 a répondu à cette question aujourd'hui ici

@+
__________________
A la question technique que par MP/MV tu formuleras, la réponse aux oubliettes finira.
Cl@udius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 09h43   #5
Membre chevronné
 
Avatar de luta
 
Inscription : novembre 2003
Messages : 1 038
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 1 038
Points : 691
Points : 691
Envoyer un message via MSN à luta
ok, en résumé ça permet de faire une transaction quoi
luta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 09h45   #6
Membre chevronné
 
Avatar de luta
 
Inscription : novembre 2003
Messages : 1 038
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 1 038
Points : 691
Points : 691
Envoyer un message via MSN à luta
Pour ma procedure stockée, j aimerais qu elle me renvoie un integer mais
1/ je ne vois pas l interet de suspend de totue façon.
2/ etant une procédure stockée et non pas une fonction, comment puis je récupérer la valeur de retour de cette procédure? (typiquement le select du generateur)

Vraiment désolé pour toutes ces questions pourries mais firebird c est vraiment spécial pour moi
j'ai bossé sur Oracle, sql server, mySql et rien ne ressemble a Firebird je trouve
luta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 09h57   #7
Membre chevronné
 
Avatar de luta
 
Inscription : novembre 2003
Messages : 1 038
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 1 038
Points : 691
Points : 691
Envoyer un message via MSN à luta
oups désolé j avais pas vu dans la FAQ, vraiment abruti moi
donc ok pour le select de la procédure
merci beaucoup pour ton aide
luta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 10h04   #8
Modérateur
 
Avatar de Cl@udius
 
Homme Claude Renouleaud
Développeur informatique
Inscription : février 2006
Messages : 4 760
Détails du profil
Informations personnelles :
Nom : Homme Claude Renouleaud
Âge : 49
Localisation : France, Hautes Pyrénées (Midi Pyrénées)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2006
Messages : 4 760
Points : 6 790
Points : 6 790
Salut

Je me pose cette question: quelle est la finalité de cette PS ?
Récupérer la valeur courante du générateur ?

@+
__________________
A la question technique que par MP/MV tu formuleras, la réponse aux oubliettes finira.
Cl@udius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 10h27   #9
Membre chevronné
 
Avatar de luta
 
Inscription : novembre 2003
Messages : 1 038
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 1 038
Points : 691
Points : 691
Envoyer un message via MSN à luta
non,
elle doit récupérer la valeur du générateur, la valeur finale après incrément (paramètre), et surtout créer ce même générateur si celui-ci n existe pas.
Des objets vont etre créer a la volée et je voudrais ne pas me soucier de l 'existence ou pas de tel ou tel générateur via PHP (déja que j ai du mal via firebird tout seul)...
voici le code (qui marche pas bien sur de ce que j ai pondu pour le moment
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE PROCEDURE CONSOMME_PARTIES(
  JEUID SMALLINT,
  LOTID INTEGER,
  NBPARTIES INTEGER)
RETURNS(
  IDDEBUT INTEGER,
  IDFIN INTEGER)
AS
DECLARE VARIABLE GENNAME VARCHAR(30);
BEGIN
  GENANME=CAST(JEUID AS VARCHAR(10))||'_'|| CAST(LOTID AS VARCHAR(10));
  IF(NOT EXISTS(EXECUTE STATEMENT 'GEN_ID('||:GENNAME||', 0)')){
    EXECUTE STATEMENT 'CREATE GENERATOR ' || :GENNAME;
    EXECUTE STATEMENT 'SET GENERATOR ' || :GENNAME || ' TO ' || 0;
  }
  IDDEBUT=EXECUTE STATEMENT 'GEN_ID('||:GENNAME||', 0)';
  IDFIN=EXECUTE STATEMENT 'GEN_ID('||:GENNAME||', '||CAST(NBPARTIES AS VARCHAR(10))||')';
 
  SUSPEND;
END
;
luta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 11h07   #10
Modérateur
 
Avatar de Cl@udius
 
Homme Claude Renouleaud
Développeur informatique
Inscription : février 2006
Messages : 4 760
Détails du profil
Informations personnelles :
Nom : Homme Claude Renouleaud
Âge : 49
Localisation : France, Hautes Pyrénées (Midi Pyrénées)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2006
Messages : 4 760
Points : 6 790
Points : 6 790
J'ai du mal à saisir ce que doit être la valeur de retour de IDFIN.
La valeur actuelle du générateur + le nombre de parties ?
Ce qui serait IDFIN = IDDEBUT + NBPARTIES.

@+
__________________
A la question technique que par MP/MV tu formuleras, la réponse aux oubliettes finira.
Cl@udius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 11h33   #11
Membre chevronné
 
Avatar de luta
 
Inscription : novembre 2003
Messages : 1 038
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 1 038
Points : 691
Points : 691
Envoyer un message via MSN à luta
tout a fait,
en fait on a pas trop confiance en les transactions
on a un peu peur qu au niveau accés concurrent on se "partage" des id donc du coup prend la plage d id dont on a besoin avec un générateur puis on fait les insertions tranquilement apres dans la base.
Maintenant je comprend vraiment pas pourquoi ma procédure n est pas créé et vu que les messages d erreurs ne sont pas vraiemnt très explicites...
as tu une idée?
luta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 11h37   #12
Modérateur
 
Avatar de Cl@udius
 
Homme Claude Renouleaud
Développeur informatique
Inscription : février 2006
Messages : 4 760
Détails du profil
Informations personnelles :
Nom : Homme Claude Renouleaud
Âge : 49
Localisation : France, Hautes Pyrénées (Midi Pyrénées)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2006
Messages : 4 760
Points : 6 790
Points : 6 790
Essaye comme ceci:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
BEGIN
  /* Nom du générateur */
  GENNAME = CAST(JEUID AS VARCHAR(10)) || '_' || CAST(LOTID AS VARCHAR(10));
  /* Vérifier sa présence */
  IF (NOT EXISTS(SELECT RDB$GENERATOR_NAME
                 FROM RDB$GENERATORS
                 WHERE RDB$GENERATOR_NAME = :GENNAME AND
                       RDB$SYSTEM_FLAG = 0))
  THEN
    BEGIN
      /* Création du générateur */
      EXECUTE STATEMENT 'CREATE GENERATOR ' || :GENNAME;
      IDDEBUT = 0;
    END
  ELSE
    /* Lire la valeur actuelle du générateur */
    EXECUTE STATEMENT 'SELECT GEN_ID(' || :GENNAME || ', 0) FROM RDB$DATABASE INTO' || :IDDEBUT;
 
  IDFIN = IDDEBUT + NBPARTIES;
 
  SUSPEND;
END
Je ne l'ai testé !

@+
__________________
A la question technique que par MP/MV tu formuleras, la réponse aux oubliettes finira.
Cl@udius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 12h12   #13
Membre chevronné
 
Avatar de luta
 
Inscription : novembre 2003
Messages : 1 038
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 1 038
Points : 691
Points : 691
Envoyer un message via MSN à luta
ça marche nickel
la seule modif que j ai faite vient du code de fin
EXECUTE STATEMENT 'SELECT GEN_ID(' || :GENNAME || ', 0) FROM RDB$DATABASE INTO' || :IDDEBUT;
EXECUTE STATEMENT 'SELECT GEN_ID(' || :GENNAME || ', '|| :NBPARTIES ||') FROM RDB$DATABASE INTO' || :IDfin;

car au prochain appel j aurai besoin que le générateur soit déja incrémenté.
Je te remercie beaucoup pour ton aide ça me fait vraiment beaucoup avancer.
En espérant ne plus trop avoir de soucis
luta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 12h14   #14
Modérateur
 
Avatar de Cl@udius
 
Homme Claude Renouleaud
Développeur informatique
Inscription : février 2006
Messages : 4 760
Détails du profil
Informations personnelles :
Nom : Homme Claude Renouleaud
Âge : 49
Localisation : France, Hautes Pyrénées (Midi Pyrénées)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2006
Messages : 4 760
Points : 6 790
Points : 6 790
Citation:
Envoyé par luta Voir le message
Je te remercie beaucoup pour ton aide ça me fait vraiment beaucoup avancer.
En espérant ne plus trop avoir de soucis
Avec plaisir , et n'hésite pas au prochain soucis...

@+ Claudius
__________________
A la question technique que par MP/MV tu formuleras, la réponse aux oubliettes finira.
Cl@udius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 12h26   #15
Membre chevronné
 
Avatar de luta
 
Inscription : novembre 2003
Messages : 1 038
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 1 038
Points : 691
Points : 691
Envoyer un message via MSN à luta

me suis un peu trop avancé...
voici ce que j ai fait en utilisant sql manager lite for firebird (ma version de firebird est 1.5.3)
la compile: OK
apres je l appelle ainsi (comme cité dans la FAQ)
select IDDEBUT,IDFIN FROM consomme_parties(1, 2, 3)

réponse:
Code :
1
2
3
4
5
Can't format message 13:896 -- message file C:\Program Files\EMS\firebird.msg not found.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 1, column 39.
RDB$DB_KEY.
ce qui en françasi veut certianement dire quelque chose...
mais le pire c 'est que je ne peux plus recompiler la procédure en m affichant une message box:
"there is an error in input field 'procedure body' "
message d erreur en bas:
Precompiler Error: Syntax error - STATEMENT
...je voies pas pourquoi puisqu a vant il n y en avait pas mais je supose que tant qu on a pas executé la procédure, on ne peut pas savoir si les requetes dynamiques fonctionnent...

le problème est que l erreur n explique rien en soi, et surtout que meme en dropant ma proc, je ne peux plus la recréer...

les joies de firebird
tu as une idée?

j ai essayé de trafiquer les requetes EXECUTE STATEMENT mais ça donne pas grand chose,
je pense queça vient des liens que la proc créée avec la table des generateurs mais après...
luta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 14h10   #16
Modérateur
 
Avatar de Cl@udius
 
Homme Claude Renouleaud
Développeur informatique
Inscription : février 2006
Messages : 4 760
Détails du profil
Informations personnelles :
Nom : Homme Claude Renouleaud
Âge : 49
Localisation : France, Hautes Pyrénées (Midi Pyrénées)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2006
Messages : 4 760
Points : 6 790
Points : 6 790
Resalut

Bon j'ai révisé ma copie

Essaye comme ceci:
Code :
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
 
CREATE PROCEDURE CONSOMME_PARTIES (
    JEUID SMALLINT,
    LOTID INTEGER,
    NBPARTIES INTEGER)
RETURNS (
    IDDEBUT INTEGER,
    IDFIN INTEGER)
AS
DECLARE VARIABLE STMT VARCHAR(1024);
DECLARE VARIABLE GENNAME VARCHAR(40);
BEGIN
  GENNAME = 'GEN_' || CAST(JEUID AS VARCHAR(10)) || '_' || CAST(LOTID AS VARCHAR(10));
 
  IF (NOT EXISTS(SELECT RDB$GENERATOR_NAME
                 FROM RDB$GENERATORS
                 WHERE RDB$GENERATOR_NAME = :GENNAME AND
                       RDB$SYSTEM_FLAG = 0))
  THEN
    EXECUTE STATEMENT 'CREATE GENERATOR ' || GENNAME;
 
  STMT = 'SELECT GEN_ID(' || :GENNAME || ', 1) FROM RDB$DATABASE';
  EXECUTE STATEMENT :STMT INTO :IDDEBUT;
  NBPARTIES = NBPARTIES - 1;
  STMT = 'SELECT GEN_ID(' || :GENNAME || ', ' || :NBPARTIES || ') FROM RDB$DATABASE';
  EXECUTE STATEMENT :STMT INTO :IDFIN;
 
  SUSPEND;
END
@+
__________________
A la question technique que par MP/MV tu formuleras, la réponse aux oubliettes finira.
Cl@udius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 14h23   #17
Membre chevronné
 
Avatar de luta
 
Inscription : novembre 2003
Messages : 1 038
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 1 038
Points : 691
Points : 691
Envoyer un message via MSN à luta
meme resultat j arrive a compiler apres j ai le message
Can't format message 13:896 -- message file C:\Program Files\EMS\firebird.msg not found.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 1, column 37.
RDB$DB_KEY.

peut etre que l outil que j utilise n est pas adapté...
je crois que je vais faire la chose en php...
luta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 14h24   #18
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 215
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

Informations professionnelles :
Activité : Consultant spécialité Firebird
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 2 215
Points : 3 318
Points : 3 318
je ne comprend pas bien tes salades
mais
1/ les générateurs sont hors transaction et donc un GEN_ID(MON_GEN, 1) donnera toujours une valeur unique
2/
Citation:
en fait on a pas trop confiance en les transactions
Pardon ?
si c'est ça autant utiliser SqlLite!
Sinon le code serait plutot (cf note de version de Firebird 1.5 où execute statement est clairement expliqué) :
Code :
1
2
EXECUTE STATEMENT 'SELECT GEN_ID(' || GENNAME || ', 0) FROM RDB$DATABASE INTO' || :IDDEBUT;
EXECUTE STATEMENT 'SELECT GEN_ID(' || GENNAME || ', '|| NBPARTIES ||') FROM RDB$DATABASE INTO' || :IDfin;
sans les deux points devant les variables car comme le dit la doc :
Citation:
The 'EXECUTE STATEMENT' DSQL string cannot contain any parameters in any syntax variation.
All variable substitution into the static part of the SQL statement should be performed before the execution
of EXECUTE STATEMENT.
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 15h40   #19
Membre chevronné
 
Avatar de luta
 
Inscription : novembre 2003
Messages : 1 038
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 1 038
Points : 691
Points : 691
Envoyer un message via MSN à luta
Citation:
1/ les générateurs sont hors transaction et donc un GEN_ID(MON_GEN, 1) donnera toujours une valeur unique
--oui c est pour ça que je souhaite utiliser le générateur d ailleurs...
du coup on utilise pas les transactions pour éviter de faire des insert qui pourrait 'se croiser', typiquement a chaque interrogation il est primordial qu une plage d id soit occupée d ou l utilisation du generateur

merci pour la précision mais le script semble planter sur toutes lignes contenant des EXECUTE STATEMENT et avec ou sans les ":" ça revient au même
luta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 16h30   #20
Expert Confirmé

 
Homme Philippe Makowski
Consultant spécialité Firebird
Inscription : mai 2002
Messages : 2 215
Détails du profil
Informations personnelles :
Nom : Homme Philippe Makowski
Âge : 49
Localisation : France

Informations professionnelles :
Activité : Consultant spécialité Firebird
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 2 215
Points : 3 318
Points : 3 318
je n'aime pas l'idée de créer un objet à la volée, mais voilà :

Code :
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
SET TERM  ^^ ;
CREATE PROCEDURE CONSOMME_PARTIES (
  JEUID SmallInt,
  LOTID Integer,
  NBPARTIES Integer)
 returns (
  IDDEBUT BigInt,
  IDFIN BigInt) AS
BEGIN
  SUSPEND;
END
 ^^
SET TERM ;  ^^
SET TERM  ^^ ;
ALTER PROCEDURE CONSOMME_PARTIES (
  JEUID SmallInt,
  LOTID Integer,
  NBPARTIES Integer)
 returns (
  IDDEBUT BigInt,
  IDFIN BigInt) AS
DECLARE VARIABLE STMT VARCHAR(1024);
DECLARE VARIABLE GENNAME VARCHAR(40);
DECLARE VARIABLE TEST INTEGER;
begin
  GENNAME = 'GEN_' || CAST(JEUID AS VARCHAR(10)) || '_' || CAST(LOTID AS VARCHAR(10));
 
  SELECT COUNT(*)
                 FROM RDB$GENERATORS
                 WHERE RDB$GENERATOR_NAME = :GENNAME AND
                       RDB$SYSTEM_FLAG = 0 INTO :TEST;
  IF (TEST = 0)
  THEN
    EXECUTE STATEMENT 'CREATE GENERATOR ' || GENNAME;
 
  STMT = 'SELECT GEN_ID(' || GENNAME || ', 1) FROM RDB$DATABASE';
  EXECUTE STATEMENT STMT INTO :IDDEBUT;
  NBPARTIES = NBPARTIES - 1;
  STMT = 'SELECT GEN_ID(' || GENNAME || ', ' || NBPARTIES || ') FROM RDB$DATABASE';
  EXECUTE STATEMENT STMT INTO :IDFIN;
 
  SUSPEND;
end ^^
SET TERM ;  ^^
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h07.


 
 
 
 
Partenaires

Hébergement Web