简介:这份PDF文档面向具备一定Intouch基础的工业自动化工程师与技术人员,系统讲解Intouch通过SQL Access访问Microsoft Access数据库的完整实现方法,解决工控现场数据记录与实时读取的对接问题。资源包共1个PDF文件,大小约919KB,内容以图文步骤形式呈现,便于对照操作。文档从阅读前提与专业术语切入,依次覆盖Microsoft Access配置SQL访问、安装SQL Access Manager与MS Access 2000 ODBC驱动、创建Intouch应用程序、定义标志名、通过SQL访问管理器建立绑定表、脚本编程以及最终测试等环节,并配有目录结构方便按需查阅。目前已有202人学习,适合需要打通Intouch与Access数据交互、实现数据库记录写入与实时显示的中级用户参考,可帮助读者掌握ODBC数据源配置、标记与表列映射及脚本读写等关键知识点。
1. Intouch 访问 SQLAccess 数据库:从 ODBC 配置到数据落地的完整路径
很多做 SCADA 的工程师第一次遇到「Intouch 访问 SQLAccess 数据库」这个需求时,场景往往很具体:现场一台运行 Intouch 的上位机,需要把实时采集的液位、温度、流量等点位数据写进一个关系型数据库,供 MES 或报表系统查询。Intouch 本身是 Wonderware(现 AVEVA)的组态软件,它并不直接「认识」SQL Server 或 Access,中间必须靠一层桥梁——SQLAccess 就是 Wonderware 体系里负责把 Intouch 的标签数据映射到数据库表的组件,底层走的是 ODBC 连接字符串。换句话说,Intouch 负责采,SQLAccess 负责转,ODBC 负责连,数据库负责存。这套链路适合产线数据归档、批次追溯、能耗统计这类需求,也适合想把组态数据和业务系统打通但预算有限的团队。下面按「先搞懂角色分工,再动手配通,最后处理踩坑」的顺序讲清楚。
2. Intouch、SQLAccess 与 ODBC 三者的角色分工
2.1 为什么不能让 Intouch 直接写数据库
Intouch 的核心是标签引擎(Tag Engine),它管理的是内存里的实时值,刷新周期通常在 100ms 到 1s 之间。如果让标签引擎直接对数据库发起 INSERT,会带来两个问题:一是数据库写入的 IO 延迟会拖慢标签扫描周期,二是组态逻辑和业务逻辑耦合在一起,后期改表结构要动画面脚本。SQLAccess 的设计思路是把「采集」和「持久化」解耦——Intouch 只管把标签值推给 SQLAccess,SQLAccess 按自己的节奏批量写库。常见做法是配置一个绑定表(Binding Table),把 Intouch 的标签名和数据库表的列名做映射,SQLAccess 按行或按触发条件写入。
这里要区分两个容易混淆的概念:SQLAccess 是 Wonderware 的数据库访问工具,而 SQL Server 是微软的数据库产品,两者名字里都有 SQL 但完全不是一回事。热搜词里出现的「SQLAccess」和「SQL Server」经常被新手混为一谈,实际配置时连错对象是高频翻车点。
2.2 ODBC 连接字符串到底怎么拼
ODBC 是 Intouch 和数据库之间的通用接口,Windows 上分 32 位和 64 位两套驱动管理器。Intouch 多数版本是 32 位进程,所以必须用 32 位的 ODBC 管理器(路径是C:\Windows\SysWOW64\odbcad32.exe),而不是默认从控制面板点进去的那个 64 位版本。这一点如果搞错,表现是「驱动装了但 Intouch 里看不到数据源」。
连接字符串的典型格式如下,以 SQL Server 为例:
# 32 位 ODBC 管理器里配置系统 DSN 时,连接字符串等价写法 Driver={SQL Server};Server=192.168.1.100;Database=SCADA_DATA;Uid=sa;Pwd=YourPassword;参数说明:Driver必须和实际安装的驱动名完全一致,SQL Server 2008 R2 用{SQL Server},2012 以后可以用{ODBC Driver 17 for SQL Server};Server可以写 IP 也可以写IP,端口;Database是目标库名;Uid/Pwd是数据库账号。如果用的是 Access 数据库,驱动名换成{Microsoft Access Driver (*.mdb, *.accdb)},Server换成Dbq=文件绝对路径。
提示:连接字符串里的分号、花括号都是语法的一部分,少一个分号就会报「无效的连接字符串属性」,这类错误在日志里往往只显示一个通用错误码,排查时先肉眼核对字符串。
2.3 SQLAccess 的绑定表怎么建
SQLAccess 的核心配置是一张绑定表,它决定了哪个 Intouch 标签写到数据库的哪一列。常见做法是在 SQLAccess 的管理界面里新建一个 Table Binding,指定目标表名、写入模式(Insert / Update / Insert or Update),然后逐行添加标签到列的映射。写入模式的选择很关键:如果目标表有自增主键且只做归档,用 Insert;如果是要维护一张「当前值」表,用 Update 或 Insert or Update。
绑定表建好后,SQLAccess 会生成一个内部的任务,按配置的触发方式执行。触发方式一般有三种:定时触发(比如每 5 秒写一次)、事件触发(标签值变化时写)、手动触发(由脚本调用)。产线数据归档通常用定时触发,因为事件触发在标签频繁抖动时会产生大量写入,把数据库打满。
3. 从零配通 Intouch 到数据库的完整步骤
3.1 环境准备与驱动安装
动手之前先把环境理清楚。假设现场是 Windows 7 或 Windows 10 的 Intouch 上位机,数据库在另一台服务器上跑 SQL Server 2012。第一步是确认 Intouch 的位数,打开任务管理器看view.exe或wm.exe是不是带*32标记。确认是 32 位后,去装 32 位的 ODBC 驱动。SQL Server 2012 对应的驱动可以从微软官方获取,安装后在 32 位 ODBC 管理器里能看到。
Access 数据库的情况稍微不同,如果目标是一个.accdb文件,需要装 Access Database Engine,同样注意选 32 位版本。热搜词里提到的「odbc missing」多半就是驱动位数装错或者根本没装。
3.2 配置系统 DSN 并测试连通
打开C:\Windows\SysWOW64\odbcad32.exe,切到「系统 DSN」页签,点「添加」,选对应驱动。以 SQL Server 为例,向导里依次填名称(比如SCADA_DSN)、服务器 IP、登录方式、默认数据库。填完后点「测试数据源」,显示「测试成功」才算通。
如果测试失败,按这个顺序排查:先ping服务器 IP 确认网络通;再用telnet IP 1433确认端口通(SQL Server 默认 1433,如果改了端口要写IP,端口);然后确认数据库账号密码正确且允许远程连接;最后看 SQL Server 配置管理器里 TCP/IP 协议是否启用。这四步能覆盖九成的连接失败。
3.3 在 SQLAccess 里建立绑定并写入
DSN 通了之后,打开 SQLAccess 配置工具。新建一个 Database Connection,选择刚才建的 DSN,填账号密码。然后新建 Table Binding,指定目标表。假设目标表结构如下:
-- 目标归档表结构,字段名要和绑定表里的列名对应 CREATE TABLE TankData ( ID INT IDENTITY(1,1) PRIMARY KEY, TagName NVARCHAR(50), TagValue FLOAT, CollectTime DATETIME DEFAULT GETDATE() );绑定表里把 Intouch 的标签Tank1_Level映射到TagValue列,TagName列可以填固定值或另一个标签。写入模式选 Insert,触发方式选定时 5 秒。配置完成后启动 SQLAccess 服务,观察日志里有没有写入记录。
# 用 sqlcmd 快速验证数据是否写进去了 sqlcmd -S 192.168.1.100 -U sa -P YourPassword -d SCADA_DATA -Q "SELECT TOP 10 * FROM TankData ORDER BY ID DESC"这条命令返回最近 10 条记录,如果能看到不断新增的行,说明整条链路通了。参数说明:-S是服务器地址,-U/-P是账号密码,-d是数据库名,-Q后面跟查询语句。如果返回空结果,先确认 SQLAccess 服务是否在运行,再看绑定表是否启用。
3.4 用脚本触发写入的替代方案
有些场景不适合用 SQLAccess 的定时绑定,比如只在批次结束时写一条汇总记录。这时候可以用 Intouch 的脚本功能,通过SQLConnect、SQLInsert这类函数直接操作数据库。常见做法是在批次结束的按钮脚本里写:
' Intouch 脚本示例:批次结束时插入一条汇总记录 Dim connID As Integer; Dim sqlStr As String; connID = SQLConnect("SCADA_DSN", "sa", "YourPassword"); If connID > 0 Then sqlStr = "INSERT INTO BatchSummary (BatchNo, TotalQty, EndTime) VALUES ('" + BatchNo + "', " + TotalQty + ", GETDATE())"; SQLInsert(connID, sqlStr); SQLDisconnect(connID); End If;逻辑说明:先建立连接拿到连接句柄,拼好 INSERT 语句后执行,最后断开连接释放资源。参数说明:SQLConnect的第一个参数是 DSN 名称,必须和 ODBC 里配的一致;BatchNo是字符串类型所以要加单引号,TotalQty是数值类型不加引号。这段脚本的坑在于字符串拼接,如果BatchNo里本身带单引号会导致 SQL 语法错误,生产环境建议做转义处理。
4. 避坑与常见问题排查
4.1 现象:Intouch 里数据正常但数据库一直没记录
原因:SQLAccess 服务没启动,或者绑定表处于禁用状态。另一个常见原因是 DSN 配在了用户 DSN 而不是系统 DSN,SQLAccess 以服务方式运行时读不到用户级配置。
解决:在 Windows 服务列表里确认 SQLAccess 相关服务是「正在运行」;检查绑定表的 Enabled 属性;把 DSN 从用户级改到系统级。改完后重启服务再观察。
4.2 现象:写入几条后报「连接超时」或「连接被重置」
原因:数据库连接池耗尽,或者 SQLAccess 的写入频率太高导致数据库来不及处理。定时 1 秒写一次、每次写几十个标签的场景很容易触发。
解决:把定时触发周期从 1 秒放宽到 5 秒或 10 秒;在 SQLAccess 里开启批量写入(Batch Insert),把多次单行写入合并成一次多行写入;检查数据库服务器的 CPU 和磁盘 IO,必要时把归档表放到独立的文件组。
4.3 现象:Access 数据库文件写入后体积暴涨
原因:Access 的.accdb文件在频繁 INSERT 后不会自动回收空间,删除记录后文件大小也不变。这是 Access 的固有特性,不是配置问题。
解决:如果数据量会持续增长,建议换成 SQL Server Express 或更正式的数据库产品。如果必须用 Access,定期用「压缩和修复数据库」功能回收空间,或者按时间分文件归档,比如每月一个.accdb。
4.4 现象:中文标签名写入后变成乱码
原因:ODBC 驱动和数据库的字符集不一致,或者连接字符串里没指定字符集。SQL Server 的NVARCHAR和VARCHAR对中文的处理不同。
解决:目标列用NVARCHAR类型;连接字符串里加Charset=UTF-8或Charset=GBK试;Intouch 脚本里拼接 SQL 时确认字符串编码。乱码问题在跨语言环境里很常见,配之前先确认数据库排序规则(Collation)是否支持中文。
4.5 现象:SQLAccess 配置界面能连上,但 Intouch 运行时报「数据源未找到」
原因:Intouch 运行在 32 位环境,而 DSN 配在了 64 位 ODBC 管理器里。这是最高频的翻车点,因为从控制面板点进去默认打开的是 64 位版本。
解决:手动运行C:\Windows\SysWOW64\odbcad32.exe,在里面重新配一遍系统 DSN。配完后可以在 Intouch 的脚本里用SQLConnect测试,返回句柄大于 0 就说明通了。
5. 进阶:用存储过程替代直接 INSERT 提升可靠性
5.1 为什么建议走存储过程
直接拼 INSERT 语句在简单场景够用,但生产环境有几个隐患:表结构一变就要改所有脚本;没有参数校验,脏数据直接进库;高并发时容易产生锁等待。把写入逻辑封装成存储过程,Intouch 侧只负责传参,数据库侧负责校验和落库,职责更清晰。热搜词里提到的「慢 SQL 优化」「数据库并发锁」在这个场景下就是实际问题——归档表如果没有合适的索引,查询和写入会互相拖慢。
5.2 存储过程写法与 Intouch 调用
-- 创建归档写入的存储过程,带基本参数校验 CREATE PROCEDURE sp_InsertTankData @TagName NVARCHAR(50), @TagValue FLOAT AS BEGIN -- 过滤明显异常的数值,避免脏数据入库 IF @TagValue IS NULL OR @TagValue < -9999 OR @TagValue > 99999 RETURN; INSERT INTO TankData (TagName, TagValue, CollectTime) VALUES (@TagName, @TagValue, GETDATE()); END;Intouch 侧调用时,把原来的 INSERT 语句换成EXEC sp_InsertTankData 'Tank1_Level', 12.5。参数说明:存储过程名前的sp_是命名习惯,不是强制要求;@TagName和@TagValue是入参,调用时按顺序传。这样改完之后,如果以后要给归档表加字段,只需要改存储过程,Intouch 脚本不用动。
5.3 验证方法与日常巡检习惯
配通之后不能就不管了。我一般会在数据库侧建一个简单的巡检查询,每天定时跑一次,统计过去 24 小时的写入条数,如果明显低于预期就说明链路有问题。
-- 巡检查询:统计最近 24 小时各标签的写入条数 SELECT TagName, COUNT(*) AS Cnt FROM TankData WHERE CollectTime > DATEADD(HOUR, -24, GETDATE()) GROUP BY TagName ORDER BY Cnt DESC;这条查询能快速看出哪个标签没在写、哪个标签写得异常频繁。参数说明:DATEADD(HOUR, -24, GETDATE())是取当前时间往前推 24 小时,改-24可以调整统计窗口。如果某个标签的 Cnt 是 0,回去查 Intouch 里那个标签是否还在采集、绑定表是否被误删。
5.4 一个我踩过的坑
早期做项目时,我把归档表和实时表放在了同一个数据库文件里,结果归档表数据量涨到几百万行后,实时查询明显变慢,操作员画面上刷新都卡。后来把归档表拆到独立的文件组,并且按月份做分区,问题才解决。这件事让我养成了一个习惯:只要涉及 Intouch 写库,先问清楚数据保留多久、查询频率多高,再决定表结构和索引策略。别等数据涨起来才后悔,迁移几百万行数据可比一开始就分好区麻烦得多。
希望帮到你。
本文还有配套的精品资源,点击获取