Passer un tableau en paramètre d'une procedure stockée [Oracle/PL-SQL] - SQL/NoSQL - Programmation
Marsh Posté le 02-07-2004 à 16:13:01
Ils viennent d'où tes enregistrements?
Marsh Posté le 02-07-2004 à 16:20:57
skeye a écrit : Ils viennent d'où tes enregistrements? |
de ton cul évidemment
Ils viennent de données entrées par l'utilisateur (enfin, pas saisies à la main, mais c'est tout comme).
Marsh Posté le 02-07-2004 à 16:34:46
1) oui.
2) je sais plus
3) les ADOs c'est des trucs de pédophiles
Marsh Posté le 02-07-2004 à 16:36:37
skeye a écrit : Ils viennent de données entrées par l'utilisateur (enfin, pas saisies à la main, mais c'est tout comme). |
Tu veux dire qu'un utilisateur est capable de saisir plus d'un millier d'enregistrements à la suite avec ses propres pieds
Marsh Posté le 02-07-2004 à 16:38:35
Ummon a écrit : Tu veux dire qu'un utilisateur est capable de saisir plus d'un millier d'enregistrements à la suite avec ses propres pieds |
Je t'arrête tout de suite, j'ai jamais écrit ça!
Marsh Posté le 02-07-2004 à 16:39:18
Ummon a écrit : Tu veux dire qu'un utilisateur est capable de saisir plus d'un millier d'enregistrements à la suite avec ses propres pieds |
c'est peut-être des données entrées en 20 ans, qui sait ?
Marsh Posté le 02-07-2004 à 16:44:46
Ummon a écrit : Tu veux dire qu'un utilisateur est capable de saisir plus d'un millier d'enregistrements à la suite avec ses propres pieds |
JagStang a écrit : c'est peut-être des données entrées en 20 ans, qui sait ? |
L'origine des données n'est pas le problème
Marsh Posté le 02-07-2004 à 16:45:59
nraynaud a écrit : 1) oui. |
1) cool
2) dommage
3) Je n'ai pas souvenir de ces faits monsieur le juge
Marsh Posté le 02-07-2004 à 23:02:13
Je suppose que chaque entrée du tableau de ton programme VB contiendrait la donnée à insérer dans ta base, et que dans ta procédure stockée, tu prends chaque entrée de ce tableau, et tu l'INSERT dans ta base.
Le client Oracle de Microsoft ne permet pas de passer des tableaux en argument à des procédures stockées (ou alors j'ai jamais réussi à y arriver, mais dans ce cas je suis pas le seul)
La meilleure solution, est de mettre toutes les entrées de ton tableau dans une grande chaine de caractères, séparées par des virgules, puis de passer cette chaine en argument à une procédure stockée.
Puis, dans la procédure stockée, il faudra que tu parses cette chaine pour séparer les données, en utilisant la virgule comme séparateur. Puis réalise ton INSERT pour chaque donnée extraite.
Tu peux parser la chaine en utilisant les fonctions INSTR, SUBSTR, LTRIM et RTRIM de PL/SQL.
Bref, bon courage, c'est pas simple
Marsh Posté le 02-07-2004 à 23:19:34
merci, je vais voir ce que je peux faire avec ça.
Marsh Posté le 02-07-2004 à 23:23:45
dans mes rechrches sur google, je suis tombé sur cet article:
http://www.databasejournal.com/fea [...] hp/3318791
avec les méthodes qu'il donne, je pense avoir trouvé le moyens d'envoyer des tableaux de valeurs en paramètre d'une procedure stockée, je testerai ça lundi matin
Marsh Posté le 02-07-2004 à 23:26:31
ça a l'air sympa
si tu y arrives, poste le code de ta procédure, ça m'intéresse
Marsh Posté le 03-07-2004 à 01:16:12
HappyHarry a écrit : tu peux pas utiliser un type de données TABLE ? |
Vu que je veux insérer des valeurs qui ne sont pas dans la base, je ne pense pas, mais si tu as une méthode pour faire ça, je suis à l'écoute.
Marsh Posté le 03-07-2004 à 13:26:15
ben tu peux passer un argument de types "table d'entier" en parametre d'une proc, ce qui correspond a un tableau
Marsh Posté le 03-07-2004 à 13:35:16
Comment je fais ça avec les ADO ?
Marsh Posté le 03-07-2004 à 13:45:49
ca c'est une autre histoire
j'avais essayé en ASP un jour, j'avais pas réussi
Marsh Posté le 05-07-2004 à 17:09:49
Bonne nouvelle: J'ai réussi \o/
Mauvaise nouvelle: C'est 4 à 5 fois plus lent en utilisant des tableaux /o\
Si ça vous intéresse, je poste le code qui permet tout ça.
Marsh Posté le 05-07-2004 à 17:51:14
CREATE TABLE TABLETEST |
Code VB:
Code :
|
Requete envoyée à Oracle:
BEGIN |
Marsh Posté le 06-07-2004 à 09:01:00
ça intéresse qqn si je poste les différences de perfs selon la méthode utilisée ou bien je laisse mourir ce topic tranquillement ?
Marsh Posté le 06-07-2004 à 09:10:20
non vas-y envoie
Marsh Posté le 06-07-2004 à 10:04:48
Pour 100000 insertions:
|
lexique:
-sans rien: execute les requêtes d'insertion une par une.
-Blocs: execute toutes les requêtes d'insertion en une seule fois dans un bloc BEGIN ... END;
-Transaction: exetute les requêtes dans une transaction.
-Proc: utilise une procedure stockee pour faire l'insert (un insert par procedure)
-proc + tableaux: utilise une procedure stockee qui prend un tableau en paramètre (tous les insert d'un seul coup).
Marsh Posté le 06-07-2004 à 10:06:38
résultats impressionnants... surtout en tre 1004 et 40 s...
Marsh Posté le 06-07-2004 à 10:07:09
merci en tout cas
Marsh Posté le 06-07-2004 à 10:09:04
JagStang a écrit : résultats impressionnants... surtout en tre 1004 et 40 s... |
t'en as sauté un
proc : 1881,984 s. |
Marsh Posté le 06-07-2004 à 10:10:24
je compare pas le meilleur et le moins bon résultat. Mais des résultats qui me semblaient comparable,
Transaction + proc : 1004,984 s.
Blocs + Transaction + proc : 40,640 s.
Marsh Posté le 06-07-2004 à 10:21:14
OK.
Moralité, les tests cai bon, mangézen
Marsh Posté le 07-07-2004 à 10:21:13
Marsh Posté le 10-07-2004 à 03:37:09
Pense bête:
1-delete de tout les couples IDAFFPH/IDTYPEH à insérer/updater (une seule reqête, aucun risque d'erreur)
2-Passage de l'IDETAT à 3 sur toutes les asso contenant un IDAFFPH à insérer/updater (une seule reqête, aucun risque d'erreur)
3-Insérer les couples IDAFFPH/IDTYPEH à insérer/updater
Marsh Posté le 17-11-2004 à 21:22:16
Quelqu'un a déjà utilisé le FORALL ? Notre DBA m'en a parlé aujourd'hui et ça a l'air d'être le moyen idéal de faire ce que je cherche à faire.
je testerai ça quand j'aurais le temps.
plus d'infos:
http://tahiti.oracle.com/pls/tahit [...] tion=48873
Marsh Posté le 17-11-2004 à 23:35:48
ça a l'air cool, je connaissais pas du tout
Marsh Posté le 18-11-2004 à 17:36:21
mareek a écrit : L'origine des données n'est pas le problème |
Bah si c'est un problème.
Parceque si tu peux passer par une table ou un truc similaire, il suffit que ta requête accepte une "table" (ou "curseur" ) en paramètre, et tu lances :
select maFonction(select mesdonnes from matable)
Marsh Posté le 18-11-2004 à 17:38:55
mareek a écrit : Bonne nouvelle: J'ai réussi \o/ |
arf
Marsh Posté le 18-11-2004 à 17:42:27
Relis le topic, ça t'évitera de débarquer 6 mois après avec une non solution
Marsh Posté le 19-11-2004 à 21:25:28
J'ai fait des tests avec le FORALL, mais je trouve des résultats bizarre
J'en parle à mon DBA lundi et je vous tiens au courant
Marsh Posté le 22-11-2004 à 20:45:50
Après avoir corrigé le bug monstrueux dans mon programme de test (:ange, j'ai enfin des résultats cohérents (toujours pour 100000 insertions):
|
(j'ai changé de serveur de test depuis les tests précédents)
Le gain apporté par le FORALL est donc assez intéressant. Et il y a de fortes chances pour que les écrats soient encore plus important dans la pratique vu que ma table de test n'est pas indexée et que le FORALL est censé gagner un temps precieux sur l'indexation.
A noter egallement que l'utilisation des objets en PL/SQL fait chuter les perfs de manière vertigineuse.
Procedures stockées utilisées pour l'insertion via tableaux(Simple):
|
Procedures stockées utilisées pour l'insertion via tableaux(Simple)+ ForAll:
CREATE OR REPLACE PROCEDURE TestInsertArrayFORALL(ARRAY_ID IN ARRAY_INT,ARRAY_NOM IN ARRAY_STR) |
Prochaine étape: regarder comment utiliser un FORALL avec des séquences.
Marsh Posté le 23-11-2004 à 14:37:30
tomlameche a écrit : Question bête : pourquoi tu utilises pas sqlloader ? |
sûrement à cause de ça:
http://forum.hardware.fr/hardwaref [...] tm#t785112
Marsh Posté le 02-07-2004 à 15:43:23
Je dois insérer un grand nombre d'enregistrement (plusieurs dizaines de milliers) dans une table à la suite. Pour optimiser cette opération, j'ai pensé à utiliser une procedure stockée qui prendrait un tableau (ou une collection ou n'importe quoi d'approchant) en paramètres plutot que d'appeller 20000 fois la même procedure.
1)Est-ce possible ?
2)Si oui, Comment dois-je m'y prendre ?
3)1+2 via les composants ADO ?
D'avance merci
---------------
"I wonder if the internal negative pressure in self pumping toothpaste tubes is adjusted for different market altitudes." John Carmack