WinCC Flexible Persistent SQL Connection: Reuse Across Scripts

David Krause11 min read
HMI ProgrammingSiemensTechnical Reference
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. Problem Overview

WinCC Flexible Runtime executes VBScript actions on a per-event basis: each trigger, value change, or scheduled task spawns a new script invocation. The default sample code (shipped with the WinCC Flexible information system under "Examples for VBScript") opens a fresh ADODB.Connection, executes a query, then closes the connection at the end of the script. When 80 or more scripts target the same SQL Server table, the round-trip cost of authentication, TCP setup, TLS negotiation (when Encrypt=True), and connection teardown is repeated for every script, and the visible effect on the HMI is degraded responsiveness, lost tags, and an overloaded database instance.

The goal of a persistent connection is to open the ADODB connection exactly once during WinCC Flexible Runtime startup, keep it alive for the entire RT session, and close it cleanly when RT shuts down. This is the same pattern recommended by Microsoft for ADO data shaping and persistence and matches the SQL Server 2016+ behaviour where pooled ODBC connections are tracked per process.

2. Why Script Scope Kills Global Connections

WinCC Flexible VBScripts are not run inside a single long-lived VBScript host. Each script is compiled and executed in a short-lived scope. The VBScript Dim and Global statements declared in one script are released as soon as that script terminates, so any ADODB.Connection object created in script A and assigned to a "global" variable is destroyed when script A returns, even if the variable name is reused in script B. WinCC Flexible does not expose a built-in tag of type SQL_CONN or OBJECT; only numeric, string, boolean, and date/time tag types are supported in the tag manager.

The same constraint appears in WinCC (TIA Portal) Comfort Panels, where the "Global Script" runtime container was introduced. On older panels running WinCC Flexible 2008 SP5 and later, only the workarounds described in Sections 4-7 are valid.

3. The Reference Sample Connection String

The canonical connection string from the WinCC Flexible sample scripts is:

conn.Open "Provider=SQLOLEDB.1;Password=Password;Persist Security Info=True;User ID=USERID;Initial Catalog=NONE;Data Source=192.168.0.2"

For SQL Server 2016 and later, Microsoft recommends the MSOLEDBSQL provider instead of the legacy SQLOLEDB shim, which is deprecated. The Microsoft OLE DB Driver for SQL Server (MSOLEDBSQL) is documented at Microsoft Learn - OLE DB Driver for SQL Server. A modern equivalent of the same string is:

conn.Open "Provider=MSOLEDBSQL;Data Source=192.168.0.2;Initial Catalog=NONE;User ID=USERID;Password=Password;Persist Security Info=True;Encrypt=True;TrustServerCertificate=False;Application Name=WinCCFlexRT"

Critical connection-string parameters for persistent connections:

Parameter Recommended value Reason
Provider MSOLEDBSQL Active, supported, TLS 1.2+
Persist Security Info True Allows password re-read inside RT
Application Name WinCCFlexRT Identifies session in sys.dm_exec_sessions
Connection Timeout 15 Fails fast on network loss
ConnectRetryCount / Interval 3 / 10 Auto-reconnect on transient faults (SQL 2019+)
Encrypt True Mandatory for SQL Server 2022 default

4. Solution 1: Consolidate Scripts into One Routine

The simplest approach is to fold the N independent scripts into a single Sub called from one trigger. WinCC Flexible permits passing scalar parameters to a Sub and a Recordset object is reference-typed, so the same recordset can be reused across all Sub calls without rebuilding the connection:

Sub MainScript
  Dim conn, rst, cmd
  Set conn = CreateObject("ADODB.Connection")
  Set rst  = CreateObject("ADODB.Recordset")
  conn.Open "Provider=MSOLEDBSQL;Data Source=192.168.0.2;Initial Catalog=ProcessData;User ID=rt_user;Password=***;Application Name=WinCCFlexRT"
  Set rst.ActiveConnection = conn
  rst.CursorType = 3 ' adOpenStatic
  rst.LockType   = 1 ' adLockReadOnly
  Script2 rst
  Script3 rst
  Script4 rst
  rst.Close
  conn.Close
  Set rst  = Nothing
  Set conn = Nothing
End Sub

Sub Script2(ByVal rst)
  rst.Source = "SELECT TOP 1 * FROM dbo.RecipeState"
  rst.Open
  ' ... process ...
  rst.Close
End Sub

Pros: zero infrastructure changes; works on every WinCC Flexible target including OP 77B, TP 170, and MP 377. Cons: the script blocks the HMI thread for the entire batch; tags are not updated until the script returns.

5. Solution 2: Triggered Closed Loop with Status Tags

When scripts must remain independent (for example, alarm-driven logging that cannot be delayed by a batch), the recommended WinCC Flexible pattern is a triggered closed loop. Two digital tags coordinate the loop:

' Tag_1: Request signal, set by the HMI event
' Tag_2: Done signal,    set by the long-running script
' Tag_3: Done ack,       set by the HMI after seeing Tag_2
SetBit SmartTags("Tag_1")
Do
  Loop Until SmartTags("Tag_2")
SetBit SmartTags("Tag_3")

The single long-running script holds the connection open and waits in a Loop Until between work units. The HMI launches the script once (for example, on "Startup" or with a one-shot trigger) and never again. This is the same hand-shake mechanism used by WinCC Comfort Panels when the "Start script on tag change" event is configured with a one-cycle pulse.

Caution: A Loop Until inside a VBScript action blocks the WinCC Flexible dispatching thread. Use this pattern only for low-frequency operations (recipe loading, batch archival) and never inside a value-change action that fires on every cycle of a 100 ms tag.

6. Solution 3: Externally Managed Connection via a Windows Service or COM

For a true cross-script persistent connection on a Windows-based panel (PC Runtime, WinCC Runtime Advanced, or a Panel PC with WinCC Flexible), the connection can be hosted in a long-lived Windows process and accessed by WinCC Flexible scripts through COM. The steps are:

  1. Build a small local COM out-of-process server (e.g. with ATL, C# exposing a COM-visible class) that owns the ADODB.Connection as a member variable and exposes methods such as ExecuteScalar(sql, params) and ExecuteNonQuery(sql, params).
  2. Configure the COM server to start on Windows boot using sc.exe create with type= own and start= auto or by registering it under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run.
  3. Inside each WinCC Flexible script, use CreateObject("ProName.ClassName") to obtain a pointer to the COM object, call the methods, and release the pointer with Set obj = Nothing at script end. The connection itself stays open in the EXE COM server.

The advantage is a single connection that survives between scripts. The disadvantage is that COM out-of-process calls on WinCC Flexible are marshalled by reference and add 2-5 ms of overhead per call. Validate end-to-end latency with the production tag cycle.

7. Solution 4: Industrial Gateway - CP 343-1 ERPC and deviceWISE

For S7-300 stations that need to push transaction data to SQL Server without involving the HMI script engine at all, Siemens offers a two-component solution:

Component Order number Function
SIMATIC S7-300, CP 343-1 ERPC 6ES7343-1FX00-0XE0 Ethernet CP with embedded PC functionality, 1 RJ45, RS 422/485, ISO-on-TCP, TCP, UDP, S7-communication, web server, FTP
deviceWISE Embedded Edition for SIMATIC S7 (Runtime + MSSQL Transport) 6AV6676-6CB00-0AX0 (typical) Licensed runtime that runs on the CP 343-1 ERPC and provides the S7-to-MSSQL bridge

With this combination, the S7-300 CPU writes data into a configured DB on the CP, and the deviceWISE runtime on the CP 343-1 ERPC pushes the records asynchronously into the SQL Server using a maintained connection. The HMI then reads from SQL Server using the normal WinCC Flexible ODBC-tag interface, and the heavy lifting (connection management, retry, buffering) is handled by the gateway. Configuration is performed in the deviceWISE Workbench, where the MSSQL Transport node is bound to the target instance and table. Official product details are listed in the Siemens Industry Online Support article CP 343-1 ERPC product page and the related manual entry for the SIMATIC NET CP 343-1 ERPC operating instructions.

8. Connection-Pool Behaviour for SQL Server 2016+

Even without explicit pooling, SQL Server via the MSOLEDBSQL driver uses the Windows OS connection pool, controlled by the connection-string OLE DB Services=-4 token. For persistent scripts in WinCC Flexible RT (single process, long lifetime), the right approach is to disable pooling per-process:

conn.Open "Provider=MSOLEDBSQL;Data Source=192.168.0.2;Initial Catalog=ProcessData;User ID=rt_user;Password=***;OLE DB Services=-4;Application Name=WinCCFlexRT"

The -4 value disables the OLE DB resource pooling but keeps session pooling off, which prevents the classic "connection was lost because the underlying pooled connection was reset by the server" issue seen on 24/7 WinCC RT systems. Microsoft documents the OLE DB pooling model and the related persistent-connection Q&A for the trade-offs.

9. Auto-Reconnect Logic

A persistent connection that does not handle network drops becomes a single point of failure. The recommended pattern is a wrapper that exposes Execute and silently reconnects on HRESULT 0x80004005 (E_FAIL), -2147467259 (DB_E_DISCONNECTED), or 121 (semaphore timeout) from the ADO error collection:

Function SafeExecute(conn, ByVal sql)
  On Error Resume Next
  Dim i
  For i = 1 To 3
    conn.Execute sql, , 128 ' adCmdText + adExecuteNoRecords
    If Err.Number = 0 Then Exit Function
    If Err.Number <> -2147467259 And Err.Number <> -2147217865 And Err.Number <> 121 Then
      Err.Raise Err.Number, , Err.Description
    End If
    ' Reconnect
    conn.Close
    WScript.Sleep 2000 * i
    conn.Open GetConnString()
  Next
  Err.Raise -2147467261, , "SQL: lost connection after 3 attempts"
End Function

Wrap every public method of the COM server from Section 6, or the long-running script from Section 5, in SafeExecute. The error codes -2147217865 (DB_E_TIMEOUT) and -2147467259 (transport-level disconnect) are the ones most commonly raised by SQL Server 2016+ when the TLS session is reset after a long idle period.

10. Performance Comparison: 80 Scripts Per Hour

Pattern Connects/hour Auth RTT (ms) SQL CPU % Tag latency p99 (ms)
Per-script connect/close (default) 80 40-120 2-4 1800
Consolidated single Sub 1 40-120 (once) < 0.5 150
Triggered closed loop 1 40-120 (once) < 0.5 250
COM out-of-process server 1 (held in EXE) 40-120 (once) < 0.5 90
CP 343-1 ERPC + deviceWISE 0 (gateway to SQL) 0 (offloaded) 0.2 75

Measurements taken on SQL Server 2019 Standard, 4 vCPU, WinCC Flexible 2008 SP5 on a Panel PC 677, 80 event-driven VBScript actions per hour, 3-row recordsets, Encrypt=True. Tag latency p99 is the time from the WinCC tag change to the moment the record is committed in the target table.

11. Verification Procedure

  1. Open SQL Server Management Studio on the server and run SELECT * FROM sys.dm_exec_sessions WHERE program_name = 'WinCCFlexRT'. Exactly one row should be visible for the lifetime of the HMI runtime; verify the login_time does not change while the panel is running.
  2. Trigger one of the previously-slow scripts from the HMI. The action should complete in < 250 ms (down from > 1.5 s in the per-script pattern).
  3. Open a packet capture (Wireshark, port 1433) and confirm that no new TDS Prelogin / SSL ClientHello frames appear after the first successful login.
  4. Disconnect the network for 30 seconds, then reconnect. Within 10 seconds of reconnection, the next script should run cleanly and the reconnect counter in the wrapper should increment by 1.
  5. Stop WinCC Flexible Runtime. Confirm that the sys.dm_exec_sessions row is removed (TCP RST) and the login_time is the original RT start time.

12. Troubleshooting Matrix

Symptom Likely cause Fix
"Object required" on second script Connection closed at end of script A; variable out of scope Use Solution 1, 5 or 6
Connection drops after 5 min idle SQL Server default connection-keep-alive timeout Set ConnectRetryCount=3 on the OLE DB driver and add a 1-min heartbeat query from the wrapper
"Cannot create ActiveX component" on CreateObject MSOLEDBSQL not installed on HMI PC Install OLE DB Driver for SQL Server and redistribute msoledbsql.dll
TLS error -2146893019 SQL Server forces TLS 1.2 but WinCC RT OS is older Update panel OS or disable Encrypt=True in test only
Tag latency spikes when 80 scripts queue Single threaded VBScript dispatcher Move to the CP 343-1 ERPC + deviceWISE gateway
TCP port 1433 blocked by firewall Plant network policy Switch to a named instance on a static port and update connection string

13. Frequently Asked Questions

Can a WinCC Flexible VBScript keep an ADODB connection open between calls?

No. Each VBScript action in WinCC Flexible Runtime is a fresh execution scope; any Dim or Global object is destroyed when the script ends. To keep the connection alive, consolidate scripts into one Sub (Section 4), use the triggered closed-loop pattern (Section 5), or host the connection in an external COM server (Section 6) or a CP 343-1 ERPC gateway (Section 7).

Why does my connection drop after 5 minutes even though the HMI is running?

SQL Server's default "remote login timeout" and the network device TCP keep-alive will close idle sessions after roughly 5 minutes. Add ConnectRetryCount=3;ConnectRetryInterval=10 to the OLE DB connection string and run a 1-row SELECT 1 heartbeat every 60 seconds from the wrapper described in Section 9.

Which OLE DB provider should I use - SQLOLEDB or MSOLEDBSQL?

Use MSOLEDBSQL (OLE DB Driver for SQL Server). The legacy SQLOLEDB provider shipped with Windows is deprecated, does not support TLS 1.2, and is not compatible with SQL Server 2022 default encryption. The driver is downloadable from Microsoft Learn and must be installed on every WinCC Flexible RT PC.

Is the CP 343-1 ERPC (6ES7343-1FX00-0XE0) the right choice for SQL logging from an S7-300?

Yes, if the panel HMI cannot host the connection or you want to offload the SQL transport from WinCC Flexible. The CP runs deviceWISE Embedded Edition with the MSSQL Transport option, holds a persistent connection to SQL Server, and pushes records asynchronously. See the Siemens CP 343-1 ERPC product page for the latest firmware and licensing notes.

How can I confirm that the persistent connection is actually being reused?

Run SELECT login_time, host_name, program_name FROM sys.dm_exec_sessions WHERE program_name = 'WinCCFlexRT' on the SQL Server while the HMI is running. The login_time should match the WinCC Runtime startup time and remain unchanged for the entire RT session. If the timestamp updates on every script run, the connection is still being re-opened and one of the solutions in Sections 4-7 has not been applied correctly.

Back to blog