Problem Overview
Engineers running SIMATIC WinCC Runtime or WinCC Professional frequently need to extract process values (flow rates, temperatures, pressures, alarm states) from the proprietary compressed archive on a fixed cadence and feed those values to downstream systems such as a historian, an MES layer, a reporting engine, or a custom analytics database. The simplest workflow reads the WinCC archive through the WinCC OLE DB Provider, returns a rowset with SQL, and either writes the result directly to a CSV file or hands the rowset to a SQL Server Integration Services (SSIS) package for transformation, file production, and incremental appending.
The symptom reported in the field is consistent: a one-shot manual export from the SQL Server Import/Export Wizard works, the file lands on disk, but the next run overwrites or ignores the existing CSV rather than appending new values, and the operator sees no incremental log. The root cause is structural, not a bug: the Import and Export Wizard is a designer tool. It does not natively maintain a growing file, and SSIS Flat File Destination components are configured for create/replace by default. This article documents the exact configuration that produces a continuously updated CSV from a WinCC archive, the VBScript alternative that is sometimes simpler, and the troubleshooting matrix that resolves the common failure modes.
Prerequisites
| Component | Required Version / Note |
|---|---|
| SIMATIC WinCC (TIA Portal) or WinCC V7.x | Runtime with archives enabled, project activated, Tag Logging running |
| WinCC OLE DB Provider | Installed automatically with the WinCC Runtime / Connectivity Pack; CLSID WinCCOLEDBProvider.1
|
| SIMATIC WinCC/Connectivity Pack | Optional; required for WinCC V7 to expose the OLE DB interface to remote SQL clients |
| Microsoft SQL Server (any edition 2014+) | SQL Server Management Studio (SSMS) and SQL Server Agent service running |
| SQL Server Data Tools (SSDT) or Visual Studio with SSIS | Used to author the .dtsx package if SSIS is selected as the orchestration layer |
| User permissions | Windows account with read access to the WinCC project directory, write access to the export path, and SQL db_datareader on the WinCC runtime database |
| Network reachability | The SQL/SSIS host must be able to reach the WinCC server on the COM/DCOM range; the OLE DB provider does not speak TDS by default |
TAG: and ALARM: virtual tables documented in the WinCC Information System under Archive System > WinCC OLE DB Provider. Reference: Siemens Support Entry 38132261 — Export of archive data using the SIMATIC WinCC/Connectivity Pack (OLE DB Provider).WinCC OLE DB Provider Architecture
The WinCC OLE DB Provider exposes the runtime archive to any OLE DB consumer on the same machine (and to remote consumers when the Connectivity Pack is licensed and the DCOM permissions are configured). The provider accepts standard OLE DB connection strings and translates a small SQL dialect into compressed archive reads.
Connection string template (local):
Provider=WinCCOLEDBProvider.1; Catalog=CC_OpenArchive_2024-03-25_12-00-00; Data Source=.\WinCC
Connection string template (remote via Connectivity Pack):
Provider=WinCCOLEDBProvider.1; Catalog=<RuntimeDBName>; Data Source=<WinCCServer>\WinCC; User ID=<WinCCUser>; Password=<Password>; Mode=Read;
The catalog name is visible in WinCC Explorer under Computer > Properties > Runtime Database and in the SQL Server Management Studio instance that ships with WinCC. The runtime database is shipped as CC_<ProjectName>_<YYYY-MM-DD>_<HH-MM-SS>; treat the suffix as fixed once the project is activated.
SQL dialect for archive reads
The provider recognizes two virtual table types: TAG:R (Tag, Realtime/Raw) and ALARM:. The most common hourly export for process data uses the TAG:R form.
SELECT * FROM TAG:R('FlowMeter01','FlowRate','2024-03-25 11:00:00.000','2024-03-25 12:00:00.000')
Argument order: ArchiveName, TagName, StartTime, EndTime. Time literals are passed as YYYY-MM-DD HH:MM:SS.mmm in the WinCC server's local time. The returned columns are Timestamp (UTC, datetime), RealValue (double), Quality (int, OPC quality code), and
Flags (int). For multiple tags in one call, use the wildcard form:
SELECT * FROM TAG:R('ProcessArchive','*','2024-03-25 11:00:00.000','2024-03-25 12:00:00.000')
For aggregated hourly rollups, use the TAE form (Tag Archive Extended) with explicit aggregate functions:
SELECT Timestamp, AVG(RealValue) AS AvgFlow, MAX(RealValue) AS PeakFlow, MIN(RealValue) AS MinFlow, COUNT(*) AS SampleCount FROM TAG:R('ProcessArchive','FlowMeter01.Flow','2024-03-25 00:00:00.000','2024-03-25 23:59:59.999') GROUP BY DATEDIFF(hour, '2024-03-25', Timestamp)
Timestamp by default. Always convert explicitly with CONVERT(datetime, SWITCHOFFSET(Timestamp, DATEPART(TZOFFSET, Timestamp))) if the downstream system expects local time, otherwise your "hourly" extract will drift 60 minutes every DST transition.Step-by-Step: Build an Hourly Append-Ready SSIS Package
The first decision is the file-append model. Two patterns are field-proven and both are documented below.
Pattern A — Append to a single growing CSV (long-lived log)
- Open SQL Server Data Tools (Visual Studio shell) and create a new Integration Services Project.
- Add an OLE DB Connection Manager named
cnxWinCC. Set the provider to Microsoft OLE DB Driver for SQL Server temporarily for the schema-build step, then reconfigure to Native OLE DB\WinCC OLE DB Provider at runtime. The package will read through this connection. - Add a Flat File Connection Manager named
cnxFlowLogpointing atC:\WinCCExport\FlowHourly.csv. On the General page, select Create file only when needed off; this is the default. On the Columns and Advanced pages, configure the column delimiter as comma, the row delimiter as{CR}{LF}, the text qualifier as", and the data type of every column toDT_STR(orDT_WSTRfor Unicode). This avoids Excel locale-driven scientific-notation conversion of long flow values. - Drag a Data Flow Task onto the Control Flow. Open it and add an OLE DB Source. Set the data access mode to SQL command and paste the
TAG:Rquery parameterized with SSIS variables. - Add a Flat File Destination pointing at
cnxFlowLog. This is the critical step for append semantics: open the destination's Advanced Editor and set the component propertyOverwriteCreate(property name in the SSIS API) to 2 = CreateOnce + Append. The default is 0 = CreateAlways, which truncates the file on every run. Reference: Microsoft Learn — Flat File Destination > Custom Properties. - Return to the Control Flow and parameterize the time window. Create two SSIS variables of type
DateTime:HourStartandHourEnd. Use an Execute SQL Task runningUPDATE [?] SET ? = DATEADD(HOUR, DATEDIFF(HOUR, 0, GETDATE()), 0); UPDATE [?] SET ? = DATEADD(HOUR, 1, DATEADD(HOUR, DATEDIFF(HOUR, 0, GETDATE()), 0));against a small parameter table, or simpler: use an SSIS Expression on the OLE DB Source that uses"..." + (DT_WSTR,30) @[User::HourStart]. - Add a Precedence Constraint with an expression
@HourStart < @HourEndto prevent an empty query on a clock-skewed agent. - Save and deploy to the SSIS Catalog (
SSISDB) or the legacy MSDB folder.
Pattern B — Unique file per run (preferred for immutable logs)
- Same project skeleton as Pattern A, but the Flat File Connection Manager uses a property expression on the
ConnectionStringto inject a timestamp:"C:\\WinCCExport\\Flow_" + (DT_WSTR,30) YEAR(GETDATE()) + RIGHT("0" + (DT_WSTR) MONTH(GETDATE()),2) + RIGHT("0" + (DT_WSTR) DAY(GETDATE()),2) + "_" + RIGHT("0" + (DT_WSTR) DATEPART("hh",GETDATE()),2) + RIGHT("0" + (DT_WSTR) DATEPART("mi",GETDATE()),2) + ".csv". - Set the Flat File Destination
OverwriteCreateproperty to 0 = CreateAlways (default) since each run has a unique path. - This pattern is the one most often recommended in WinCC community threads because it avoids the failure mode where a single growing file is locked by an open Excel session or a downstream service, causing the next run to abort with
0xC020200Eor0xC004701A.
Pattern C — VBScript in WinCC (no SQL Server required)
For self-contained WinCC Runtime projects, the WinCC Scripting Runtime can perform the export entirely inside the SCADA without a SQL Server agent. The script is attached to a cyclic trigger of 1 hour.
Option Explicit
Dim sCon, oCon, oRs, sSql, sFile, fso, ts
Const adOpenStatic = 3
Const adLockReadOnly = 1
sCon = "Provider=WinCCOLEDBProvider.1;Catalog=CC_OpenArchive_2024-03-25_12-00-00;Data Source=.\WinCC"
sSql = "SELECT * FROM TAG:R('ProcessArchive','FlowMeter*','" _
& Year(Now) & "-" & Right("0"&Month(Now),2) & "-" & Right("0"&Day(Now),2) _
& " " & Right("0"&Hour(Now),2) & ":00:00.000','" _
& Year(Now) & "-" & Right("0"&Month(Now),2) & "-" & Right("0"&Day(Now),2) _
& " " & Right("0"&Hour(Now),2) & ":59:59.999')"
sFile = "C:\WinCCExport\Flow_" & Year(Date) & Right("0"&Month(Date),2) _
& Right("0"&Day(Date),2) & "_" & Right("0"&Hour(Now),2) _
& Right("0"&Minute(Now),2) & Right("0"&Second(Now),2) & ".csv"
Set oCon = CreateObject("ADODB.Connection")
oCon.Open sCon
Set oRs = oCon.Execute(sSql)
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.CreateTextFile(sFile, True, True)
ts.WriteLine "Timestamp,TagName,RealValue,Quality,Flags"
Do While Not oRs.EOF
ts.WriteLine oRs.Fields(0).Value & "," & oRs.Fields(1).Value _
& "," & oRs.Fields(2).Value & "," & oRs.Fields(3).Value _
& "," & oRs.Fields(4).Value
oRs.MoveNext
Loop
ts.Close
oRs.Close
oCon.Close
Set ts = Nothing
Set oRs = Nothing
Set oCon = Nothing
CreateTextFile(sFile, True, True) with OpenTextFile(sFile, 8, True, -1) to open the file in ForAppending mode, and skip the WriteLine "Timestamp,..." header unless you also write a sentinel that detects first-run vs subsequent-run. The community-validated approach is to keep the unique-name pattern (Pattern B) and let the file system provide the time index.Scheduling the Periodic Run
SSIS packages live in three contexts. Pick the one that matches your infrastructure.
| Context | Scheduling Agent | Service Account | Notes |
|---|---|---|---|
SSIS Catalog (SSISDB) |
SQL Server Agent Job calling SSISDB.catalog.create_execution
|
Agent service account must have read on the WinCC project folder over the network | Most maintainable, supports 32/64-bit runtime choice, central logging in SSISDB.[internal].[operation_messages]
|
| MSDB legacy package | SQL Server Agent Job step of type SQL Server Integration Services Package | Same as above | Simpler, fewer moving parts; preferred for small plants |
| Standalone WinCC | WinCC cyclic trigger or Windows Task Scheduler invoking CScript.exe on a VBS file |
Local SYSTEM or dedicated service account | No SQL Server license required; least coupling to IT infrastructure |
| External orchestrator (cron, Ansible, PowerShell) |
DTExec.exe invoked from a wrapper |
Service account of the orchestrator | Useful in containerized WinCC Runtime on HMI panels |
SQL Server Agent job definition for SSISDB:
USE msdb;
GO
EXEC sp_add_job @job_name = N'WinCC_HourlyFlowExport', @enabled = 1;
EXEC sp_add_jobstep @job_name = N'WinCC_HourlyFlowExport',
@step_name = N'Run SSIS Package',
@subsystem = N'SSIS',
@command = N'/ISSERVER "\SSISDB\WinCCExport\Packages\Pkg_FlowHourly.dtsx" /SERVER "sql-host\wincc" /ENVREFERENCE 1 /Par "\$Package.HourStart" "2024-03-25 11:00:00"',
@retry_attempts = 3,
@retry_interval = 5;
EXEC sp_add_schedule @schedule_name = N'EveryHour',
@freq_type = 4, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 60;
EXEC sp_attach_schedule @job_name = N'WinCC_HourlyFlowExport', @schedule_name = N'EveryHour';
EXEC sp_add_jobserver @job_name = N'WinCC_HourlyFlowExport';
DTExec parameters: When invoking from a SQL Server Agent Job Step the subsystem SQL Server Integration Services Package parses a single line of switches. Long package paths must be quoted with care; nested " characters are escaped as \" in the @command parameter when used in a T-SQL call but stay plain in the SSMS Job Step UI.Comparison: SSIS vs VBScript vs Connectivity Pack
| Criterion | SSIS (.dtsx) | VBScript in WinCC | WinCC Connectivity Pack OLE DB |
|---|---|---|---|
| License cost | SQL Server Standard+ required for SSIS/Agent | Free with WinCC | Connectivity Pack license required for remote OLE DB |
| Append safety | High — property OverwriteCreate=2
|
Moderate — manual OpenTextFile(... 8)
|
Same as VBScript; the pack is just the data access |
| Scheduling | Native via Agent | WinCC cyclic or Task Scheduler | Same — pack is not a scheduler |
| Error handling | Built-in event handlers, package logging, Agent job history | Manual On Error Resume Next
|
Manual |
| Best for | Plants with IT/OT separation, multiple sites, audit trails | Standalone machines, panel-based Runtime, no SQL Server | Large V7 deployments with remote reporting servers |
Troubleshooting Matrix
| Symptom | Hex / Error Code | Likely Root Cause | Resolution |
|---|---|---|---|
| SSIS run creates file once, then fails on every subsequent run |
DTS_E_CANNOTACQUIRECONNECTIONFROMCONNECTIONMANAGER 0xC020801F |
The OLE DB connection is in RetainSameConnection=False mode and the WinCC catalog is being cycled | Set RetainSameConnection=True on the OLE DB Connection Manager and ensure the WinCC project stays activated |
| CSV is overwritten each run, no history retained | 0xC020200E (cannot acquire interface) | Flat File Destination OverwriteCreate=0 (default) |
Set OverwriteCreate=2 per the Flat File Destination custom properties, or switch to the unique-name pattern |
| Query returns 0 rows for the requested window | None — silent empty result | WinCC uses UTC internally; your TimeBegin is in local time so the window misses the data |
Subtract 1 hour from TimeBegin/TimeEnd or convert to UTC explicitly |
| "The WinCC OLE DB Provider cannot be initialized" | 0x80004005 (Unspecified error) | DCOM permissions, WinCC Runtime not running, or wrong catalog name | Verify catalog against WinCC Explorer, run dcomcnfg and grant the SQL service account launch and activation rights on the WinCC applications |
| SSIS job history shows Access is denied on the export path | 0x80070005 | SQL Server Agent service account has no write rights to C:\WinCCExport
|
Grant Modify on the target directory to the Agent service account (typically NT SERVICE\SQLSERVERAGENT) |
| SSIS package runs interactively but fails under the Agent | 0xC00160AC (loading package) | 32/64-bit mismatch: SSIS 32-bit tool on a SQL Server 64-bit instance without the 32-bit runtime | Install Microsoft SQL Server 2014 Integration Services feature in 32-bit mode, or use DTExec.exe -PA and set the project property Run64BitRuntime=False |
Time column arrives as 0001-01-01
|
None — data type issue | Flat File Connection Manager declared the column as DT_STR but the source is DT_DBTIMESTAMP
|
|
Set the column's data type to DT_DBTIMESTAMP and let the SSIS pipeline convert it on output | |||
| Hourly job runs but downstream system sees no new file for 90 minutes | None — schedule issue | Agent job is in CatchUp mode and is replaying missed runs after an outage | Disable catch-up by setting @freq_subday_interval carefully and avoid setting @freq_interval=0
|
Performance and Capacity Considerations
Reading 10,000 tags for a one-hour window through the WinCC OLE DB Provider typically completes in 2-8 seconds on a WinCC V7.4 SP1 server with 16 GB RAM and a local SSD archive volume. The provider reads the compressed archive in a single thread; SSIS does not parallelize the OLE DB Source by default. For high-fan-out scenarios (>1,000 tags per hour), consider:
- Splitting the tag list into multiple
TAG:Rcalls inside SSIS Sequence Containers and fanning out with a precedence constraint, then re-joining via Union All. - Switching to the
TAEaggregated query and pre-aggregating in WinCC with a Tag Aggregation of type Sum, Average, Min, Max per hour — the provider then reads only the rollup rows. - Indexing the export target directory on the SSIS host by NTFS file system to avoid slow creation of millions of small files when Pattern B is selected.
- Compressing the export directory with NTFS compression or piping through gzip via a Script Task in SSIS to keep disk usage bounded for years of hourly history.
For reference, the SIMATIC WinCC Information System and the Siemens application example 38132261 benchmark a 5,000-tag hourly export at ~6 seconds for raw values and ~0.4 seconds for aggregated values on the recommended hardware.
Verification Checklist
- Confirm the
.dtsxpackage runs successfully from SSDT (one successful execution in the SSIS Catalog All Executions report). - Trigger the SQL Server Agent job manually; verify a new file appears in the export directory within the expected cadence.
- Wait two consecutive hours; verify the file count or file size grows monotonically (append pattern) or new files appear with the expected timestamp pattern (unique-name pattern).
- Open the latest CSV in a text editor and validate the header row, the column count, and that the
Timestampcolumn advances by exactly one hour per row group. - Pull a row from the CSV into a SQL staging table and cross-check the value against the live WinCC online trend — values must match within the configured acquisition cycle (typically 500 ms or 1 s).
- Force a WinCC Runtime restart; confirm the next scheduled run still produces a file. This validates the
RetainSameConnectionand catalog-name behavior across re-activation. - Inspect the SSIS Catalog All Messages view for the job to ensure no warnings (yellow triangles) remain that could become failures under load.
Field-Proven Pitfalls
-
Catalog name changes after re-activation. Every time the WinCC project is reactivated, the runtime database name changes (the timestamp suffix updates). Hard-coded catalog names in connection strings break silently. Always derive the catalog dynamically from WinCC Explorer > Computer > Properties or query
SELECT name FROM sys.databases WHERE name LIKE 'CC[_]%'on the bundled SQL Server instance. - 32-bit provider on 64-bit OS without WoW redirection. The WinCC OLE DB Provider is 32-bit only on older WinCC versions (pre-V7.4). The 64-bit DTExec will fail to load it. Verify the bitness by inspecting the connection manager from the SSDT designer.
-
TagLoggingFast acquisition vs TagLoggingSlow. The default cyclic archive is TagLoggingSlow at 1 s. Flow meters with 100 ms acquisition end up in TagLoggingFast and are not visible to the standard
TAG:Rquery unless the correct archive name is supplied as the first argument. -
Time-zone DST. The hour window computed by
DATEADD(HOUR, DATEDIFF(HOUR, 0, GETDATE()), 0)returns the local clock hour, not a fixed UTC offset. On the spring-forward day the job runs 23 times; on fall-back it runs 25. Use UTC windows to get exactly 24 per day. -
Locking the CSV in Excel. If the user opens the unique-named CSV in Excel while the next hour's export is being written, the write fails with
0x80070020(sharing violation). Switch to the append pattern or use a staging directory that is rotated on completion.
Architectural Diagram
References in Context
The architectural foundation is documented in the Siemens TIA Portal Help for Access to archive data via WinCC OLE DB Provider (RT Professional) and the classic WinCC V7 Information System. The application example at Siemens Support 38132261 provides the three canonical architectures: direct OLE DB, Connectivity Pack relay, and the SQL Server / SSIS route discussed in this article.
FAQ
Why does my SSIS package produce a CSV on the first run but fail on every subsequent hourly run?
The Flat File Destination's OverwriteCreate property defaults to 0 (CreateAlways), which truncates the file but raises a file-locking error when the destination file is held open by Excel, an antivirus scan, or a downstream consumer. Set OverwriteCreate=2 for append semantics, or switch to a per-run filename pattern using a property expression on the ConnectionString.
How do I keep the WinCC OLE DB connection string valid across project re-activations?
Read the catalog name from WinCC Explorer > Computer > Properties > Runtime Database after every re-activation. The catalog follows the pattern CC_<ProjectName>_<YYYY-MM-DD>_<HH-MM-SS> and changes on each activation. Persist the catalog in an SSIS Package Parameter or a SQL configuration table queried at the start of the package.
Can I avoid SQL Server entirely and still get hourly CSV exports from WinCC?
Yes. Use a VBScript (Pattern C above) attached to a WinCC cyclic trigger, or a Windows scheduled task running CScript.exe HourlyExport.vbs. The script uses ADODB.Connection with the WinCC OLE DB provider and Scripting.FileSystemObject to write the CSV. No SQL Server license is required.
My TAG:R query returns zero rows even though values exist in the online trend — what is wrong?
Three common causes: (1) the time window is in local time but the archive stores UTC — subtract 1 hour or convert to UTC; (2) the tag is in the TagLoggingFast archive but the query is using the default TagLoggingSlow archive name as the first argument; (3) the tag is being archived in a different WinCC project than the one whose catalog is referenced in the connection string.
How do I schedule an SSIS package to run every hour from SQL Server Agent?
Create a SQL Server Agent job with a step of subsystem SQL Server Integration Services Package pointing at the deployed .dtsx. Add a schedule with @freq_type=4 (daily), @freq_subday_type=1 (at the specified time), and @freq_subday_interval=60 (every 60 minutes). Make sure the SQL Server Agent service account has read access to the WinCC project directory and write access to the export path.
What is the difference between TAG:R and TAE queries?
TAG:R (Tag Raw) returns individual archived values inside the time window — one row per acquired sample. TAE (Tag Archive Extended) returns the same data but supports SQL aggregation (GROUP BY, AVG, MAX, MIN) and is the recommended form for hourly rollups because the aggregation is performed in the WinCC archive engine before the rowset leaves the server.