Configuring Periodic CSV Export from WinCC OLE DB Archive

David Krause16 min read
SiemensTutorial / How-toWinCC
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

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
Important: The WinCC archive is a proprietary compressed store, not a standard relational database. Direct SELECT against tables returns the configuration schema only. Process values are surfaced through the 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)
Time-zone trap: WinCC stores raw archive entries in UTC and the provider returns the UTC 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)

  1. Open SQL Server Data Tools (Visual Studio shell) and create a new Integration Services Project.
  2. 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.
  3. Add a Flat File Connection Manager named cnxFlowLog pointing at C:\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 to DT_STR (or DT_WSTR for Unicode). This avoids Excel locale-driven scientific-notation conversion of long flow values.
  4. 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:R query parameterized with SSIS variables.
  5. 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 property OverwriteCreate (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.
  6. Return to the Control Flow and parameterize the time window. Create two SSIS variables of type DateTime: HourStart and HourEnd. Use an Execute SQL Task running UPDATE [?] 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].
  7. Add a Precedence Constraint with an expression @HourStart < @HourEnd to prevent an empty query on a clock-skewed agent.
  8. Save and deploy to the SSIS Catalog (SSISDB) or the legacy MSDB folder.

Pattern B — Unique file per run (preferred for immutable logs)

  1. Same project skeleton as Pattern A, but the Flat File Connection Manager uses a property expression on the ConnectionString to 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".
  2. Set the Flat File Destination OverwriteCreate property to 0 = CreateAlways (default) since each run has a unique path.
  3. 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 0xC020200E or 0xC004701A.

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
Append note for Pattern C: Replace 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';
Note on 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:R calls inside SSIS Sequence Containers and fanning out with a precedence constraint, then re-joining via Union All.
  • Switching to the TAE aggregated 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

  1. Confirm the .dtsx package runs successfully from SSDT (one successful execution in the SSIS Catalog All Executions report).
  2. Trigger the SQL Server Agent job manually; verify a new file appears in the export directory within the expected cadence.
  3. 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).
  4. Open the latest CSV in a text editor and validate the header row, the column count, and that the Timestamp column advances by exactly one hour per row group.
  5. 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).
  6. Force a WinCC Runtime restart; confirm the next scheduled run still produces a file. This validates the RetainSameConnection and catalog-name behavior across re-activation.
  7. 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:R query 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

PLC / Field S7-1500, ET200SP Flow meters WinCC Runtime Tag Logging archive WinCC OLE DB Provider SQL / SSIS Host SQL Server Agent SSIS package (.dtsx) Export Target C:\WinCCExport Flow_*.csv Schedule loop (hourly) Agent fires → SSIS reads TAG:R → Flat File Destination OverwriteCreate=2 (append) OR unique filename

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.

Back to blog