dBase & DBF data migration that survives an audit
DBF is not just an old file format — it is a minefield of codepages, memo files, ghost rows and index-encoded rules. We move the data with its meaning intact, and prove it with numbers.
Why DBF-to-SQL is harder than it looks
Every generic ETL tool claims DBF support, and every one of them will happily produce a SQL database that is subtly wrong. The format is simple; the ecosystem around it is not:
- Codepages. A single byte in the header — frequently zero or lying — decides whether text decodes correctly. Hebrew cp862, Cyrillic cp866, Central European cp852 files masquerade as plain ASCII until the first non-Latin character.
- Memo files. The DBF stores 4- or 10-byte pointers; the actual text lives in .fpt/.dbt blocks. Orphaned pointers, shared blocks and corrupted block sizes are common after decades of copying.
- Ghost rows. Deleted means flagged, not gone. Whether those rows are junk, an accidental archive, or legally significant history differs per table.
- Index expressions.
UPPER(LAST+FIRST),DTOS(INVDATE)+SERIES, conditional indexes — business rules that exist nowhere else and vanish if you migrate only the data. - Type semantics. Empty vs zero numerics, blank vs 1899-12-30 dates, logical fields holding three states in a two-state type — each needs an explicit mapping decision.
- The 2 GB wall and multi-file "tables". Applications that hit the limit often shard data across yearly or per-branch files that must be merged with provenance preserved.
Our pipeline
-
Structural survey
Every DBF, memo and index file cataloged: dialect, codepage evidence, field maps, record and deleted counts, corruption flags. (The same checks our free DBF Analyzer runs — plus content-level profiling.)
-
Mapping decisions on paper
Per-column codepage, per-table deleted-row policy, empty-value semantics, index expressions translated to SQL constraints and computed columns — written down and agreed before a single row moves.
-
Repeatable transfer, verified every run
A scripted pipeline (not a one-off wizard session) moves the data and emits a verification report: row counts, per-column checksums, memo coverage, round-trip spot decodes. Runs nightly during transition so SQL is always current.
-
Handover
You get the pipeline, the mapping document and the verification history — an audit trail that answers "did anything get lost?" with evidence.
Typical destinations
SQL Server or PostgreSQL as the system of record; the legacy application either retired, kept running against a live mirror for reporting, or rebuilt in slices — see FoxPro to .NET and Clipper/xBase migration for the application side of that journey.
Frequently asked questions
Can’t we just import the DBF files into SQL with a generic tool?
You can — and that is how data quietly gets ruined. Generic importers trust the file’s codepage byte (often wrong or absent), skip or blindly include deleted rows, ignore the memo file, coerce empty dates and numbers incorrectly, and know nothing about the business logic hidden in index expressions. The rows arrive; the meaning does not. A verified migration checks every one of those explicitly.
Our text comes out as garbage (question marks, box characters, gibberish). Why?
Codepages. DOS-era applications wrote text in OEM codepages — cp437, cp850, cp852, cp862 for Hebrew, cp866 for Cyrillic — and usually did not record which one in the file. Windows-era tools then read those bytes as ANSI or UTF-8 and produce garbage. The data is almost never lost: it just needs the correct per-column decoding, which we identify from the data itself and from the application’s history. Our free DBF Analyzer shows what your files actually declare.
What are the .fpt / .dbt / .cdx / .ntx files next to our DBFs?
.fpt and .dbt hold memo (long text/binary) content — the DBF itself only stores block pointers, so copying a DBF without its memo file destroys those fields. .cdx and .ntx are indexes; beyond speed, their expressions often encode real rules (unique keys, filtered views, collation-dependent ordering) that must be reproduced in SQL. Losing track of these companions is the single most common self-inflicted wound in DIY migrations.
Do deleted records matter?
In xBase, deletion only flags a row; until someone runs PACK the data is still there — and many applications never PACK. We routinely find years of "deleted" transactions still sitting in tables. Migration policy (drop, archive, or restore them) is a business decision we put in front of you with real counts, not a tool default applied silently.
The old application must keep running after the data moves. Possible?
Yes. A one-off cutover is rarely wise, so we build the transfer as a repeatable pipeline that can run nightly or on demand. The legacy app keeps writing DBF; SQL stays in sync as a read-only mirror feeding new reports and systems; write responsibilities move later, module by module, or never — a permanent live mirror is a perfectly valid end state for reporting and BI.
Start with a fixed-price Legacy Assessment
One to two weeks. You get a full inventory of the application and its data, a risk map (what breaks first, what is undocumented, what nobody can rebuild), a data-quality report and a migration roadmap with honest effort estimates — a document you can execute with us or with any other team. Fixed price, agreed before we start.