Από το θέμα του περιοδικού στην πρακτική εφαρμογή του έργου
Σχετικές σελίδες υπηρεσιών και τεχνολογίας για το άρθρο
Ένα BDE-Ablosung mit nativer Anbindung Bulk-Insert mit Array DML είναι συχνά ο ταχύτερος τρόπος για να περάσουν πολλές εγγραφές σε μια βάση δεδομένων: αντί για χίλια μεμονωμένα Inserts δεσμεύεται ένας πίνακας παραμέτρων και αποστέλλεται μονομιάς στον διακομιστή. Στην πράξη όμως το κρίσιμο σημείο εμφανίζεται γρήγορα: μια εγγραφή παραβιάζει έναν Unique-Index, ένα πεδίο NOT NULL είναι κενό, ένα Foreign Key δεν ταιριάζει — και ξαφνικά δεν είναι σαφές ποια γραμμή προκάλεσε την αποτυχία του batch, αν κάποιο μέρος έχει ήδη εγγραφεί και πώς προχωράς με καθαρό τρόπο χωρίς να δημιουργήσεις ασυνέπειες δεδομένων.
Ακριβώς αυτό είναι το θέμα εδώ: Πώς να χρησιμοποιήσεις Array DML έτσι ώστε να λαμβάνεις ανά γραμμή αξιόπιστες πληροφορίες σφάλματος, να διατηρείς τον έλεγχο της συναλλαγής και να μπορείς στη λειτουργία να αναπαράγεις τι συνέβη. Η εστίαση δεν είναι στην ακαδημαϊκή ανάγνωση της API, αλλά στο περιθωριακό σενάριο που σε πραγματικά imports εμφανίζεται τακτικά: ένα μεγάλο batch, λίγες κατεστραμμένες γραμμές, αλλά θέλεις παρ’ όλα αυτά ταχύτητα.
FireDAC Bulk-Insert με Array DML: Γιατί το Array DML αποδίδει στο Bulk-Insert
Το Array DML (Data Manipulation Language) σημαίνει σε FireDAC: δεσμεύεις παραμέτρους όχι ως μεμονωμένες τιμές αλλά ως πίνακα. Το FireDAC τότε (ανάλογα με τον Treiber/DB) στέλνει λιγότερα roundtrips, μπορεί να λειτουργεί αποδοτικότερα στην πλευρά του διακομιστή και μειώνει δραστικά το overhead στον client. Αυτό είναι ιδιαίτερα σχετικό σε τρεις περιπτώσεις:
- ETL- και ροές εισαγωγής: CSV/XML/JSON εισαγωγή, κανονικοποίηση/Mapping, στη συνέχεια σε staging- ή πίνακα προορισμού.
- Προσωρινά αποθέματα διεπαφών: REST- oder MQ-Payloads συγκεντρώνονται και αποθηκεύονται περιοδικά.
- Πίνακες πρωτοκόλλων/γεγονότων: πολλά μικρά Inserts, όπου κυριαρχεί η καθυστέρηση.
Το κέρδος όμως δεν έρχεται χωρίς κόστος. Με Array DML μετατοπίζεις την πολυπλοκότητα από «πολλές μεμονωμένες εντολές» σε «μία εντολή με πολλές γραμμές». Αυτό είναι καλό για την απόδοση, αλλά περισσότερο απαιτητικό για διάγνωση σφαλμάτων, λογική συναλλαγών και επανεκτέλεση.
Το τυπικό περιθωριακό σενάριο: Ένα Batch, μια κατεστραμμένη Zeile
Το κλασικό σενάριο στην παραγωγή: εισάγεις 50.000 γραμμές. Επιλέγεις μια ArraySize των 1.000, γιατί δεν θέλεις για κάθε γραμμή ένα roundtrip. Το Batch 17 αποτυγχάνει. Η DB αναφέρει μόνο «duplicate key» ή «violates foreign key constraint». Στο UI ή στο service-Log εμφανίζεται τότε συχνά μόνο: „ExecSQL failed“.
Χωρίς σωστό Error-Handling συμβαίνουν συνήθως δύο ανεπιθύμητα αποτελέσματα:
- Απορρίπτεις ολόκληρο το batch, παρόλο που 999 από τις 1.000 γραμμές θα ήταν εντάξει.
- Επιστρέφεις σε μεμονωμένα Inserts και χάνεις το πλεονέκτημα απόδοσης μόνιμα.
Στόχος είναι μια τρίτη οδός: διατήρηση της απόδοσης σε Batch, αλλά ακριβής καταγραφή σφαλμάτων (δείκτης γραμμής, τιμές κλειδιών, κείμενο σφάλματος DB) και προαιρετικά να κάνεις commit των «σωστών γραμμών» – ανάλογα με το πόσο κρίσιμη είναι η συνέπεια και η idempotenz (εκτέλεση πολλαπλές φορές χωρίς διπλή επίδραση) στη ροή σου.
FireDAC Array DML: Οι σχετικές παράμετροι (χωρίς μύθους)
Για μαζική εισαγωγή (Bulk-Insert) με Array DML στην πράξη πάντα οι ίδιες παράμετροι είναι καθοριστικές:
1) ArraySize und Batch-Größe
ArraySize (στα TFDQuery/TFDCommand) καθορίζει πόσες «γραμμές» FireDAC επεξεργάζεται μια κλήση. Μεγαλύτερο δεν είναι αυτομάτως καλύτερο. Πολύ μεγάλο σημαίνει: περισσότερη μνήμη στον πελάτη, μεγαλύτερο payload στο δίκτυο, μεγαλύτερα locks/φόρτος στο log στον server και σε περίπτωση σφάλματος μεγαλύτερος „blast radius“. Για ανθεκτικά imports ένα εύρος Batch μεταξύ 200 και 2.000 είναι συχνά καλό ξεκίνημα, ανάλογα με τον αριθμό στηλών, BLOBs και την καθυστέρηση (latency).
2) Transaktionsgrenze
Χρειάζεσαι μια σαφή απόφαση: Commit ανά Batch ή Commit για ολόκληρο το Import. Αυτό δεν είναι θέμα γούστου αλλά λειτουργικής απόφασης:
- Commit pro Batch: περιορίζει τα locks και το transaction log, διευκολύνει το επανεκκίνηση, αλλά ενδιάμεσα στάδια είναι ορατά (ανάλογα με το Isolation Level). Σφάλματα στο Batch 17 αφήνουν τα Batch 1–16 στο σύστημα.
- Commit am Ende: «όλα ή τίποτα», πιο συνεκτικό σε επιχειρησιακό επίπεδο, αλλά με μεγάλους όγκους ρισκάρεις μακρά locks, μεγάλο rollback και σε περίπτωση σφάλματος χάνεις τα πάντα.
Για πολλές διεπαφές και διαδικασίες εισαγωγής η στρατηγική «Commit pro Batch» είναι πιο ρεαλιστική – αλλά μόνο αν έχεις καθαρά ρυθμισμένη idempotenz και στρατηγική για διπλότυπα (π.χ. μέσω φυσικών κλειδιών, upserts ή ενός Import-ID).
3) UpdateOptions und Prepared Statements
Σε επαναλαμβανόμενα Batches αξίζει το statement να παραμένει προετοιμασμένο. Το «Prepare» σημαίνει ότι η FireDAC αφήνει τη DB να κάνει parse/compile και να το επαναχρησιμοποιήσει. Αναλόγως της βάσης αυτό μπορεί να έχει αισθητό αποτέλεσμα, ειδικά σε υψηλή συχνότητα. Εδώ το σημαντικό δεν είναι κάποιο «τρικ», αλλά: η συνεπής επαναχρησιμοποίηση του ίδιου αντικειμένου Query (ή του ίδιου TFDCommand) και σταθεροί τύποι παραμέτρων.
Καθαρός χειρισμός σφαλμάτων ανά γραμμή: Τι χρειάζεσαι πραγματικά
Αν θέλεις να χειριστείς σφάλματα «ανά γραμμή», χρειάζεσαι τρία πράγματα:
- Αντιστοίχιση: Ποιος δείκτης array (0..N-1) απέτυχε;
- Πλαίσιο: Ποιες επιχειρησιακές τιμές κλειδιών έχει αυτή η γραμμή (π.χ. εξωτερικό ID, αριθμός πελάτη, χρονική σήμανση);
- Έλεγχος: Τι κάνεις μετά; Διακοπή, απλώς παράλειψη των κακών γραμμών, ή διαχωρισμός του Batch;
Η FireDAC μπορεί ανάλογα με τον driver να επιστρέψει σφάλμα ανά στοιχείο του array. Στην πράξη όμως αυτό δεν είναι «αυτόματο». Πρέπει να υπολογίσεις ότι κάποιες βάσεις/προμηθευτές θα αναφέρουν μόνο το πρώτο σφάλμα ή ότι ένα σφάλμα στο Batch μπορεί να εμποδίσει την εκτέλεση των υπολοίπων. Ακριβώς γι‘ αυτό ένα ανθεκτικό μοτίβο είναι συνήθως δύο σταδίων:
- Στάδιο A: Δοκίμασε τον Batch ως Array DML.
- Στάδιο B: Αν ο Batch αποτύχει, διαιρέσέ τον (στη μέση) ή επιστρέψε με ελεγχόμενο τρόπο στην εκτέλεση γραμμή-γραμμή – αλλά μόνο για αυτόν τον Batch – και καταχώρησε τα σφάλματα με ακρίβεια.
Ακούγεται σαν παραπάνω δουλειά, αλλά σε ροές εισαγωγής είναι η διαφορά μεταξύ «στις 02:00 το βράδυ σταματάει όλα» και «το import προχωράει, 7 γραμμές καταλήγουν στη λίστα σφαλμάτων».
Ένα πρακτικό μοτίβο: Πρώτα Batch, μετά στοχευμένη απομόνωση
Το ακόλουθο πρότυπο έχει αποδειχθεί αποτελεσματικό σε εφαρμογές λογισμικού κοντά στη διαδικασία, όπου η ποιότητα των δεδομένων είναι μεικτή:
Βήμα 1: Τοποθέτηση των δεδομένων σε δομή batch (συμπεριλαμβανομένου του πλαισίου σφάλματος)
Αποθήκευσε τα προς εισαγωγή δεδομένα όχι μόνο ως ακατέργαστες τιμές, αλλά με ελάχιστο συμφραζόμενο: εξωτερικό ID, αριθμό γραμμής από την πηγή, ενδεχομένως Hash/Checksumme. Αυτό δεν είναι «Nice to have»: σε περίπτωση σφάλματος δεν θέλεις να ξανααναλύσεις το CSV για να διαπιστώσεις τι έχει χαλάσει.
Βήμα 2: Εκτέλεση Array DML
Θα ορίσεις το ArraySize στο μέγεθος του batch, θα δέσεις τις παραμέτρους ως arrays και θα εκτελέσεις ExecSQL. Σημαντικό: διατήρησε σταθερούς τους τύπους των παραμέτρων (π.χ. για αριθμητικά πεδία μην δεσμεύεις μερικές φορές ως String και άλλες ως Integer), αλλιώς η DB θα παράγει implizite Casts ή FireDAC θα πρέπει να μετατρέψει ανά στοιχείο.
Βήμα 3: Περίπτωση σφάλματος – περιορισμός του batch αντί τυφλής επανάληψης
Εάν το ExecSQL αποτύχει, έχεις δύο αξιόπιστες επιλογές:
- Binary Split (halbieren): Διαίρεση του batch σε δύο μισά και προσπάθεια εκτέλεσης κάθε μισού ξανά ως Array DML. Επαναλαμβάνεις αυτό μέχρι να φτάσεις σε μικρό αριθμό στοιχείων που μπορείς να ελέγξεις ξεχωριστά. Πλεονέκτημα: διατηρείς μεγάλο μέρος της απόδοσης όταν μόνο λίγες γραμμές είναι κατεστραμμένες. Μειονέκτημα: περισσότερη λογική, και σε συστηματικά σφάλματα (π.χ. λάθος τύπος δεδομένων) αποδίδει λιγότερο.
- Fallback auf Einzelzeilen για αυτό το batch: ορίζεις ArraySize=1 (ή δένεις μεμονωμένες τιμές) και εκτελείς γραμμή–γραμμή, καταγράφεις σφάλματα και συνεχίζεις. Πλεονέκτημα: απλό, εγγυημένο ανά γραμμή. Μειονέκτημα: σε αυτό το batch χάνεις ταχύτητα.
Στην πράξη συνδυάζω και τα δύο: πρώτα κάνω διαίρεση 1–2 φορές (για να περάσω γρήγορα «καλά μπλοκ»), στη συνέχεια σε μικρά υπόλοιπα περνάω σε μεμονωμένες γραμμές για να καταγράψω σαφείς πληροφορίες σφάλματος.
Αντικείμενα σφάλματος και μηνύματα: Τι πρέπει να εξάγεις από FireDAC
FireDAC περιβάλλει σφάλματα DB σε Exceptions (τυπικά EFDDBEngineException) με λεπτομερείς πληροφορίες. Για τη λειτουργία είναι σημαντικά τρία επίπεδα:
- DB-σφάλματος κωδικός (ειδικός για τη DB): π.χ. SQLSTATE σε PostgreSQL, Error Number σε SQL Server.
- Όνομα περιορισμού/αντικειμένου: συχνά περιλαμβάνεται στο κείμενο σφάλματος (Unique-Index, FK-Constraint).
- Πλαίσιο του Statement: πίνακας, λειτουργία, ενδεχομένως τιμές παραμέτρων (προσοχή σε προσωπικά δεδομένα).
Αν θέλεις να καταγράφεις ανά γραμμή, πρέπει σε περίπτωση σφάλματος επίσης να ταυτοποιήσεις τη γραμμή. FireDAC μπορεί υπό συνθήκες να παρέχει τον Array-Index. Μην βασίζεσαι όμως αποκλειστικά σε αυτό. Διεύρυνε πάντα με έναν δικό σου δείκτη (θέση στο batch) και καταγράφεις για αυτή τη θέση τουλάχιστον ένα επιχειρησιακό κλειδί.
Παγίδες που κοστίζουν χρόνο σε πραγματικές εισαγωγές
1) «Es war doch nur eine Zeile» – aber die Transaktion ist schon «dirty»
Ανάλογα με τη DB και τον οδηγό, ένα σφάλμα μπορεί να οδηγήσει στο να θεωρηθεί ότι η ολόκληρη εκτέλεση των statements απέτυχε και η συναλλαγή να βρίσκεται σε κατάσταση όπου είτε πρέπει να κάνεις ρητά rollback είτε όπου επόμενα statements θα αποτύχουν. Ειδικά με ορισμένους Treibern ist «nach Fehler einfach weitermachen» keine sichere Annahme.
Konsequenz: Wenn du in einer Transaktion arbeitest und ein Batch fehlschlägt, ist der Standardpfad: Rollback des aktuellen Batch-Kontexts (oder der gesamten Transaktion) und dann neu ansetzen. Das passt gut zu „Commit pro Batch“.
2) Autocommit vs. ρητή συναλλαγή
Εάν δεν ξεκινήσεις ρητή συναλλαγή, συχνά ο Treiber/Provider αποφασίζει πώς θα κάνει commit τα statements. Για bulk-imports αυτό σπάνια είναι επιθυμητό. Οι ρητές συναλλαγές σου δίνουν έλεγχο πάνω σε:
- Διάρκεια κλειδώματος
- Συμπεριφορά rollback
- Σημεία επανεκκίνησης
Και: «Explizit» δεν σημαίνει «μια τεράστια συναλλαγή». Σημαίνει «συνειδητά».
3) Trigger, Constraints και παρενέργειες
Το Array DML επιταχύνει την παράδοση, αλλά δεν επιταχύνει αυτόματα την εργασία στην πλευρά του διακομιστή. Αν στη στοχευόμενη πίνακα υπάρχουν Trigger (π.χ. Audit-Logging, αυτόματος υπολογισμός κατάστασης), τότε ο φραγμός ενδέχεται να μην είναι το INSERT, αλλά ο κώδικας του trigger. Τότε ένα batch μπορεί να έχει λιγότερα roundtrips, αλλά η CPU στον DB-Server παραμένει ο περιοριστικός παράγοντας.
Για Admins και τεχνικούς Leads: Σε προβλήματα απόδοσης αξίζει μία ματιά στα Wait Events/Locks και στο transaction log. Το Bulk-Insert είναι συχνά μόνο ο πυροδότης, όχι η αιτία.
4) Datentypen und implizite Konvertierungen
Ένας από τους συχνότερους λόγους του «Γιατί είναι αργό;»: οι παράμετροι δεσμεύονται ως String και η DB κάνει cast ανά σειρά σε Integer/Date/Decimal. Αυτό είναι αόρατο αλλά δαπανηρό. Για σταθερή απόδοση:
- Όρισε σωστά τους τύπους δεδομένων των παραμέτρων (ημερομηνία ως ημερομηνία, αριθμός ως αριθμός).
- Στα Decimals να προσέχεις τις παγίδες του locale (κόμμα vs. τελεία). FireDAC είναι εδώ κατά κανόνα σωστό, αλλά οι μικτές πηγές δεν είναι.
- Διευκρίνισε εκ των προτέρων τη στρατηγική ζωνών ώρας/UTC (Timestamps είναι κλασική πηγή προβλημάτων στα Imports).
5) Fehlertexte sind für Menschen, aber nicht für Automatisierung
Είναι δελεαστικό να κάνεις parsing στο κείμενο σφάλματος («duplicate key value violates unique constraint …»). Κάντο μόνο ως τελευταία επιλογή. Προτιμότεροι είναι δομημένοι κωδικοί (SQLSTATE, Error Number). Δυστυχώς δεν παρέχουν όλοι οι Treiber τα ίδια δεδομένα με την ίδια ποιότητα. Σχεδίασε επομένως και τα δύο: κωδικό και κείμενο, συν προαιρετικά «όνομα Constraint από το κείμενο», αλλά χωρίς σκληρή εξάρτηση.
Debugging-Hinweise: So findest du schnell die kaputte Zeile
Batch reproduzierbar machen
Αν ένας Import αποτυγχάνει σποραδικά, χρειάζεσαι αναπαραγωγιμότητα. Αποθήκευσε ανά Batch ένα μικρό αρχείο διάγνωσης ή ένα καταγεγραμμένο μήνυμα που περιέχει:
- Αριθμό batch και χρονική σήμανση
- ArraySize και τρόπο συναλλαγής
- τη λίστα των επιχειρησιακών κλειδιών (π.χ. εξωτερικά IDs) στο batch
Συχνά αυτό αρκεί για να τρέξεις εκ των υστέρων έναν στοχευμένο mini-Import μόνο για αυτά τα IDs.
Finale SQL sichtbar machen (aber ohne Datenleaks)
Στο debugging θέλεις να ξέρεις: Είναι το SQL σωστό; Είναι οι παράμετροι σωστοί; FireDAC προσφέρει Monitoring/Tracing μέσω συνιστωσών FDMoni και Treiber-Logging. Σε περιβάλλοντα κοντά στην παραγωγή είναι σημαντικό:
- Ενεργοποίησε το Tracing στοχευμένα και μόνο προσωρινά (επίδοση και προστασία δεδομένων).
- Κατέγραψε τις τιμές των παραμέτρων μόνο σε ένα ασφαλές περιβάλλον ή με μάσκα.
- Σε προσωπικά δεδομένα: στο log μόνο τεχνικά κλειδιά (IDs) και όχι περιεχόμενο σε απλό κείμενο.
Wenn du split-testest: Abbruchkriterien definieren
Στο Binary Split δεν θέλεις να διαιρείς επʼ αόριστον. Θέσε ένα κατώτατο όριο, π.χ. «κάτω από 20 γραμμές — μετάβαση σε μονό τρόπο». Και όρισε ένα όριο για το πόσα σφάλματα συνολικά θα ανεχτείς πριν διακόψεις τον Import (π.χ. σε συστηματικά προβλήματα mapping). Αλλιώς καταλήγεις σε ατελείωτες λίστες σφαλμάτων και μπλοκάρεις την επεξεργασία που ακολουθεί.
Wann sich der Aufwand wirklich lohnt (und wann nicht)
Το Array DML με ανά-σειρά χειρισμό σφαλμάτων αξίζει ιδιαίτερα, όταν:
- Επεξεργάζονται πολλές γραμμές (χιλιάδες έως εκατομμύρια).
- Λίγες γραμμές έχουν σφάλματα, αλλά θέλεις παρʼ όλα αυτά να προχωρήσει η διαδικασία.
- Ο Import πρέπει να τρέχει σταθερά σε παραγωγική λειτουργία (π.χ. νυχτερινή επεξεργασία, service χωρίς UI).
- Πρέπει να επιστρέψεις μια λίστα σφαλμάτων στο Fachbereich/πηγή (με αναφορά σε γραμμή).
Αξίζει λιγότερο όταν:
- γράφεις μόνο μερικές δεκάδες γραμμές (μεμονωμένα inserts είναι εντάξει),
- η ποιότητα των δεδομένων είναι τόσο κακή που 30–50% των γραμμών αποτυγχάνουν (τότε μια στρατηγική staging είναι πιο λογική),
- χρησιμοποιείς ήδη μια DB-ενδογενή διαδικασία Bulk-Load (π.χ. COPY σε PostgreSQL, BCP/BULK INSERT σε SQL Server) – τότε το Array DML δεν είναι το κατάλληλο εργαλείο.
Alternative Architektur: Staging-Tabelle statt „Direkt ins Ziel“
Αν τακτικά παλεύεις με μικτή ποιότητα δεδομένων, ένα καθαρό «insert απευθείας στον πίνακα προορισμού» συχνά είναι η λάθος απόφαση. Ένας πίνακας staging (προκαταρκτικό στάδιο) είναι ένας πίνακας στον οποίο αποθηκεύεις τα δεδομένα αρχικά τεχνικά σωστά (ενδεχομένως με χαλαρούς τύπους) και μόνο στη συνέχεια τα επικυρώνεις και τα μεταφέρεις στον πίνακα προορισμού.
Πλεονεκτήματα στη λειτουργία:
- Τα ελαττωματικά αρχεία παραμένουν αποθηκευμένα και αναγνωρίσιμα (συμπεριλαμβανομένων των raw δεδομένων).
- Μπορείς να εκτελείς την επικύρωση ξεχωριστά και επαναλαμβανόμενα.
- Αποσυνδέεις την παραδοχή της διεπαφής από την επιχειρησιακή επεξεργασία.
Το Array DML είναι συχνά ο γρήγορος δρόμος προς τον πίνακα staging, ενώ η μεταφορά στον πίνακα προορισμού γίνεται ως SQL βασισμένο σε σύνολα ή ως αποθηκευμένη διαδικασία. Αυτό μεταθέτει την αντιμετώπιση σφαλμάτων σε μεγαλύτερο βαθμό στην πλευρά της βάσης δεδομένων, κάτι που ανάλογα με την οργάνωση (ρόλοι DBA, Deployment) μπορεί να είναι επιθυμητό ή όχι.
Betrieb und Administration: Was IT-Leads und Admins dazu wissen sollten
Monitoring: Fehlerquote und Durchsatz sind die Kernmetriken
Για τη σταθερή λειτουργία ενός bulk-import δύο μετρικές λένε περισσότερα από μόνο το «χρόνο εκτέλεσης»:
- Ρυθμός επεξεργασίας: γραμμές ανά λεπτό (ή ανά batch) συμπεριλαμβανομένων μέγιστου/διάμεσου.
- Ποσοστό σφαλμάτων: ελαττωματικές γραμμές ανά εκτέλεση, ιδανικά ομαδοποιημένες κατά κλάση σφάλματος (Unique, FK, NOT NULL, σύγκρουση τύπου).
Αν παρακολουθείς τακτικά αυτές τις δύο τιμές, αναγνωρίζεις νωρίς αν έχει αλλάξει κάτι στην πηγή (π.χ. νέο format) ή αν το σύστημα προορισμού (π.χ. νέα constraints) έγινε πιο αυστηρό.
Sperren und Lastfenster
Τα bulk-inserts μπορούν να προκαλέσουν κλειδώματα και IO-φορτίο. Αν παράλληλα χρήστες εργάζονται στους ίδιους πίνακες, πρέπει να σκεφτείς επίπεδα απομόνωσης, δείκτες και ενδεχόμενη κατατμήση. Πρακτικά αυτό σημαίνει: είτε τοποθετείς τα imports σε παράθυρα χαμηλού φόρτου, είτε κατασκευάζεις τη ροή δεδομένων ώστε να συνυπάρχει με την τρέχουσα λειτουργία (π.χ. μέσω staging + ασύγχρολης μεταφοράς).
Konkrete Checkliste für einen robusten Bulk-Insert mit Array DML
- Μέγεθος batch ορίστε (αρχική τιμή 500–1.000) και βελτιστοποιήστε με μετρήσιμα βήματα.
- Εξακριβωμένη συναλλαγή: Commit ανά batch ως προεπιλογή, «Commit στο τέλος» μόνο με επίγνωση των συνεπειών.
- Σταθεροί τύποι παραμέτρων: ορίστε σταθερά τύπους, μη επιβάλλετε έμμεσες μετατροπές (implicit casts).
- Πλαίσιο σφάλματος ανά εγγραφή: φέρε μαζί στοιχεία (εξωτερικό ID, γραμμή προέλευσης).
- Στρατηγική σφαλμάτων: πρώτα batch-level, μετά split/fallback, καταγραφή ανά γραμμή.
- Logging: κωδικοί + κείμενο, αλλά σύμφωνο με προστασία δεδομένων· καταγράψτε Batch-ID και Lauf-ID.
- Επαναληψιμότητα: διασφαλίστε idempotenz (κλείδι/Upsert/Import-ID).
Fazit: Array DML ist schnell – robust wird es durch Prozess und Fehlerstrategie
Ένα FireDAC Bulk-Insert με Array DML είναι ένα ισχυρό εργαλείο, αρκεί να μην προσποιείσαι ότι δεν υπάρχουν σφάλματα. Σε πραγματικά ρεύματα δεδομένων υπάρχουν πάντα αποκλίσεις: διπλότυπα, ελλείπουσες αναφορές, κατεστραμμένες τιμές ημερομηνίας. Η ορθή προσέγγιση είναι επομένως: Array DML για την απόδοση, σε συνδυασμό με μια ελεγχόμενη στρατηγική απομόνωσης (Split ή Fallback) και μια λίστα σφαλμάτων ανά γραμμή με δυνατότητα ιχνηλασιμότητας. Με αυτό συνδυάζεις ταχύτητα και επιχειρησιακή αξιοπιστία — και αυτό είναι που μετράει όταν οι εισαγωγές δεν τρέχουν μόνο στο εργαστήριο αλλά πρέπει να ολοκληρώνονται αξιόπιστα κάθε νύχτα.
Εάν επιθυμείτε να σταθεροποιήσετε μια υπάρχουσα διαδικασία εισαγωγής ή διεπαφής σε Delphi/FireDAC (Performance, Transaktionen, Wiederanlauf, Logging), το διευκρινίζουμε ευχαρίστως δομημένα σε μια τεχνική συζήτηση:
Για αυτό το θέμα είναι επίσης σημαντικά τα Delphi Bulk Insert και Bulk Insert Delphi FireDAC. Το άρθρο τοποθετεί αυτά τα ζητήματα με σαφή τρόπο και δείχνει σε τι πρέπει να δίνεται προσοχή στην καθημερινή πράξη.
επόμενο βήμα
Όταν ένα θέμα εξελιχθεί σε ένα πραγματικό έργο, η αρχιτεκτονική, τα υφιστάμενα συστήματα και η λειτουργία πρέπει να εξεταστούν από νωρίς από κοινού.
Υποστηρίζουμε όχι μόνο σε μεμονωμένα ζητήματα, αλλά και όταν από αποσπάσματα πηγαίου κώδικα, θέματα legacy ή ιδέες για πύλες πρέπει να προκύψει ένα αξιόπιστο εταιρικό έργο.
- Η υφιστάμενη κατάσταση, το επιθυμητό μελλοντικό μοντέλο και οι τεχνικοί κίνδυνοι αξιολογούνται από κοινού.
- REST, πρόσβαση στα δεδομένα, πύλες και Rollout δεν θα αναβληθούν ως μεταγενέστερες συνέπειες.
- Διαπιστώνετε έγκαιρα ποια προσέγγιση είναι οικονομικά και επιχειρησιακά βιώσιμη.