Every migration into the Power Platform is the same three decisions in a different order. Where the data lands (SharePoint lists on the licence you already have, or Dataverse at NZ$32.40 per user per month), what gets rebuilt (forms, reports, stored procedures and VBA never move), and what the source does to you on the way (identity columns, multi-value fields, precision, and the thing that talked to the database that nobody wrote down). The sections below are the gotcha lists per source; the fixed-price bands for the work are on the services page. Who this kind of migration is for, and who it is not, is on the Power Platform consultant page.
Where each source usually lands
| Source | Usual home | The one question that flips it | Tool that does the move |
|---|---|---|---|
| SQL Server database | Dataverse | Is it really one flat table under 20,000 rows? Then SharePoint | Power Platform dataflow, through the on-premises data gateway if the server is yours |
| Access database | SharePoint lists, unless money or eight-plus related tables | Does an accountant reconcile anything in it? Then Dataverse | Access: External Data, Export to Dataverse (Dataverse only); a flow or dataflow for SharePoint |
| SharePoint list | Stays a list until it hits a wall | Row-level security, real relationships, or 20,000+ rows? Then Dataverse | Power Apps: new table, Import from SharePoint list |
| Excel workbook | One SharePoint list, or an Excel table in Teams | Two people editing on the same day and money on it? Then a list with an app, or Dataverse | Power Apps: Import from Excel, or a dataflow with cleaning steps |
The reasoning behind that table, with the five-question test, is in SharePoint or Dataverse: how to choose. What follows assumes you have picked a home.
SQL Server to Dataverse
The full decision, costs and timeline are in moving a SQL Server database into Microsoft 365. This is the mechanics, and the eight things that go wrong. The cost, weeks and capacity line on one page is SQL Server to Dataverse in NZ.
The method
- Build the Dataverse tables first, by hand or from the schema: names, relationships, autonumber columns that continue your job or invoice sequence, alternate keys for anything that had a unique index.
- Install the on-premises data gateway on a machine that can reach the SQL Server, if the server is on your network. No inbound ports; it calls out.
- Create a Power Platform dataflow with SQL Server as the source, select the tables, add the cleaning steps in Power Query (trim, fix dates, drop the columns nobody uses), and map each query to its Dataverse table.
- Run it into a dev environment first. Read every row the validator rejects. Fix the data in SQL, not in the target.
- Load parent tables before child tables so lookups resolve, or run the dataflow twice.
- Reconcile row counts and a handful of known records, then repeat on cut-over day into the live environment.
The gotchas
- Identity columns. Dataverse keys every row with a GUID. Your old integer IDs come across as a plain number column, and the sequence continues only if you set up an autonumber column with a seed.
- Foreign keys become lookups. The dataflow needs the parent row to exist first, and it matches on an alternate key, not on your old integer, so define the key before the load.
- Precision. Decimal columns keep up to ten decimal places; float keeps five. Money maps to Currency in the environment's base currency, one currency per row.
- Text lengths. nvarchar(n) becomes Text with a 4,000-character cap; nvarchar(max) becomes Multiline Text. Anything longer than about a million characters needs a file column.
- Blobs. varbinary columns do not load through a dataflow. Export the files, put them in a file or image column or a SharePoint library, and store the link.
- Stored procedures, triggers, views and jobs. None of it moves. Each becomes a Power Automate flow, a business rule, a Dataverse formula column, or a line in the app. Inventory them before you quote.
- Delegation. A canvas app against Dataverse delegates most filters, but a formula that could not be delegated silently stops at 500 rows (2,000 with the setting raised). Test with the real row count, not the sample.
- The thing nobody wrote down. A label printer, an ODBC link from Excel, a Xero sync. List everything that connects to the database from outside, or find out on Monday.
Do I need a licence to run the dataflow itself?
The person building and running the dataflow needs a Power Apps Premium licence, because SQL Server is a premium connector and the gateway needs a premium licence too. One licence for the migration is fine; the ongoing cost is set by who uses the result.
Can I keep SQL Server and just build the app on it?
Yes, through the gateway, and it suits a firm whose server is current and staying. Every user of the app then needs Power Apps Premium at NZ$32.40 a month, the same as Dataverse, and you still patch and back up the server. It is the right call when the database is fine and the front end is the problem.
Access to Dataverse, or to SharePoint lists
The buyer's version, with what it costs, is in moving an Access database off the shared drive, and the short cost-and-weeks version is Access to Power Apps in NZ. The mechanics:
The method, Dataverse
- Copy the .accdb somewhere safe and open it in Access from Microsoft 365 (the migration tool is not in Access 2016 or 2019).
- In Access, change Number: Single and Number: Double columns to Decimal if the values need more than five decimal places. Note every unique index; they do not migrate.
- External Data, Export to Dataverse. Pick the environment (or Dataverse for Teams), optionally a solution, and the tables.
- Read the validator. It lists unsupported types and rows that exceed Dataverse limits, and keeps the failing rows in a local Access table rather than dropping them.
- Let it relink. The Access forms keep working against the cloud tables while the Power App is built alongside.
- Recreate the unique indexes as alternate keys, rebuild multi-value lookups as Choice columns if the validator flagged them, and turn calculated fields back into formula columns.
The method, SharePoint lists
The export tool goes to Dataverse only. For SharePoint, create the lists with the right column types, then load each table with a Power Automate flow or a dataflow reading the Access file from OneDrive. Lookups between lists are plain lookup columns, so load parents first and map the child rows by the parent's title or an ID column you keep.
The gotchas
- Forms, reports, macros, VBA. None of it moves. The forms are the spec for the Power App; the macros and VBA become flows or app logic; the reports become views or Power BI.
- Attachments and OLE objects. Pull them out to files first.
- Multi-value lookups need the two-column shape Microsoft documents before they become Choice columns.
- Two people, one file. The corruption that drove the migration also means the last week of edits may be in two copies. Freeze the file on cut-over day and check the modified dates.
Is Access going away?
Access in Microsoft 365 is supported and still updated. Access 2016 and 2019 left support on 14 October 2025 and Access LTSC 2021 on 13 October 2026, so the version you open the file with is the risk, not the file. Dates are on the end-of-support page.
SharePoint list to Dataverse
This is the outgrew-it move, and it is the easiest of the four. Power Apps has it built in.
The method
- In Power Apps, Tables, New table, Import from SharePoint list. Pick the site and the list.
- Review the column mapping. Text, number, date, yes/no, choice and lookup columns map cleanly; lookups between lists become relationships if the parent list is imported first.
- Import. Items load as rows; version history and item-level permissions do not come across.
- Repoint the canvas app: change the data source from the list to the table. Most formulas survive; anything that used the list's numeric ID or the Title column convention needs a small edit.
- Move flows the same way, one connector swap per action.
The gotchas
- Person columns become lookups to the Dataverse user table; external users and deleted accounts fail to match.
- Managed metadata and rich text need a decision: Choice column, or plain text.
- Permissions. Item-level permissions on the list were probably the reason for the move; they become security roles and a business unit or team structure in Dataverse, designed rather than copied. Dataverse security roles is the guide.
- The 5,000 view threshold that hurt in SharePoint does not exist in Dataverse, but the 500/2,000 delegation ceiling in a canvas app does. Different wall, same symptom.
Should I move a list to Dataverse just because it is big?
Not on size alone. Lists hold 30 million items; the pain is views past 5,000 items without an indexed filter, which indexing and filtered views fix for nothing. Move when you need relationships, row-level security or an audit trail, because that is what the NZ$32.40 a user buys. The 5,000 item limit has the detail.
Excel to Dataverse, or to a list
Most Excel migrations should stop at a SharePoint list. The decision tree is in replacing the spreadsheet that runs your business. When Dataverse is right, the mechanics:
The method
- Make it a table. One header row, one data type per column, no merged cells, no totals row, dates as dates not text.
- Split what is really two tables (jobs and clients on one sheet) into two sheets with a key column.
- Power Apps, Tables, Import from Excel, or a dataflow reading the workbook from OneDrive when you need cleaning steps that repeat.
- Check the type inference. A column with one stray text value becomes Text for the whole column; fix the source and reimport.
The gotchas
- Formulas. Values import, formulas do not. Each formula that matters becomes a formula column, a rollup, or a calculation in the app.
- Colour as data. The red rows meant something. Add a status column before you import, because the colour will not come.
- The 40-column sheet is usually three tables and a report. Import it as one and you have moved the problem, not solved it.
The data-type map, SQL Server and Access to Dataverse
The same table serves both sources. Limits are Dataverse's, checked September 2026.
| SQL Server type | Access type | Dataverse column | Watch for |
|---|---|---|---|
| int, smallint, tinyint | Number: Integer, Long Integer | Whole Number | Range is plus or minus 2,147,483,647 |
| bigint | Large Number | Big Integer | Usable through the API; canvas apps do not display it natively |
| decimal, numeric | Number: Decimal | Decimal Number | Up to 10 decimal places |
| float, real | Number: Single, Double | Floating Point Number | Up to 5 decimal places; change to Decimal at the source if that matters |
| money, smallmoney | Currency | Currency | One base currency per environment; the migration assumes it |
| nvarchar(n), varchar(n), char | Short Text | Text | 4,000-character cap |
| nvarchar(max), text | Long Text, Rich Text | Multiline Text, Rich Text | Up to 1,048,576 characters |
| bit | Yes/No | Yes/No | NULL becomes No unless you decide otherwise |
| datetime, datetime2 | Date/Time | Date and Time | Choose user-local or time-zone independent per column; get it wrong and every date shifts by 12 hours |
| date | Date/Time (date part) | Date Only | Not supported in Dataverse for Teams |
| uniqueidentifier | GUID | Unique Identifier | Used as keys only |
| identity column | AutoNumber | Autonumber | Set the seed so the sequence continues |
| foreign key | Lookup (single value) | Lookup (relationship) | Load parents first; match on an alternate key |
| varbinary, image | Attachment, OLE Object | File or Image | Not loaded by dataflow or the Access tool; export the files first |
| computed column | Calculated field | Formula or Calculated column | The Access tool stores the value; recreate the formula |
| unique index | Unique index | Alternate key | Not migrated by either tool; recreate by hand |
| lookup table with fixed values | Multi-value lookup, value list | Choice, Choices | Needs the two-column shape in Access before export |
| hyperlink stored as text | Hyperlink | URL | Fine |
The licence line, in NZD
| Home | Per user, per month | Notes |
|---|---|---|
| SharePoint lists | $0 on top of Microsoft 365 | Standard connectors only; the moment a flow touches SQL, HTTP or Xero it becomes premium |
| Dataverse | NZ$32.40 (Power Apps Premium, paid yearly) | 10 GB tenant default plus 250 MB database per licence; add-on NZ$64.70 per GB a month |
| Keep SQL Server, app through the gateway | NZ$32.40 | SQL Server is a premium connector; the gateway needs a premium licence |
| A standalone premium flow (the nightly sync) | NZ$24.30 for its owner (Power Automate Premium) | Or NZ$242.70 a month for a flow with no owner; usually the wrong buy |
Microsoft's NZ price list, checked September 2026; the capacity side (what the tenant gets free, what 1 GB holds) is on Dataverse pricing in NZ. The whole list is on Power Platform pricing in NZ. The worked totals for 5, 10 and 20 people are in what Power Automate actually costs a small NZ business, and the app side in what a custom Power App costs.
When I would leave it alone
- The database sits under a vendor product that is still supported. Migrating it breaks the product; ask the vendor for their hosted version instead.
- The server is current and the only complaint is the front end. Build the app through the gateway and keep the database.
- Under about 500 rows and one editor. A SharePoint list or an Excel table in Teams, no project.
- The reason is "Dataverse sounds more proper". When Power Platform is the wrong answer has the longer list.
Copy first, improve second: how to move a desktop database without changing how you work.
Trial loads and fake data: what each stage of test data catches.
Coming from Visual FoxPro? Export first, then pick the destination.
Where to next
The 38-point migration checklist is the working document for any of the four; it is free and it works with whoever you hire. If the server underneath is on a deadline, the end-of-support dates set the timeline. If you are in Canterbury or anywhere in NZ and want it done at a fixed price, that is the job I do.