mysql a une belle déclaration: chargez XML local infilière
par exemple, si vous avez cette table: p> et le fichier XML suivant appelé personne.xml: p> Vous pouvez le faire: p> Ma question est, que si les noms de colonne étaient différents dans le fichier XML que ce qu'ils sont dans la table? Par exemple: p> Comment pouvez-vous accomplir la même chose avec une instruction MySQL sans manipuler le fichier XML? J'ai cherché partout mais je n'ai pas pu trouver une réponse. p> p>
5 Réponses :
Vous pouvez créer une table temporaire à l'aide des noms de colonne à partir du fichier XML (bien que cela puisse être effectué manuellement dans la table code> Créer temporaire code> requête), chargez le fichier XML dans cette table, puis Insérer dans la personne Sélectionnez * à partir de TMP_TABLE_NAME CODE>. P>
C'est un très bon travail autour. Cependant, comme j'ai commenté la réponse de Bill Karwin, il y a un autre problème avec la relève de la charge XML. Il n'accepte pas les étiquettes vides minimisées telles que
Je n'ai jamais travaillé avec charger XML code>, alors je suis juste allé avec une supposition éduquée sur cette réponse. Donc, non, malheureusement, je ne connais pas une solution à ce problème, autrement que le chargement du fichier XML dans une autre langue (p. Ex. PHP), le paître, puis l'envoi de la requête résultante à la base de données.
FYI L'échec à charger
Les champs du fichier XML qui ne correspondent pas aux noms de colonne physique sont ignorés. Et les colonnes de la table qui ne disposent pas de champs correspondants dans le XML sont définies NULL.
Que ferais ce que je ferais est de charger dans une table temporaire car @Kolink suggère mais avec des colonnes supplémentaires. Ajouter une clause code> définir code> lorsque vous chargez les données de XML. p> Copiez-le sur la table réelle, sélectionnez un sous-ensemble de colonnes. P> ALTER TABLE person_xml
DROP COLUMN PersonId,
DROP COLUMN FirstName,
DROP COLUMN LastName;
INSERT INTO person SELECT * FROM person_xml;
SELECT * FROM person;
+-----------+--------+-------------+
| person_id | fname | lname |
+-----------+--------+-------------+
| 1 | Mikael | Ronström |
| 2 | Lars | Thalmann |
+-----------+--------+-------------+
Merci. Un nouveau problème a émergé. Apparemment, cette déclaration n'aime pas les éléments vides dans la forme
Ce sont des fichiers énormes que je ne génère pas moi-même et ils doivent être chargés dans MySQL toutes les 15 minutes. Ce serait trop inefficace pour les manipuler. Sinon, je sauterais toute cette déclaration et utilise simplement saxo via Java pour les analyser et insérer les données dans MySQL.
Comme tu veux. Je dis juste que je voudrais utiliser XSLT. Il est plus rapide de développer et d'exécuter des transformations contre XML que n'importe quel langage de codage comme une langue de procédure.
Je pense que je peux aller avec votre recommandation de transformer le fichier en premier avec XSLT, puis à l'aide de l'instruction LOAD XML sur le fichier transformé.
Encore une fois, le problème que je suis confronté est que ces fichiers XML sont trop volumineux pour se charger de la mémoire. Les transformations XSLT chargent normalement le XML dans la mémoire en premier.
On dirait que vous essayez de faire la réplication d'un pauvre homme. Y a-t-il une chance que vous puissiez demander que les données soient fournies au format CSV? Il sera moins gonflé que XML et plus facile à la charge en vrac avec des données de charge Local Infile, qui utilise des paramètres de position au lieu des correspondances exactes de la colonne.
Je n'ai absolument aucun contrôle sur les données XML. Si je faisais, j'aurais les éléments nommés systématiquement et les éléments vides apparaissent sans le format minimisé. Ensuite, je pourrais facilement utiliser la relève de la charge XML.
Un peu hacky, solution de travail utilisant le bon vieux Charger Data Infile :
LOAD DATA LOCAL INFILE '/tmp/xml/loaded.xml' INTO TABLE person CHARACTER SET binary LINES STARTING BY '<person>' TERMINATED BY '</person>' (@person) SET person_id = ExtractValue(@person:=CONVERT(@person using utf8), 'PersonId'), fname = ExtractValue(@person, 'FirstName'), lname = ExtractValue(@person, 'LastName') ;
Cela pourrait être sujet à une erreur. Trop hacky. Merci pour votre réponse cependant.
Merci. L'avantage de vitesse sur charge XML code> est un ordre de grandeur
C'était plus lent que chargez XML code> sur un fichier de 3 + GB pour moi sur mon test de test local DB. Il a également perdu Connect après 109 minutes. (MySQL 8.0.18)
Les options sont disponibles pour moi: P>
Option 1: Créez une table temporaire avec différents noms de champs (comme suggéré par les autres réponses). Cela aurait été une approche satisfaisante. Cependant, lorsque je l'ai essayé, un nouveau problème a émergé: la relève de la charge XML ne fait pas, pour une raison quelconque, accepte des éléments de format minimisés de format (par exemple Option 2: Transformez le fichier XML avec XSLT avant d'exécuter l'instruction de chargement XML pour modifier les noms d'élément et modifier les formats d'élément vides. Ce n'était pas réalisable car les fichiers XML sont très volumineux et les moteurs de traitement XSLT chargent l'ensemble du XML dans la mémoire avant le traitement. p>
Option 3: contourner entièrement l'instruction XML de chargement et utiliser un analyseur SAX pour analyser le fichier XML et insérez les enregistrements directement dans la base de données à l'aide de JDBC et de déclarations préparées. Même si la JDBC brut et les déclarations préparées sont généralement efficaces, cela s'est avéré être trop lent. Beaucoup plus lent que la déclaration de charge XML. p>
Option 4: Utilisez l'instruction de données de charge au lieu de la relève de la charge XML et de la lecture avec les clauses facultatives associées à cette instruction correspondant à mes besoins (par exemple, des lignes séparées par, etc.). Cela aurait pu travailler mais aurait été sujet aux erreurs et instables. p>
Option 5: Analysez le fichier avec un analyseur rapide et en lecture / écriture simultanément sur simultanément et générer un nouveau fichier XML avec les noms modifiés dans le format souhaité pour l'instruction de chargement XML. p>
J'ai fini par utiliser l'option 5. J'ai utilisé l'API de streaming Java pour XML (Stax) pour la lecture du fichier XML et générer le fichier XML modifié, puis exécutant l'infiltration locale de chargement XML via JDBC de l'application Web. Cela fonctionne parfaitement et c'est super rapide. p>
schéma de table mysql: organisation_type (ID, nom)
OrganisationType.xml: p> et la requête d'importation MySQL ressemblera à ceci: p> < Pré> xxx pré> p>