Export
From a table in the tree, or from a result grid through the context menu.
Three formats. CSV, with or without a header row. JSON, as an array of objects. SQL, as
INSERT statements.
Three scopes, each carrying its count.
| Scope | What it writes |
|---|---|
| Selection | The rows you selected in the grid |
| Page | The rows on the page in front of you |
| All | Every row the source has |
The counts are on the buttons, and the scope starts on whatever you actually have: a selection if there is one, the page otherwise. Starting on "everything" is how an export of one row becomes an export of four million.
"All" for a table is answered by a fresh query rather than by the page, so the number on that button is the number of rows the table has. That distinction is the whole reason the counts are shown.
Options. Column headers for CSV. ISO 8601 for dates, which is what you want for anything another program will read.
Progress is reported as it goes and can be cancelled. A cancelled export says how many rows it had written, since the file is on disk either way.
Import
Three steps, because the decisions depend on each other, and nothing is written until the third one finishes.
1. File. A CSV or a JSON file. For CSV: whether the first row is headers, which delimiter, and
whether an empty field means NULL or an empty string. That last one is on by default, since a CSV
has no way to tell the two apart and a missing value is a null.
A line under the options says roughly how many rows the file holds, which is the sanity check on the delimiter: a file that reads as one row has been split on the wrong character.
2. Destination. The table to write into. Nothing else, because everything else depends on which table it is.
3. Columns. Two decisions on one page.
What to do when a row collides with one already there:
| On a collision | Does |
|---|---|
| Skip the row | Leaves the row that is there and counts the one from the file as skipped |
| Update | A MERGE, so a row that is not there is still inserted |
| Stop the import | Abandons the import. What has been written stays written, and the report says how much |
All three were measured rather than assumed. Update matters most: an update path that only updated would silently drop every new row in the file.
Then the mapping: which column of the file goes into which column of the table. Names that match are mapped for you, and anything left over is yours to map or to leave out.
What happens when a row is refused
The import writes in batches rather than as one transaction. That is the default deliberately: the mode that cannot fail partway is also the mode that fails on the largest file. A cancel stops at a batch boundary, and the report says honestly how many rows are already in the database.
All-or-nothing is a checkbox, for when you genuinely need it, and it says what it costs.
Every refusal carries its reason and its line. The reason is the engine's own message, in the engine's words, and the line number is the number in the file, one-based: with a header row the first row of data is line 2, which is what an editor will show you when you go to fix it.
The report lists the first ten. Where an import refused fifteen rows, ten of them are on screen and the count tells you there are five more.
Where to go next
- Data and editing, the grid these come from
- Query editor, for anything the dialogs will not do
- WitSQL,
MERGEand the rest