SyteLine Incremental Extract Query Generator for SSIS and ETL
This generator writes a complete watermark pattern for pulling one Infor SyteLine 9/10 table into a staging database incrementally with SQL Server Integration Services, Azure Data Factory or any ETL tool. It uses the system columns every SyteLine _mst table carries, RowPointer as the stable key and RecordDate as the change marker.
Fill in
One _mst table per run, for example item_mst, co_mst, coitem_mst, job_mst, matltran_mst.
RecordDate catches inserts and updates; CreateDate only catches new rows.
1. Watermark table (staging database, not the SyteLine database)
CREATE TABLE dbo.etl_watermark (
table_name sysname NOT NULL,
site_ref nvarchar(20) NOT NULL,
last_value datetime2(3) NOT NULL,
CONSTRAINT PK_etl_watermark PRIMARY KEY (table_name, site_ref)
);
INSERT INTO dbo.etl_watermark (table_name, site_ref, last_value)
VALUES (N'coitem_mst', N'MAIN', '1900-01-01');2. Delta extract (run on the SyteLine reporting replica)
-- @LastValue comes from the watermark table, @RunStart is captured once at the start of the run
DECLARE @Site nvarchar(20) = N'MAIN';
DECLARE @Overlap int = 5;
DECLARE @LastValue datetime2(3) = ?; -- parameter mapped by SSIS/ADF
DECLARE @RunStart datetime2(3) = ?; -- parameter mapped by SSIS/ADF
SELECT
co_num, co_line, co_release, item, qty_ordered, qty_shipped, stat, due_date,
RowPointer,
RecordDate,
CreateDate
FROM dbo.coitem_mst
WHERE site_ref = @Site
AND RecordDate > DATEADD(minute, -@Overlap, @LastValue)
AND RecordDate <= @RunStart;3. Advance the watermark (only after the load commits)
-- Separate batch: map the same @RunStart value captured for block 2 to the ? marker UPDATE dbo.etl_watermark SET last_value = ? WHERE table_name = N'coitem_mst' AND site_ref = N'MAIN';
4. Delete detection (land the full key list, then compare)
-- Extract on the source replica into dbo.land_coitem_keys:
-- SELECT RowPointer FROM dbo.coitem_mst WHERE site_ref = N'MAIN';
-- Then in the staging database:
DELETE t
FROM dbo.stg_coitem t
WHERE NOT EXISTS (
SELECT 1
FROM dbo.land_coitem_keys k
WHERE k.RowPointer = t.RowPointer
);5. MERGE landed delta into the staging table on RowPointer
MERGE dbo.stg_coitem AS t
USING dbo.land_coitem AS s
ON t.RowPointer = s.RowPointer
WHEN MATCHED AND s.RecordDate > t.RecordDate THEN
UPDATE SET t.co_num = s.co_num, t.co_line = s.co_line, t.co_release = s.co_release, t.item = s.item, t.qty_ordered = s.qty_ordered, t.qty_shipped = s.qty_shipped, t.stat = s.stat, t.due_date = s.due_date, t.RecordDate = s.RecordDate
WHEN NOT MATCHED BY TARGET THEN
INSERT (co_num, co_line, co_release, item, qty_ordered, qty_shipped, stat, due_date, RowPointer, RecordDate)
VALUES (s.co_num, s.co_line, s.co_release, s.item, s.qty_ordered, s.qty_shipped, s.stat, s.due_date, s.RowPointer, s.RecordDate);
TRUNCATE TABLE dbo.land_coitem;Verify on your SyteLine 9/10 database: that RowPointer is uniqueidentifier and unique on the table, and that RecordDate is refreshed on every update for the tables you extract (check the update triggers or update a test row and compare). The ? markers are OLE DB parameter placeholders for an SSIS Execute SQL or source task; replace them with @-parameters for ADO.NET or ADF. Keep the column lists in the three fields in the same order. Extract from a reporting replica, never through views that rely on the session site context.
Planning a SyteLine data warehouse?
Send us your table list and refresh targets and we will review the extract design, watermark choices and delete handling for your version.
Optional. The tool and every export work without this. No spam.
How to use it
Enter the source table and the business columns you need, then the matching MERGE update and insert lists in the same order. Block 1 runs once in your staging database to create the control table and seed it with an old date. Each scheduled run then does four steps: read last_value from the control table and capture the run start time, execute block 2 on the SyteLine replica and land the rows into the landing table, run block 5 to MERGE them into the staging table, and finally run block 3 to move the watermark to the captured run start. Run block 4 on a slower schedule, nightly or weekly, for tables where deleted rows matter. In SSIS this maps to an Execute SQL task, a data flow and two more Execute SQL tasks inside a sequence container.
- Seed with 1900-01-01 so the first run is a full load
- Capture @RunStart once, before the extract, and reuse it for the update
- Update the watermark only after the MERGE commits
Why RowPointer and RecordDate
SyteLine tables carry a set of system columns: RowPointer, RecordDate, CreateDate, CreatedBy, UpdatedBy and NoteExistsFlag. RowPointer is a GUID that identifies the row for the lifetime of the record, so it is a better merge key than business keys that users can renumber or that span several columns. RecordDate is maintained by SyteLine on change, which makes it a usable high-water mark for inserts and updates. CreateDate only moves on insert, so use it as the watermark only for append-only tables. The overlap window re-reads a few minutes before the last watermark, which covers transactions that committed late with an earlier timestamp. The MERGE condition on RecordDate stops a re-read row from overwriting a newer copy.
Worked example
For coitem_mst at site MAIN with a 5 minute overlap: the last run finished with a watermark of 06:00:00. The 07:00 run captures @RunStart 07:00:00 and extracts rows with RecordDate after 05:55:00 and up to 07:00:00. Suppose 1,240 order lines changed; perhaps 40 of them were already loaded last hour and come back because of the overlap. The MERGE updates those 40 only if their RecordDate moved, inserts genuinely new RowPointers, and the watermark becomes 07:00:00. If the load fails part-way, the watermark stays at 06:00:00 and the next run simply repeats the window, because the pattern is idempotent.
Gotchas
Deletes never show up in a RecordDate delta, which is why block 4 compares full RowPointer sets. Mass updates through SQL scripts that disable triggers will not move RecordDate, so after any data fix run a full reload of that table. Clock skew between the replica and the ETL server matters less than it seems because the window uses the SyteLine server time stored in the rows, but always take @RunStart from the source server. Read from an Always On readable secondary or a log-shipped copy, not production. Avoid SyteLine views that filter by the session site: an ETL login has no site context and can return nothing or the wrong site. Index RecordDate on large tables such as matltran_mst only after checking the impact with your DBA.
Frequently Asked Questions
What is SQL Server Integration Services used for with SyteLine?
SSIS is Microsoft's ETL tool that ships with SQL Server. With SyteLine it typically moves data from the ERP database into a reporting or warehouse database on a schedule, so heavy reporting, Power BI models and AI retrieval run against a copy instead of the live transactional database.
How do I do an incremental load in SSIS?
Keep a watermark table with the last loaded timestamp per source, read it into a variable, extract only rows changed after it (minus a small overlap), load into a landing table, MERGE into the target on a stable key, then advance the watermark. This generator writes each of those statements for a SyteLine table.
Is RowPointer unique in SyteLine tables?
RowPointer is the uniqueidentifier system column that SyteLine and the IDO layer use to identify a row, and it is unique per table. Confirm the data type and that a unique index exists on your version with sp_help before you rely on it as the merge key.
Why not use SQL Server change tracking instead?
Change tracking or CDC can be better for very high volume tables, but they need database-level configuration on the ERP database and DBA ownership through upgrades. The RecordDate watermark needs no change to the SyteLine database and works from a read-only replica, which is why it is the usual first step.
If you want this staging data to feed a private assistant that answers SyteLine questions on your own servers, we can build that on top of the same extract.
Related Tools
SyteLine Database Tables Reference
Searchable lookup of the main SyteLine SQL tables, what each holds and its usual business key, for writing queries and reports.
Developer ToolsSyteLine Open Purchase Order Query Generator
Builds a read-only SQL query for open and late PO lines in SyteLine 9/10, with a second query for vendor on-time delivery from PO receipts.
Developer ToolsSyteLine IDO REST Paging Throughput Calculator
Estimate how many REST calls, how much payload and how long a bulk IDO read takes for a given recordcap, and find a page size that avoids timeouts.
Developer ToolsSyteLine SQL Blocking and Long Running Query Script Generator
Builds read-only SQL Server diagnostic scripts for blocking, head blockers, open transactions and slow requests on a SyteLine database.
More Developer Tools tools
See all- SyteLine IDO REST Request Generator
- SyteLine SQL Query Generator for Item, Job and Order Tables
- SyteLine Custom Table CREATE Script Generator
- SyteLine Mongoose Framework Events Reference
- SyteLine Event Action Types Reference
- SyteLine Event Action Parameter Functions Reference
- SyteLine WinStudio Standard Form Events Reference
- SyteLine Mongoose API Options Reference
- SyteLine SQL User-Defined Data Types Reference
Keep exploring
Free tools
- ERP Incremental Extract Watermark SQL GeneratorGenerate a T-SQL script that pulls only new and changed ERP rows using a watermark control table.
- SyteLine Open Purchase Order Query GeneratorBuilds a read-only SQL query for open and late PO lines in SyteLine 9/10, with a second query for vendor on-time delivery from PO receipts.
- ERP Data Extract PowerShell to CSV Script GeneratorCreates a scheduled-task-ready PowerShell script that runs a read-only SQL query and writes a timestamped CSV with a simple log.