博图WINCC历史数据记录到SQL数据库 将博图WinCC中的变量作为历史数据记录到SQL Server数据库中,并将历史数据记录作为曲线图的方式展示出来,软件采用博图V15.1 Adanced编写,数据库为SQL Server2014 变量循环记录20000条,间隔2S记录一次数据到数据库中,有需要的朋友可以联系我! 资源包扣,数据库的安装方法和下载地址以及数据库的配置过程,开发文档里显示的很详细

先来个效果预览:现场压力、温度这些关键参数每2秒存一次,自动循环保留最新的两万条记录。数据存进SQL Server之后,用个ASP.NET页面就能拉出趋势曲线,设备状态一目了然。

第一步 配数据库(具体安装包和配置文档资源里都有)

重点说连接字符串,WinCC这边得用对驱动:

-- 建库语句示例
CREATE DATABASE WinCC_HistDB
ON PRIMARY 
(NAME = WinCC_HistDB_Data, 
FILENAME = 'D:\SQLData\WinCC_HistDB.mdf')
LOG ON 
(NAME = WinCC_HistDB_Log,
FILENAME = 'D:\SQLData\WinCC_HistDB.ldf');

-- 建表脚本
CREATE TABLE TagLog (
    ID INT IDENTITY PRIMARY KEY,
    TagName NVARCHAR(50),
    Value REAL,
    TimeStamp DATETIME DEFAULT GETDATE()
);

这里建议给TimeStamp字段加个聚集索引,后面查数据能快不少。

第二步 WinCC全局脚本(V15.1 Advanced版)

在全局脚本里挂个2秒的定时器,核心是这段C脚本:

#include "apdefap.h"
void OnTimer(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)
{
    // 连接数据库
    SQLHENV hEnv;
    SQLHDBC hDbc;
    SQLRETURN ret;
    
    // 初始化ODBC环境
    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
    SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
    SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);
    
    // 替换成自己的连接字符串
    ret = SQLDriverConnect(hDbc, NULL, "DSN=WinCC_HistDB;UID=sa;PWD=123456;", SQL_NTS,
                          NULL, 0, NULL, SQL_DRIVER_COMPLETE);

    if(SQL_SUCCEEDED(ret)) {
        // 获取当前值
        float pressure = GetTagFloat("Pressure"); 
        float temperature = GetTagFloat("Temperature");
        
        // 防SQL注入写法
        SQLHSTMT hStmt;
        SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt);
        SQLPrepare(hStmt, "INSERT INTO TagLog (TagName,Value) VALUES (?,?), (?,?)", SQL_NTS);
        
        SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 50, 0, "Pressure", 0);
        SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 0, 0, &pressure, 0);
        // 同理绑定温度参数...
        
        SQLExecute(hStmt);
        SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
    }
    
    // 释放连接
    SQLDisconnect(hDbc);
    SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
    SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}

注意!这里用了批处理插入提升性能,实际部署时建议加上错误处理。遇到过现场因为网络闪断导致ODBC连接卡死的情况,后来在脚本里加了超时重连机制才解决。

数据循环策略

在SQL Server里搞个定时作业,每小时跑一次清理旧数据:

DELETE FROM TagLog 
WHERE ID < (
    SELECT MAX(ID) - 20000 
    FROM TagLog
)

比用时间戳判断更靠谱,避免设备停机期间误删数据。

曲线展示部分

用Python的matplotlib拉数据画图也挺方便:

import pyodbc
import matplotlib.dates as mdates

conn = pyodbc.connect('DRIVER={SQL Server};SERVER=.;DATABASE=WinCC_HistDB;UID=sa;PWD=123456')
cursor = conn.cursor()

cursor.execute("""
SELECT TimeStamp, Value 
FROM TagLog 
WHERE TagName='Pressure' 
AND TimeStamp > DATEADD(hour, -1, GETDATE())
""")

times = []
values = []
for row in cursor:
    times.append(row.TimeStamp)
    values.append(row.Value)

# 画图配置
plt.plot_date(mdates.date2num(times), values, fmt='-')
plt.gcf().autofmt_xdate()
plt.title('Pressure Trend - Last Hour')
plt.grid(True)
plt.show()

如果要做实时刷新,可以考虑用WebSocket推送到前端,比轮询方式省资源。

实际项目中发现几个典型问题:

  1. WinCC脚本执行间隔不稳定时,最好在SQL里补时间戳
  2. 大批量插入时启用SQL Server的批处理优化参数
  3. 归档周期建议和控制系统扫描周期对齐
  4. 数据库字段类型要和WinCC变量类型严格匹配

有朋友测试时发现存储速度跟不上,后来把插入语句改成存储过程,性能直接翻倍。具体优化方案得看现场数据量,一般两万条的规模用上述方案完全够用。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐