PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV 2024 → SQL multi INSERT
SQL multi INSERT
Débuté par Bioley Léal, 20 avr. 2015 16:32 - 18 réponses
Posté le 20 avril 2015 - 16:32
Bonjour,

Juste une question: c'est moi qui ai mal lu (Voir ci-dessous) ou HExécuteRequêteSQL n'est pas capable de gérer une requête INSERT multiple de type:
INSERT INTO user (id, nom) VALUES ('1', 'toto'), ('2', 'tata'), ('3', 'tutu');

Rassurez moi, c'est moi qui m'y prend mal. En 2015 sa devrait être interdit une base de donnée qui ne gère pas sa!

15'000 records = 15'000 Requêtes INSERT ???

Meilleures salutations

Léal

http://doc.pcsoft.fr/fr-FR/?2034001#NOTE3
(Sous WinDev, l'instruction INSERT est mono-tuple : il ajoute un seul enregistrement à la fois. La requête suivante n'est pas acceptée)
Membre enregistré
18 messages
Posté le 20 avril 2015 - 17:09
Bonjour,

Je n'est pas tester, mais depuis la version20 c'est possible :

http://doc.pcsoft.fr/fr-FR/?2034001#NOTE3

Nouveauté 20
3 produits dans un fichier PRODUIT :

Insert INTO PRODUIT
VALUES ('Ref01', 'Eau minérale'), ('Ref02', 'Beurre'), ('Ref03', 'Eponge')


Cordialement
Posté le 20 avril 2015 - 17:12
Bonjour

Je ne sais pas si HFSQL gere le multi INSERT mais pour 15000 enregistrement tu vas construire une chaine avec tes 15000 données ?

j'espère que tu n'as pas d'image ni de mémos !

ce qui prend du temps lors de l'ajout dans l'ajout de la DB c'est la mise à jour des index, voilà une solution qui va accélérer considérablement ton traitement

http://blogs.pcsoft.fr/post.awp…

tu peux aussi combiner cela avec de tâches parallèles : voir le support de cours du dernier TDFTECH

et tu verra que tes 15000 records tu les verras pas passer..

Bon Dev
Marc Fastre
www.marc-fastre.be
Posté le 20 avril 2015 - 17:20
Merci.

Sa ne m'arrange pas car je dois bosser en 19. Mais je ne comprend pas quelque chose:

Je n'ai utilisé qu'une seul fois HyperFile (Il y a bien longtemps) et j'étais assez vite arrivé à la conclusion " A ne pas utiliser" mais comment font les gens qui l'utilise dans ce genre de cas? 1'000 enregistrement = 1'000 requête? (Je dois faire installer de la fibre optique? ;-) ) Je pose la question car c'est mon cas. Je DOIS développer en WD19 et sur HF (Sa ne m'arrange pas du tout) car l'application est déjà en place.

(Si il n'y a pas de solution, j'espère ne jamais être réincarné en switch dans une entreprise utilisant HF en version inférieur à la 20 ;-) )

C'est tout de même bizarre car la norme SQL (ISO/CEI 9075) date de 1986 sa fais quand même un bon bout de temps!

Il n'y a pas une petite commande H magique pour le faire?

Merci beaucoup pour ta réponse.

Léal
Posté le 20 avril 2015 - 17:30
Bonjour Marc,

Merci pour ta réponse.

Oui je préfère largement envoyer une seule requête de 15'000 records car de toute façon elle sera plus courte que 15'000 requêtes de 1 record (Dans tout les cas, toute les données devront transiter par le réseau) sans compter tout le temps perdu par le réseau. Du reste, lors d'un select le serveur ne fais pas 1 paquet par record mais t’envoie bel et bien toutes les données d'un coup. Si tu as plusieurs poste qui travaille de la sorte, je n'aimerais pas être à la place de la carte réseau du serveur.

Je te remercie pour l'astuce du HEcrit. Je ne suis vraiment pas habitué aux ordres H sa fais un bout de temps que je ne laisse plus Windev gérer les accès à la base de donnée mais que j'utilise des dll externe en c#. Windev fait très bien son travail mais de cette manière, j'ai en moyenne 20-30% de temps de traitement en moins.

Salutations et merci encore.

Léal
Posté le 20 avril 2015 - 17:36
Bonjour

moi, ca fait 20 ans que je développe en wlanguage, à 99% avec HF
(classique d'abord puis C/S), et je n'ai JAMAIS eu besoin de ca.

Une simple boucle avec un hjoute fait très bien le boulot dans un temps
TRES raisonnable (je parles de la vrai vie, la, pas du nombre d'anges
sur une tête d'épingle)

Si on a VRAIMENT besoin d'aller plus vite, le truc du hecrit dans la
boucle avec reindexation est la pour ca...

Je ne sais pas sur quoi tu t'étais basé pour arriver à ton " A ne pas
utiliser", mais je dois dire que je suis en désaccord COMPLET. Les seuls
arguments valide que j'ai entendu en 20 ans pour utiliser une autre base
ont été :
- le client me l'impose
- je suis habitué à travailler comme ca

Quand à la norme XXX de 1986, elle est sans doute parfaire, mais ca n'a
pas empêché chaque éditeur de base de données d'implémenter un langage
SQL avec une syntaxe différente... Vive les normes...

Cordialement


--
Fabrice Harari
Consultant WinDev, WebDev et WinDev Mobile International

NOUVEAU: WXReplication, votre système de réplication open source est
disponible sur mon site web !!!
WXShowroom.com : Montrez vos projets !
Plus d'information sur http://fabriceharari.com


On 4/20/2015 9:20 AM, "Bioley Léal" wrote:
Merci.

Sa ne m'arrange pas car je dois bosser en 19. Mais je ne comprend pas
quelque chose:

Je n'ai utilisé qu'une seul fois HyperFile (Il y a bien longtemps) et
j'étais assez vite arrivé à la conclusion " A ne pas utiliser" mais
comment font les gens qui l'utilise dans ce genre de cas? 1'000
enregistrement = 1'000 requête? (Je dois faire installer de la fibre
optique? ;-) ) Je pose la question car c'est mon cas. Je DOIS développer
en WD19 et sur HF (Sa ne m'arrange pas du tout) car l'application est
déjà en place.

(Si il n'y a pas de solution, j'espère ne jamais être réincarné en
switch dans une entreprise utilisant HF en version inférieur à la 20 ;-) )

C'est tout de même bizarre car la norme SQL (ISO/CEI 9075) date de 1986
sa fais quand même un bon bout de temps!

Il n'y a pas une petite commande H magique pour le faire?

Merci beaucoup pour ta réponse.

Léal
Membre enregistré
240 messages
Popularité : +3 (3 votes)
Posté le 21 avril 2015 - 08:41
J'ai tendance à être d'accord avec Bioley Léal. Dans le cas d'une insertion cela peut être pratique d'avoir un "batch" de requêtes.
Il existe cela en Java (et à mon avis en .NET aussi) et cela fait gagner pas mal de temps (http://vincent-lecomte.blogspot.be/2013/07/java-executer-un-lot-de-requetes-sql.html) ; après évidemment il faut gérer tout le reste autour, annuler les insertions en cas de problème, etc. Sur des bases de données externes, cela serait un plus. Pourquoi parce qu'on ne s'en sert pas depuis 20 ans cela n'est-il pas une bonne idée ? Ce genre d'évolution n'est pas un mal bien au contraire, donc pourquoi s'en priver ?

--
Vincent
Membre enregistré
240 messages
Popularité : +3 (3 votes)
Posté le 21 avril 2015 - 08:50
(Le INSERT multiple étant une bonne idée également, ici je parlais de batch ce qui n'est pas exactement la même méthode)

--
Vincent
Posté le 21 avril 2015 - 10:08
Bonjour,

Selon les tests que j'ai effectué, même réseau, même serveur, même client, même données, en ce qui concerne l'ajout d'enregistrement dans la même table HF/CS est déjà bien plus véloce que SQL serveur, de plus si tu utilises un hecrit et ensuite un hreindexe, donc voilà pourquoi le problème se pose moins un HFCS

J'ai essayé de désactiver le mécanisme de gestion des index sur SQL serveur mais impossible d'y ajouter un record

Maintenant chacun son choix, j'utiliserais SQL multi INSERT pour insérer quelques records ( 5 -10 ) ca peut être sympa de l'exécuter en une seule requête, mais de là à construire requête en chaine pour y définir les données de 15000 record c'est autre chose...

Bon Dev
Marc fastré
www.marc-fastre.be
Posté le 21 avril 2015 - 10:17
Bonjour,
entièrement d accord avec fabrice ca fait moi aussi 15 ans que je utilise HFSQL surtout en client serveur
et entièrement satisfait facile a administrer performant comme le dit fabrice
j utilise les bases tierces uniquement si on me l'impose
Gerard
Membre enregistré
240 messages
Popularité : +3 (3 votes)
Posté le 21 avril 2015 - 11:03
Marc fastré a écrit :
Bonjour,

Selon les tests que j'ai effectué, même réseau, même serveur, même client, même données, en ce qui concerne l'ajout d'enregistrement dans la même table HF/CS est déjà bien plus véloce que SQL serveur, de plus si tu utilises un hecrit et ensuite un hreindexe, donc voilà pourquoi le problème se pose moins un HFCS

J'ai essayé de désactiver le mécanisme de gestion des index sur SQL serveur mais impossible d'y ajouter un record

Maintenant chacun son choix, j'utiliserais SQL multi INSERT pour insérer quelques records ( 5 -10 ) ca peut être sympa de l'exécuter en une seule requête, mais de là à construire requête en chaine pour y définir les données de 15000 record c'est autre chose...

Bon Dev
Marc fastré
www.marc-fastre.be


Tu as testé en effectuant un HAjoute() pour les deux méthodes ou comparé la boucle HAjoute() en HFSQL et l'INSERT multiple en SQL Server ?

--
Vincent
Posté le 21 avril 2015 - 11:36

Tu as testé en effectuant un HAjoute() pour les deux méthodes ou comparé la boucle HAjoute() en HFSQL et l'INSERT multiple en SQL Server ?

--
Vincent


Non, je n'ai pas comparé avec les INSERT Multiples, j'ai fait cela en v18 seulement donc INSERT simple et HAJOUTE sur les deux bases, pas de HECRIT car pas compatible SQLSEVER

Je vais couramment des transferts complets de DB sur deux bases ( les bases font souvent plusieurs centaines de milliers de lignes ) en HFCS et SQLSERVER que j'essaie de les lancer sur la machine ou est installée le serveur pour ne pas encombrer le réseau ( j'avoue ) , en général HF/CS et HECRIT "Avale" les nouveaux records 3 à 5x plus vite que les INSERT simple ou hajoute sur sqlserver dans les même conditions

La mise à jour des "petits" fichier d'index de HFCS semble plus performante que celle du gros fichier type MDB de sqlserver... ce qui n'est pas vrai pour les reqûetes

Mais bon c'est vrai que si je devais passer sur un cloud je passerai peut-être par un INSERT multi,( ou une procédure stockée sur HFCS ) mais par centaine de record tout au plus, envoyer 15000 record à la fois attendre que le serveur effectue l'ajout pour savoir si tout est ok cela risque d'être une expérience stressante pour l'opérateur qui n'aime pas rester devant un programme immobile

Bon Dev
Marc fastré
www.marc-fastre.be
Posté le 21 avril 2015 - 11:44
Bonjour Vincent,

ok, je joue...


(http://vincent-lecomte.blogspot.be/2013/07/java-executer-un-lot-de-requetes-sql.html)
; après évidemment il faut gérer tout le reste autour, annuler les
insertions en cas de problème, etc. Sur des bases de données externes,
cela serait un plus. Pourquoi parce qu'on ne s'en sert pas depuis 20 ans
cela n'est-il pas une bonne idée ? Ce genre d'évolution n'est pas un mal
bien au contraire, donc pourquoi s'en priver ?


Voila pourquoi ce n'est pas une bonne idée :

1. Code de construction de la requête à écrire = développement plus long
2. Beaucoup plus complexe qu'une simple boucle sur hajoute =
développement plus long
3. Problèmes de typage potentiel des contenus,
4. En cas d'erreur en milieu des insertions, le débug devient un
cauchemar... Que quelle ligne ? Quelle valeur ? Il faut faire un
roll-back de tout le taintouin, tout ca est beaucoup plus difficile à
débugguer, et beaucoup PLUS LONG.

Ce n'est pas parce que je ne l'utilise pas depuis 20 ans que je ne veux
pas l'utiliser, c'est parceque c'est une FAUSSE bonne idée... Quand je
code, mes objectifs sont :
- coder rapidement (pas bon avec la requête d'insertion)
- coder simplement (pas bon avec la requête d'insertion) pour éviter les
erreurs
- créer un code qui sera facilement maintenable par moi OU par mes
clients (pas bon avec la requête d'insertion)

Donc, oui, c'est possible, et je suis même sur qu'il y a des profs qui
conseillent d'utiliser cette méthode...

Moi, je code dans la vrai vie de la manière la plus efficace possible...

Cordialement



--
Fabrice Harari
Consultant WinDev, WebDev et WinDev Mobile International

NOUVEAU: WXReplication, votre système de réplication open source est
disponible sur mon site web !!!
WXShowroom.com : Montrez vos projets !
Plus d'information sur http://fabriceharari.com






--
Vincent
Posté le 21 avril 2015 - 14:30
J'approuve la réflexion de Fabrice avec deux choses en plus

- ca va pas être coton avec les mémos
- tu risques d'avoir des surprises quand tu va modifier la structure de ton fichier

Ce n'est pas parce qu'on PEUT le faire que l'on DOIT le faire...

Dans certains cas peut-être, à utiliser avec beaucoup de parcimonie, mais en ce qui me concerne en 20 ans jamais eu le besoin non plus

Bon dev

Marc Fastré
www.marc-fastre.be
Posté le 21 avril 2015 - 15:18
Je travaille beaucoup pour un client qui à plusieurs dizaine de million de records dans une Oracle en cluster et je vous promet que les requête multiples sont une excellente alternative (Voir unique). Bien évidement il faut mesurer ce que l'on fait. Je ne vais pas pousser 3'000'000 de records dans une requêtes mais jusqu'à 10Mo voir plus (Dépend du réseau) il n'y a aucun problèmes. Lorsqu'une connexion n'est pas rapide (VPN ou passerelle) tu verra une différence incroyable de vitesse entre plusieurs requête simple ou une multiples.

L'argument du temps de dev ne tiens pas. Crée une classe de génération de requête SQL c'est fait en 10min chrono avec une main attachée dans le dos.

De mon expérience, j'avais abandonné HyperFile car je trouvais la gestion des index très fragile et j'avais l'impression d'être dans la peau d'un administrateur en 1990 qui devait ré-indexer ces bases tout le temps. HyperFile est la seul base de donnée avec laquelle j'ai eut des problèmes d'index (Certainement que maintenant c'est mieux). Elle n'est pas assez ouverte et du coup compatible avec aucun logiciel de supervision ou de monitoring du marché. (Excepté ceux de PCSoft et dans la pharma un nouveau logiciel est souvent un logiciel de trop pour les validateurs) Il est vrai que tout est question de positions. Si je dois faire une application pour gérer quelques centaine/milliers de records et que les performance ne sont pas critiques, pourquoi pas.

Il y a aussi que HyperFile en V20 n'a rien à voir avec ce qu'elle était il y a quelques années. Il faudrait que j'essaie à nouveau pour me refaire un avis plus actuel. Il y a encore quelques petit manque comme la notion de séquenceurs (A ma connaissance sa n'existe pas) que j'utilise beaucoup sur Oracle et Postgre.

Marc : Merci pour ce retour d'expérience. Le test de vitesse que tu as effectué, tu as utilisé le driver natif de PCSoft? Quand je te parle de ma solution, elle n'utilise ni l'analyse ni des drivers de PCSoft mais des drivers codés en c# ou c++ externe.

Fabrice: Ce n'est pas la premières fois que nous ne sommes pas d’accord (En fait nous ne l'avons jamais été je crois ;-) ) mais je tiens quand même à te dire que je trouve tes remarques toujours très agressives alors que tu ne sais pas qui tu as en face. Tu ne peux pas être un petit peux plus humble? Quand tu me dis "Dans la vrai vie" Je ne comprend pas ce que tu entend pas la vrai vie. Moi dans ma vrai vie c'est la pharma, la chimie, ... Ce sont des milieux très sérieux ou je travaille avec plusieurs développeur et consultant sur des projet, voilà ma vrai vie à moi. Il y a une différence fondamentale entre un petit ERP qui fais 20req par minutes pour connaitre le prix des factures et déverser 10Go de log d'un batch de fabrication dans la bdd. Si je te dis que j'ai mesuré des différences de vitesse c'est que je l'ai fait. Tu es certainement plus vieux que moi mais sa n'est pas interdit de s'intéresse à une autre façon de faire plutôt que de me dire: Sa fais 20 que depuis mon ile je travaille comme sa et sa va super bien. Je ne trouve pas cette remarque très constructive.
Posté le 21 avril 2015 - 16:34
J'ai utilisé le driver OLEDB pour mes tests

j'avais fait également des tests entre une requête d'ajout en boucle sur Sql Server exécutée depuis une appli en C# et depuis une appli Windev et il n'y avait pas de différence significative

Comme je disais le multi INSERT est à utiliser dans des cas spécifiques, pour les logs en effet, avec des fichiers dans lesquels il y a peu de rubriques et pas de mémos, car je me vois mal pousser une chaine de 2Go dans un hexecuterequetesql afin d'importer 10.000 articles et leurs description RTF et leurs images

Marc Fastré
www.marc-fastre.be
Membre enregistré
101 messages
Popularité : +1 (1 vote)
Posté le 21 avril 2015 - 16:53
Tout est question de point de vue.

Windev + HFSQL + des instructions de type Hajoute ou Hecrit est certainement très bien comparé à SQLServer ou MySQL ...
Mais quand on a goûté à Oracle, HFSQL paraît très faible.

Et tout s'explique, les budgets ne sont pas les mêmes !
Membre enregistré
240 messages
Popularité : +3 (3 votes)
Posté le 21 avril 2015 - 19:12
J'ai eu quelques fois recours à des solutions autres que Windev pour réaliser certaines tâches... Et étant quelqu'un qui a beaucoup appris à manipuler le SQL et des langages de programmation comme le Java, j'ai tendance à aller vers ceux-ci pour pas mal de raisons. Je suis chaque jour dans Windev mais il faut reconnaitre que pour certaines opérations il est loin d'être parfait. C'est justement pour l'améliorer sans cesse que nous sommes tous là à débattre. Selon moi ce n'est donc pas une fausse bonne idée que d'avoir plusieurs méthodes aux performances différentes pour les nombreux cas de chacun...

--
Vincent
Membre enregistré
36 messages
Posté le 24 avril 2015 - 12:44
Bonjour,

je rejoins cette discussion avec un retour d'expérience :

utilisant SQL Server via un cloud privé nous avons eu besoin de cela afin d'accélérer les temps de réponse lors d'INSERT de lots de lignes (import de données).
Ici ce qui nous pénalise ce n'est pas la bande passante (y'en a assez de chaque côté) mais la latence.
J'ai donc développé une classe qui permet de gérer cela.

A l'usage c'est très simple et rapide à utiliser (puisque la classe est faite).
Plus il y a d'INSERT, plus le gain est important.
Je l'utilise pour quelques traitement d'importation de données (on parle de centaines ou milliers de lignes, guère plus).

Pour quelques lignes, le gain est mineur. En fait, tout dépend du volume de données moyen par ligne, du nombre de ligne et de la latence.
On peut dire qu'à partir de quelques dizaines de lignes ça devient intéressant : facile à calculer...
De même pour avoir utilisé la classe directement dans un soft sur le serveur SQL, le gain dans ce cas n'est pas important (c'est l'alimentation des index qui prend du temps au serveur, à creuser selon le besoin).

Si ça vous intéresse de creuser ce sujet : SQL Serveur impose une limite de 1000 lignes à la fois (j'ai géré cela dans la classe)
Il y a une limite concernant la taille des requêtes mais elle assez élevée pour 1000 lignes... tant qu'il n'y a pas de mémo...
La syntaxe "moderne" est disponible à partir de SQL Server 2008, pour les versions antérieures il faut faire des UNION ALL...

http://blog.sqlauthority.com/2008/07/02/sql-server-2008-insert-multiple-records-using-one-insert-statement-use-of-row-constructor/

Si vous désirez faire des INSERT très massif (plusieurs centaines de milliers de lignes, voir plus) : il faut par contre se diriger vers BULK INSERT directement sur le serveur... c'est une approche différente (peut être complexe selon le cas) mais très performante.
Voir : http://beyondrelational.com/modules/2/blogs/70/posts/10891/bulk-insert-to-table-with-specific-columns.aspx

Donc pour ma part très satisfait de cela dans ce cadre (utilisation distante) mais il faut en avoir besoin...
Bref, utiliser la bonne méthode pour la bonne problématique.

A+

Olivier