WinCC 6.0 External SQL Database Tag Logging with VBScript

David Krause13 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

1. Overview

Siemens WinCC 6.0 is a SCADA/HMI runtime that stores process values, alarms, and internal tag data inside its own Microsoft SQL Server instance (the runtime database, suffixed with R). For most user applications this archive is sufficient. However, when an external MES, historian, ERP, or reporting tool needs direct read/write access to live process data without going through the WinCC user archive API, engineers often need to push selected tag values into a custom SQL table on a separate database.

The native and most maintainable way to do this in WinCC 6.0 is a VBScript action that:

  1. Reads the desired tags through the HMIRuntime.Tags object model.
  2. Opens an ADODB connection to the target SQL Server using an OLE DB provider.
  3. Executes a parameterised INSERT (or UPDATE / MERGE) into a user-defined table.

This reference walks through the prerequisites, ODBC configuration, table design, full working script, action placement, error handling, verification, and a troubleshooting matrix. It closes with a migration path to WinCC Unified (TIA Portal V20), where the same pattern is implemented in JavaScript.

Scope: This document targets WinCC 6.0 SP3/SP4 with Microsoft SQL Server 2000/2005. The same VBScript pattern applies to WinCC 7.x with minor provider adjustments. For WinCC Unified / RT Unified, see Section 14.

2. Architecture: WinCC Internal Archive vs External SQL Table

WinCC 6.0 installs its own SQL Server (MSDE 2000 on small projects, SQL Server 2005 Express on larger ones). The runtime creates two databases named after the project:

  • <ProjectName> – the configuration database (project settings, picture tree, tag definitions).
  • <ProjectName>R – the runtime database (process value archive, alarm archive, user archive).

Tag values generated at runtime are written into compressed archive tables inside <ProjectName>R (typically PDE#<TagName> for process data and ALG#<TagName> for alarms). The internal schema is not officially supported for direct SELECT from third-party applications – the column layout, partitioning, and compression are subject to change between SP and Hotfix levels.

For external consumers the recommended pattern is therefore a parallel, fully documented SQL database that WinCC writes to through a script. This decouples the SCADA archive from the consumer schema and survives WinCC hotfixes.

3. Prerequisites

Component Requirement Notes
WinCC 6.0 SP3 or SP4 (Hotfix ≥ HF1 recommended) VBScript engine, HMIRuntime object available out of the box
SQL Server SQL Server 2000 SP4, 2005 SP2, or 2005 Express on WinCC server OR a remote instance If using a remote instance, the WinCC service account must have TCP/IP access on port 1433 (default)
Authentication SQL Server authentication (e.g., sa) or Windows authentication matching the WinCC service account Avoid using sa in production; create a dedicated login with db_datareader / db_datawriter on the target DB
OLE DB Provider SQLOLEDB.1 (native OLE DB) or SQLNCLI (SQL Server Native Client, requires install) SQLOLEDB ships with MDAC/WinCC; SQLNCLI provides better performance on 2005+
Database & Table Target database (e.g., PROCESS_DATA) with a pre-created table (e.g., DATA) Schema must exist before the script runs; the script does not auto-create the table
Permissions WinCC service user must be able to read process tags and write to the SQL table Configure in WinCC Explorer → User Administrator and SQL Server Management Studio

4. ODBC / OLE DB Data Source Configuration

Although ADODB can open a connection without a pre-defined DSN, declaring a system DSN makes troubleshooting easier and centralises the connection parameters.

  1. Open Control Panel → Administrative Tools → Data Sources (ODBC) on the WinCC server.
  2. Select the System DSN tab and click Add….
  3. Choose SQL Server (32-bit, even on x64 Windows, because WinCC 6.0 is a 32-bit application) and finish the wizard.
  4. Name: WINCC_PROC. Description: WinCC process data sink. Server: WINCC_SERVER\WINCC (or your instance name).
  5. Configure SQL Server authentication and map to the PROCESS_DATA default database.
  6. Test the data source before leaving the wizard.

If you use a 64-bit OS, the ODBC Administrator under %windir%\SysWOW64\odbcad32.exe is the correct entry point for 32-bit drivers – this is a common gotcha for WinCC 6.0 deployments on Windows Server 2008/2012.

5. SQL Server Table Schema Design

Create the destination table before launching WinCC Runtime. The script assumes the columns match the tag names exactly (case-insensitive on default SQL Server collation).

CREATE DATABASE PROCESS_DATA;
GO
USE PROCESS_DATA;
GO
CREATE TABLE DATA (
    ID          INT IDENTITY(1,1) PRIMARY KEY,
    D_DATE      DATETIME      NOT NULL,
    TAG1        FLOAT         NULL,
    TAG2        FLOAT         NULL,
    TAG3        FLOAT         NULL,
    TAG4        FLOAT         NULL
);
GO
CREATE INDEX IX_DATA_DATE ON DATA (D_DATE DESC);
GO

Recommended design notes:

  • Use DATETIME (not SMALLDATETIME) for sub-second resolution – matches PLC scan rates above 1 Hz.
  • Use FLOAT for analog values; BIT for booleans; NVARCHAR(n) for strings.
  • Index the timestamp column to accelerate downstream time-range queries.
  • Add a retention job (e.g., SQL Server Agent) to delete rows older than the business-defined retention period (typically 90–365 days).

6. VBScript Action Placement in WinCC

WinCC 6.0 supports VBS in three locations. Pick the one that matches the trigger:

Location Trigger Typical Use
Project module (Global Script → Project Modules) Called from other actions or from a C function Reusable helper functions, shared connection logic
Standard module (Global Script → Standard Modules) Called via a function name from pictures or scheduled tasks Wrapper functions for tag logging, alarm acknowledgement
Picture event (right-click object → Properties → Events → VBS Action) Mouse click, value change, screen open Operator-initiated writes, on-screen handshakes
Scheduled task (Computer → Scheduled Tasks → Add Task) Cyclic, one-time, event-driven on a tag Most common for SQL logging – runs in the background

For a logging job that runs every 1–10 seconds, configure a cyclic scheduled task with a 1 s or 5 s interval and call a public function in a standard module. The function executes in the WinCC Runtime context and has access to HMIRuntime.

7. Connection String Reference

Provider Connection String Example When to Use
SQLOLEDB.1 Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Pwd=PASSWORD;Initial Catalog=PROCESS_DATA;Data Source=WINCC_SERVER\WINCC Default. Ships with Windows. Works against SQL 2000 and 2005.
SQLNCLI Provider=SQLNCLI;Integrated Security=SSPI;Initial Catalog=PROCESS_DATA;Data Source=WINCC_SERVER\WINCC SQL Server Native Client (10/11). Best on 2008+; supports TLS 1.2.
MSOLEDBSQL Provider=MSOLEDBSQL;Data Source=WINCC_SERVER\WINCC;Initial Catalog=PROCESS_DATA;Integrated Security=SSPI;Use Encryption for Data=True; Modern OLE DB Driver 18+. Required for TLS 1.2 against SQL 2016+.
DSN-based DSN=WINCC_PROC;Uid=sa;Pwd=PASSWORD; Uses a configured system DSN; centralised credentials.
Security: Avoid hard-coding sa passwords in script source. Create a least-privilege SQL login (e.g., wincc_writer) with db_datawriter on PROCESS_DATA and rotate the password through a WinCC project variable or an environment variable.

8. Reading Tags with HMIRuntime

Tag reads in WinCC VBS go through the HMIRuntime.Tags object. Reading a single tag triggers an internal roundtrip; reading many tags through a TagSet is significantly more efficient.

' Read a single tag
Dim oTag
Set oTag = HMIRuntime.Tags("TANK1_TEMP")
oTag.Read
lngValue = oTag.Value
Set oTag = Nothing

' Read a TagSet (recommended for > 2 tags)
Dim VGrp
Set VGrp = HMIRuntime.Tags.CreateTagSet
VGrp.Add "TAG1"
VGrp.Add "TAG2"
VGrp.Add "TAG3"
VGrp.Add "TAG4"
VGrp.Read

Notes on tag access:

  • Tag names are case-sensitive in WinCC 6.0 and must match the Tag Management exactly.
  • If a tag resides in a different channel/connection, ensure the WinCC service user has read rights on that PLC connection.
  • VGrp.Read returns HmiErrorValue for any failed tag – check VGrp.Error after the call if the values look wrong.

9. Writing to SQL: Complete Working Script

The following standard module function reads four tags, builds an INSERT statement with a server-side timestamp, and commits one row to the DATA table. Drop this into Global Script → Standard Modules as a procedure named WriteTagsToSQL.

Option Explicit

Dim TableName, Uname, DBPassword, DataBaseName, SQLServer
Dim PLCCurrentDateTime
Dim objConnection, objCommand
Dim strConnectionString, strSQL

' ---------- Configurable constants ----------
TableName     = "DATA"
Uname         = "sa"
DBPassword    = "PASSWORD"
DataBaseName  = "PROCESS_DATA"
SQLServer     = "WINCC_SERVER\WINCC"

' ---------- Read a tag group ----------
Dim VGrp
Set VGrp = HMIRuntime.Tags.CreateTagSet
VGrp.Add "TAG1"
VGrp.Add "TAG2"
VGrp.Add "TAG3"
VGrp.Add "TAG4"
VGrp.Read

' ---------- Build the timestamp (use Now() or PLC time) ----------
PLCCurrentDateTime = Year(Now) & "-" & _
                     Right("0" & Month(Now), 2) & "-" & _
                     Right("0" & Day(Now), 2) & " " & _
                     Right("0" & Hour(Now), 2) & ":" & _
                     Right("0" & Minute(Now), 2) & ":" & _
                     Right("0" & Second(Now), 2)

' ---------- Build the connection string ----------
strConnectionString = "Provider=SQLOLEDB.1;Persist Security Info=False;" & _
                      "User ID=" & Uname & ";" & _
                      "Pwd=" & DBPassword & ";" & _
                      "Initial Catalog=" & DataBaseName & ";" & _
                      "Data Source=" & SQLServer

' ---------- Build the INSERT statement ----------
strSQL = "INSERT INTO " & TableName & _
         " (D_DATE, TAG1, TAG2, TAG3, TAG4) VALUES (" & _
         "'" & PLCCurrentDateTime & "'," & _
         "'" & Round(VGrp("TAG1").Value, 2) & "'," & _
         "'" & Round(VGrp("TAG2").Value, 2) & "'," & _
         "'" & Round(VGrp("TAG3").Value, 2) & "'," & _
         "'" & Round(VGrp("TAG4").Value, 2) & "')"

' ---------- Execute ----------
Set objConnection = CreateObject("ADODB.Connection")
objConnection.ConnectionString = strConnectionString
objConnection.Open
Set objCommand = CreateObject("ADODB.Command")
With objCommand
    .ActiveConnection = objConnection
    .CommandText = strSQL
    .Execute
End With

' ---------- Clean up ----------
Set objCommand = Nothing
objConnection.Close
Set objConnection = Nothing

10. Triggering the Script (Cyclic, Event, Time-Based)

  1. Open WinCC Explorer → Computer → Scheduled Tasks.
  2. Right-click and choose Insert New Task….
  3. Type: Cyclic Task – choose a 1 s, 5 s, 1 min, or any user-defined interval.
  4. Under Properties → VB Action, enter a one-line call:
    WriteTagsToSQL
  5. Activate runtime and watch the DATA table fill with one row per interval.

For event-driven logging, attach the same WriteTagsToSQL call to a tag-change event on a picture object or in a project-level action. For one-shot initialisation (e.g., seeding the table at runtime start), use a One-time task triggered by @PRF_ActivateRuntime.

11. Error Handling and Logging

The script above fails silently if the SQL Server is unreachable or credentials are wrong. Wrap the ADODB calls with On Error Resume Next plus a counter to a WinCC internal tag, and emit a WinCC alarm on persistent failure.

On Error Resume Next
objConnection.Open
If Err.Number <> 0 Then
    HMIRuntime.Tags("SQL_WRITE_ERR").Write Err.Number & ":" & Err.Description
    HMIRuntime.Tags("SQL_WRITE_ERR_CNT").Read
    HMIRuntime.Tags("SQL_WRITE_ERR_CNT").Write CLng(HMIRuntime.Tags("SQL_WRITE_ERR_CNT").Value) + 1
    Err.Clear
    Exit Sub
End If
On Error Goto 0

Persist the SQL_WRITE_ERR_CNT tag so it survives runtime restarts. Trend it in the WinCC process screen so a stuck or failing connection becomes visible in the operator's process overview.

12. Verification Procedure

  1. Static check: In the WinCC Graphics Designer, open the VBScript editor and compile (Syntax Check). The script must compile clean.
  2. Manual trigger: Right-click the scheduled task and choose Start once. Verify the row count in PROCESS_DATA.DBO.DATA increases by one.
  3. Spot-check values: Run SELECT TOP 5 * FROM DATA ORDER BY D_DATE DESC in SQL Server Management Studio. Confirm the timestamp advances, and the numeric columns are within expected ranges.
  4. Tag fault injection: Force one of the source tags to an invalid state (e.g., quality bad). The script should still write, but the column should reflect the last good value (WinCC VBS returns the substituted value of 0 for a quality-bad tag unless configured otherwise).
  5. Load test: Run the cyclic task at 1 s for 24 h. The table should grow by ~86,400 rows. If row count is off, check the scheduled task log and the SQL_WRITE_ERR_CNT tag.

13. Troubleshooting Matrix

Symptom Likely Root Cause Remediation
Provider cannot be found (HRESULT 0x80040E14) Wrong provider; SQLNCLI not installed Install the matching native client, or revert to SQLOLEDB.1
Login failed for user 'sa' Mixed-mode auth disabled, or wrong password Enable SQL auth in sp_configure; reset the login password
Cannot open database "PROCESS_DATA" requested by the login Database missing or login not mapped Create the database and run sp_addrolemember 'db_datawriter', 'wincc_writer'
Invalid object name 'DATA' Wrong default schema, table not created, or wrong database in connection string Re-check Initial Catalog; prefix the table with dbo. in the SQL
Script runs but no row appears Auto-commit off, transaction never committed Use .Execute on a Command (autocommits) or call objConnection.CommitTrans
Cyclic task fires but DB is unreachable intermittently TCP/IP disabled on SQL Server, firewall blocking 1433 Enable TCP/IP in SQL Server Configuration Manager; open the firewall on both sides
Tag values are always 0 Tag name typo, or tag not started (no PLC connection) Open Tag Management in WinCC Explorer and check the diagnostics view
Performance degrades after several days Table index fragmented, transaction log full Schedule REBUILD INDEX and DBCC SHRINKFILE jobs
Subscript out of range on VGrp("TAG1").Value Tag name not in TagSet Confirm each VGrp.Add matches a real tag; tags are case-sensitive
Arithmetic overflow writing to FLOAT Source is REAL with NaN/+Inf Wrap with IsNumeric and substitute NULL

14. Migration to WinCC Unified (TIA Portal V20)

WinCC 6.0 is long out of mainstream support. New projects (or major upgrades) should use WinCC Unified, where the equivalent pattern is JavaScript-based and runs directly on the Unified Comfort Panel or the Unified PC runtime.

Key differences for the SQL connection:

  • Use the SQL object and HMIRuntime JavaScript namespace.
  • The connection string uses the MS SQL OLE DB provider; SQLite is also supported.
  • Tags are read with Tags("Tag1").Read() (synchronous) and the connection is opened with sql.Open(connectionString).
  • Scripts are attached in the TIA Portal under Runtime scripting and can be triggered cyclically or by tag change.

Refer to the official Siemens TIA Portal V20 documentation for a working example: Connecting Unified Comfort Panel with SQL database (RT Unified).

For the broader scripting reference inside TIA Portal, browse the Runtime scripting (RT Unified) section of the Siemens documentation portal. Standard WinCC 6.0 manuals and compatibility notes remain available on the Siemens Industry Online Support portal.

15. Field-Proven Notes

  • Provider choice. SQLOLEDB.1 is deprecated by Microsoft but still ships with Windows; for new deployments target SQLNCLI or MSOLEDBSQL to get TLS 1.2 support.
  • Connection pooling. WinCC scripts do not share an ADODB connection – each scheduled task call opens a new one. For high-rate logging (≥ 1 Hz) consider a single long-lived connection stored in a project-global object opened by the startup task and closed at shutdown.
  • Time skew. When WinCC and SQL Server are not synchronised to a common NTP source, the D_DATE column will drift. Use the PLC time instead, or use SYSDATETIME() as a SQL-side default and let the server clock win.
  • Null handling. Round(NULL, 2) raises an error in VBS. Always IsNumeric the value before formatting, and substitute an empty string or NULL literal.
  • SQL injection. The pattern shown concatenates values into the SQL string – safe when the inputs are Round(...,2) numerics, but unsafe if you ever pass user input directly. Switch to a parameterised Command with Parameters.Append for any field that could contain a quote.
  • Retention. On a 1 s logging loop you generate ~3 million rows per month. Add a daily SQL Agent job to delete rows older than the retention window and to rebuild indexes weekly.

16. FAQ

Where exactly do I place the script in WinCC 6.0?

Open Global Script → Standard Modules, create a new module, and paste the procedure. Then create a cyclic scheduled task in Computer → Scheduled Tasks that calls the procedure name (e.g., WriteTagsToSQL) every 1–10 s.

Do I need to configure an ODBC DSN first?

No. ADODB can open a connection from a connection string without a registered DSN. A DSN is recommended only for centralised credential management and for testing the connection outside WinCC.

Can I read the WinCC runtime database directly with SELECT * FROM PDE#TAG1?

Technically yes, but the archive schema is private and subject to change across SP/Hotfix levels. A separate PROCESS_DATA database written to by a VBScript action is the supported, future-proof pattern.

What is the best OLE DB provider for SQL Server 2005 from WinCC 6.0?

Start with Provider=SQLOLEDB.1 (ships with Windows). For better performance and TLS 1.2 support install SQL Server Native Client 10.0 and switch to Provider=SQLNCLI. Avoid MSOLEDBSQL 18 on WinCC 6.0 – it requires the OLE DB Driver 18 redistributable and is meant for modern stacks.

How do I migrate the same logic to WinCC Unified on a Comfort Panel?

Use the JavaScript HMIRuntime.Tags and the SQL scripting object. The official TIA Portal V20 example Connecting Unified Comfort Panel with SQL database (RT Unified) shows a full connection plus INSERT in 30 lines of JavaScript.

Back to blog