Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1733 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [Oracle]Mise à jour de clé étrangère aléatoire

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Oracle]Mise à jour de clé étrangère aléatoire

n°2008054
electricbl​ue
Pas très inspiré...
Posté le 08-07-2010 à 14:40:06  profilanswer
 

Bonjour,
 
Je suis sous Oracle, et j'ai un petit problème de "random".
 
Pour faire simple, voici mes tables de travail :

Code :
  1. CREATE TABLE DEPARTEMENT
  2.   (
  3.     "ID"               NUMBER(10,0) NOT NULL ENABLE,
  4.     "NAME"          VARCHAR2(100 CHAR) NOT NULL ENABLE
  5.   )

 

Code :
  1. CREATE TABLE EMPLOYE
  2.   (
  3.     "ID"               NUMBER(10,0) NOT NULL ENABLE,
  4.     "NAME"          VARCHAR2(100 CHAR) NOT NULL ENABLE,
  5.     "DEPT"          NUMBER(10,0)
  6.   )


"DEPT" est une clé étrangère vers la table "DEPARTEMENT".
Je voudrais mettre à jour, de manière aléatoire, ce champ pour tous les employés.
 
Pour tirer une ligne au hasard de la table "DEPARTEMENT", j'utilise :

Code :
  1. SELECT id
  2. FROM
  3.   ( SELECT id FROM DEPARTEMENT ORDER BY dbms_random.value
  4.   )
  5. WHERE rownum = 1;


Ce qui me renvoie bien un id différent à chaque exécution.
Pour la mise à jour de ma clé étrangère, j'utilise :

Code :
  1. UPDATE EMPLOYEE
  2. SET DEPT =
  3.   (SELECT did
  4.   FROM
  5.     (SELECT d.id AS did
  6.     FROM DEPARTEMENT d
  7.     ORDER BY dbms_random.value
  8.     )
  9.   WHERE rownum = 1
  10.   );


Malheureusement, toutes les lignes sont mises à jour avec la même clé, et non pas de manière aléatoire. Apparemment la génération de la clé aléatoire n'est faite qu'une seule fois alors que je voudrais qu'elle le soit pour chaque employé.
Comment faire alors??
 
Merci d'avance pour vos réponses :)

mood
Publicité
Posté le 08-07-2010 à 14:40:06  profilanswer
 

n°2008191
Oliiii
Posté le 09-07-2010 à 08:10:54  profilanswer
 

Je suppose qu'en Oracle, tout comme en SQL server, le random n'est evalué qu'une seule fois par query, donc tu es plus ou moins condamné a faire l'operation row by row dans une boucle.
 
Un moyen pour forcer la fonction random a etre recalculée a chaque fois est de lui donner un seed different (ici tu peux lui filler ton ID) mais la distribution statistique des données ne sera plus vraiment correcte (ca n'a peut etre pas d'importance pour toi).


Message édité par Oliiii le 09-07-2010 à 08:11:21
n°2008198
Oliiii
Posté le 09-07-2010 à 08:34:16  profilanswer
 

Bon ben j'ai trouvé une autre facon en SQL Server:

Code :
  1. UPDATE #tmpTable
  2.     SET DEPT = ABS(CHECKSUM(NEWID())) % 5


 
NEWID() retourne un GUID, donc ca doit exister sous Oracle
CHECKSUM retourne un INT
ABS pour avoir la valeur absolue
et le % c'est pour faire un modulo pour limiter les valeures (ici entre 0 et 5).
 
Les valeures sont assez bien répartie, meme si c'est pas aussi bon qu'un row by row random.

n°2008719
Sve@r
Posté le 11-07-2010 à 18:37:02  profilanswer
 

Oliiii a écrit :

et le % c'est pour faire un modulo pour limiter les valeures (ici entre 0 et 5).


Il est communément admis que cette méthode ne donne pas un aléatoire toujours uniformisé.
Il est conseillé, en programmation, de faire plutôt
n=random() * max / RANDMAX
La constante "RANDMAX" étant la valeur maximale que peut renvoyer la fonction random()...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°2008864
electricbl​ue
Pas très inspiré...
Posté le 12-07-2010 à 16:28:39  profilanswer
 

Bonjour et merci pour vos réponses
 
Pour répondre à la question de l'importance de l'aléatoire : peu importe, je veux juste répartir les gens dans les départements pour des besoins de test.
 
Après concernant le bout de code : si je comprends bien, ça retourne un nombre aléatoire entre 0 et n, mais le problème c'est qu'il peut y avoir des "trous" dans les id des départements, et qu'en plus je ne dois utiliser que certains départements (via une condition where).
 
Apparemment la seule solution est de faire une boucle (même si je pensais pas que c'était si compliqué à faire ce genre de choses).
 
Merci encore pour vos réponses :)

n°2011142
electricbl​ue
Pas très inspiré...
Posté le 22-07-2010 à 19:03:41  profilanswer
 

Bon, avec un peu de retard, je mets une solution que j'ai trouvée pour faire ce que je voulais. Ya surement plus simple, mais comme je m'y connais pas en pl/sql, j'ai pris le premier exemple de boucle que j'ai trouvé :
 

Code :
  1. DECLARE
  2.   CURSOR emp
  3.   IS
  4.     SELECT * FROM EMPLOYE;
  5. BEGIN
  6.   FOR oneEmp IN emp
  7.   LOOP
  8.     UPDATE EMPLOYE emp0
  9.     SET dept =
  10.       (SELECT did
  11.       FROM
  12.         (SELECT d.id AS did FROM DEPARTEMENT d ORDER BY dbms_random.value
  13.         )
  14.       WHERE rownum = 1
  15.       )
  16.     WHERE emp0.id = oneEmp.id;
  17.   END LOOP;
  18. END;
  19. /


 
Si jamais ça peut vous aider :)

n°2016984
JeffyJeff
Posté le 15-08-2010 à 09:30:35  profilanswer
 

C'est très bien mais tu n'as pas besoin de ramener toute la table dans ton curseur. SELECT id from EMPLOYE devrait suffire.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [Oracle]Mise à jour de clé étrangère aléatoire

 

Sujets relatifs
Remplissage clé étrangèreUrgent SQL vers Oracle
[CSS] problème de mise en pageProblème de mise à jours avec une requête Microsoft Query
mise à jour de liste déroulante sous access 2007[RESOLU] mysql_query("UPDATE ce met à jour mais remplace au lieu...
Oracle 10g vers Oracle 10g via SSIS 2005[java] mise en forme Panels et JButtons
oracle utiliser la même table pour lire .... 
Plus de sujets relatifs à : [Oracle]Mise à jour de clé étrangère aléatoire


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR