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:
- Reads the desired tags through the
HMIRuntime.Tagsobject model. - Opens an ADODB connection to the target SQL Server using an OLE DB provider.
- Executes a parameterised
INSERT(orUPDATE/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.
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.
- Open Control Panel → Administrative Tools → Data Sources (ODBC) on the WinCC server.
- Select the System DSN tab and click Add….
- Choose SQL Server (32-bit, even on x64 Windows, because WinCC 6.0 is a 32-bit application) and finish the wizard.
- Name:
WINCC_PROC. Description:WinCC process data sink. Server:WINCC_SERVER\WINCC(or your instance name). - Configure SQL Server authentication and map to the
PROCESS_DATAdefault database. - 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(notSMALLDATETIME) for sub-second resolution – matches PLC scan rates above 1 Hz. - Use
FLOATfor analog values;BITfor 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. |
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.ReadreturnsHmiErrorValuefor any failed tag – checkVGrp.Errorafter 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)
- Open WinCC Explorer → Computer → Scheduled Tasks.
- Right-click and choose Insert New Task….
- Type: Cyclic Task – choose a 1 s, 5 s, 1 min, or any user-defined interval.
- Under Properties → VB Action, enter a one-line call:
WriteTagsToSQL - Activate runtime and watch the
DATAtable 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
- Static check: In the WinCC Graphics Designer, open the VBScript editor and compile (Syntax Check). The script must compile clean.
-
Manual trigger: Right-click the scheduled task and choose Start once. Verify the row count in
PROCESS_DATA.DBO.DATAincreases by one. -
Spot-check values: Run
SELECT TOP 5 * FROM DATA ORDER BY D_DATE DESCin SQL Server Management Studio. Confirm the timestamp advances, and the numeric columns are within expected ranges. -
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
0for a quality-bad tag unless configured otherwise). -
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_CNTtag.
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
SQLobject andHMIRuntimeJavaScript namespace. - The connection string uses the
MS SQL OLE DBprovider; SQLite is also supported. - Tags are read with
Tags("Tag1").Read()(synchronous) and the connection is opened withsql.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.1is deprecated by Microsoft but still ships with Windows; for new deployments targetSQLNCLIorMSOLEDBSQLto 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_DATEcolumn will drift. Use the PLC time instead, or useSYSDATETIME()as a SQL-side default and let the server clock win. -
Null handling.
Round(NULL, 2)raises an error in VBS. AlwaysIsNumericthe value before formatting, and substitute an empty string orNULLliteral. -
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 parameterisedCommandwithParameters.Appendfor 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.