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 17/05/2007, 22h04   #1
Rédacteur/Modérateur
 
Avatar de sjrd
 
Homme Sébastien Doeraene
Ingénieur développement logiciels
Inscription : juin 2004
Messages : 4 500
Détails du profil
Informations personnelles :
Nom : Homme Sébastien Doeraene
Âge : 22
Localisation : Belgique

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2004
Messages : 4 500
Points : 7 873
Points : 7 873
Par défaut [Rand] Eviter les résultats similaires sous FB 1.5

Bonjour,

Je dois pouvoir générer des ID de session aléatoires dans une procédure stockée, sous la forme de chaînes de 16 chiffres hexadécimaux.

Pour ça, j'ai codé la procédure stockée suivante :
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
CREATE PROCEDURE RandomString (
  ValidChars VARCHAR(255) CHARACTER SET ASCII,
  StrLength INTEGER
)
RETURNS (
  RandStr VARCHAR(255) CHARACTER SET ASCII
)
AS
 
DECLARE VARIABLE Len SMALLINT;
DECLARE VARIABLE RandInt SMALLINT;
BEGIN
  RandStr = '';
  Len = StrLen(ValidChars);
 
  WHILE (StrLength > 0) DO
  BEGIN
    RandInt = Floor(Len*Rand()) + 1;
    IF (RandInt <= StrLength) THEN -- avoiding Rand returning 1
    BEGIN
      RandStr = RandStr || SubStr(ValidChars, RandInt, RandInt);
      StrLength = StrLength - 1;
    END
  END
 
  SUSPEND;
END
Le problème, c'est que les appels répétés à Rand() en peu de temps donnent le même résultat plusieurs fois de suite. J'obtiens des chaînes comme :
Code X :
1
2
3
5555555555522200
CCCC999555533000
9999999776333210
Bref pas très aléatoire

En cosultant ib_udf2.sql, on trouve :
Citation:
Note: The rand() function was changed in Firebird 2.0 so that the seed value is not set by every call. This corrects a potential duplicate value problem and ensures that different values will always be returned.

To seed the random number generator or retain the old behaviour, use srand().
Mais mon hébergeur travaille sous Firebird 1.5, et ne m'autorise pas l'utilisation de mes propres UDFs.

Y a-t-il un moyen d'éviter ces répétitions ? Forcer des pertes de temps entre deux appels ?

d'avance
__________________
sjrd, rédacteur/modérateur Delphi
Les règles du forum tu liras et tu respecteras.
Ainsi ami des modos tu seras...

Mis à jour le 6 mai 2012 : découvrez FunLabyrinthe v5.3 : un jeu de labyrinthe gratuit et personnalisable à l'infini avec des scripts Delphi-like.
Découvrez aussi Sepi, un moteur de script orienté objet pour Delphi.

Mes tutoriels
sjrd est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/05/2007, 15h44   #2
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
en ajoutant l'appel à un generateur ?
cela garantira l'unicité
__________________
Philippe Makowski
IBPhoenix - Firebird
Membre de l'April
makowski est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/05/2007, 16h20   #3
Rédacteur/Modérateur
 
Avatar de sjrd
 
Homme Sébastien Doeraene
Ingénieur développement logiciels
Inscription : juin 2004
Messages : 4 500
Détails du profil
Informations personnelles :
Nom : Homme Sébastien Doeraene
Âge : 22
Localisation : Belgique

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2004
Messages : 4 500
Points : 7 873
Points : 7 873
Citation:
Envoyé par makowski
en ajoutant l'appel à un generateur ?
cela garantira l'unicité
Ca marche super



Pour la postérité, mon nouveau code :
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
CREATE PROCEDURE RandomString (
  ValidChars VARCHAR(255) CHARACTER SET ASCII,
  StrLength INTEGER
)
RETURNS (
  RandStr VARCHAR(255) CHARACTER SET ASCII
)
AS
 
DECLARE VARIABLE Len SMALLINT;
DECLARE VARIABLE RandInt SMALLINT;
BEGIN
  RandStr = '';
  Len = StrLen(ValidChars);
 
  WHILE (StrLength > 0) DO
  BEGIN
    RandInt = GEN_ID(SessionIDGenerator, 1) * Floor(Len*Rand());
    RandInt = Mod(RandInt, Len) + 1;
    RandStr = RandStr || SubStr(ValidChars, RandInt, RandInt);
    StrLength = StrLength - 1;
  END
 
  SUSPEND;
END
__________________
sjrd, rédacteur/modérateur Delphi
Les règles du forum tu liras et tu respecteras.
Ainsi ami des modos tu seras...

Mis à jour le 6 mai 2012 : découvrez FunLabyrinthe v5.3 : un jeu de labyrinthe gratuit et personnalisable à l'infini avec des scripts Delphi-like.
Découvrez aussi Sepi, un moteur de script orienté objet pour Delphi.

Mes tutoriels
sjrd est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h38.


 
 
 
 
Partenaires

Hébergement Web