首页 / 资讯中心 / 文章详情

Intouch与SQL Server 2012历史库配置及Excel报表闭环

Intouch与SQL Server 2012历史库配置及Excel报表闭环 ★ FEATURED ARTICLE
简介这份文档面向使用 WonderWare Intouch 2014R2 构建 SCADA 系统的工程人员与初学者聚焦 HMI 与 SQL Server 2012 数据库集成及 Excel 报表落地。内容围绕数据库登录方式与权限配置、Intouch 标记字典与条件脚本编写、SQL 访问管理器变量绑定、SQLConnect/SQLDisconnect 连接管理、SQLInsert 定时写入以及 Excel VBA 报表模板引用与数据提取展开并附数据库文件恢复思路。整包仅 1 个 doc 文件约 2.48MB便于按章节查阅与现场对照。已有 533 人学习下载适合需要打通 Intouch 数据存储、历史数据报表呈现与故障恢复流程的读者作为操作参考。1. 装 Intouch 2014 R2 之前先确认 SQL Server 2012 这套底座能不能立住工控机上装 Intouch 2014 R2配 SQL Server 2012 做历史库再用 Excel 报表把班组的参数日报拉出来这套组合在不少 SCADA 项目里是标准动作。真正上手才发现坑不在 Intouch 的画面绘制而在 SQLConnect 那一行连接串里 Data Source 写错一个字符绑定列表照常配置、脚本照常编译通过数据就是不进库。等 Excel 报表打开一片空白回头排查已经过去两天。这套环境适合手里有一台能装 SQL Server 2012 的工控机、需要把 Intouch 实时数据落库并按班次出报表的人也适合接手别人现场、只看到一堆 .mdf 和 .ldf 文件要恢复的运维。下面按我实际装过的顺序从 SQL Server 2012 实例一直写到 Excel 报表刷新。2. SQL Server 2012 实例配置实例名、混合验证与建库建表这一章要交付的是「一个 Intouch 能连上、Excel 能读、以后能恢复」的数据库底座。装 SQL Server 2012 本身不难难的是装完之后那几个默认值——默认只开 Windows 身份验证、默认不启用 TCP/IP、默认把库建在 C 盘——三个默认值凑在一起正好让 Intouch 的 SQL 访问管理器连不上。我一般把这几项在安装阶段就一次定死省得后面回头改注册表再重启服务。2.1 实例名与排序规则装之前先定死版本先选清楚。SQL Server 2012 Express 单库有 10GB 上限做几天班组的参数日报还够用一旦要存几个月的秒级数据就会顶到天花板那时候再换版本要停机迁移成本比一开始装标准版高得多。工控机上如果不确定数据量我的做法是先按标准版规划实在只有 Express 介质就把写入频率从秒级降到分钟级并且在建库时把文件增长量调大减少碎片。实例类型建议用默认实例 MSSQLSERVER不要图省事装成命名实例。原因是 Intouch 的 SQL 访问管理器走的是 OLEDB连接串里Data Source一段写的是数据库所在计算机名默认实例只写主机名就行命名实例要写成主机名\实例名反斜杠在字符串里、在 Excel VBA 里都容易被转义或截断是后面排查的高发点。如果现场已经有命名实例不能改那就把实例名记死后面每一处连接串都照抄不要一处写主机名、一处写完整实例名。排序规则选 Chinese_PRC_CI_AS这是中文环境的常规选项大小写不敏感、重音敏感后面按日期字符串查询、按计算机名过滤都不会出岔子。装的时候在「数据库引擎配置」页把「身份验证模式」直接选成「混合模式」同时把 SQL Server 管理员密码设好如果安装时漏了,后面在 SSMS 里改也行但必须重启服务才生效。安装项建议值说明版本标准版优先Express 仅限小数据量Express 单库 10GB 上限实例类型默认实例 MSSQLSERVER连接串只写主机名排序规则Chinese_PRC_CI_AS中文环境常规选择身份验证模式SQL Server 和 Windows 身份验证模式装完再改需重启服务TCP/IP 协议启用端口 1433OLEDB 连接的前置条件SQL Server Browser自动启动命名实例必须默认实例也建议开数据文件目录E:\DataBase与后续数据库恢复目录保持一致装完第一件事不是急着建库而是确认网络协议真的开了。这一步在图形界面里点「启用」之后服务不重启是不生效的很多人在这里翻车明明勾了 TCP/IPOLEDB 还是连不上。# 在数据库服务器上执行确认实例服务状态与监听端口 Get-Service -Name MSSQLSERVER | Select-Object Name, Status, StartType # 从错误日志里确认实例实际监听的端口默认实例通常是 1433 Select-String -Path C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Log\ERRORLOG -Pattern Server is listening on第一段命令看的是服务有没有起来、启动类型是不是自动第二段命令直接读错误日志比在配置管理器里翻协议可靠得多日志里出现Server is listening on [ any ipv4 1433]就说明端口正常。如果只看到共享内存和命名管道、没有 TCP 那一行回到 SQL Server 配置管理器把MSSQLSERVER 的协议下的 TCP/IP 启用然后重启SQL Server (MSSQLSERVER)服务再查一次。2.2 开启 SQL Server 和 Windows 身份验证模式并新建登录名装完是「仅 Windows 身份验证」的话Intouch 那条连接串里的User ID/Password根本没有用SQLConnect 会一直返回 0而 Intouch 不会给你任何报错弹窗——这是最费时间的一种失败。改法有图形和脚本两条路图形路径是SSMS 里右键实例 → 属性 → 左侧选「安全性」→ 右侧「服务器身份验证」选「SQL Server 和 Windows 身份验证模式」→ 确定 → 重启服务。我习惯用注册表脚本改因为可以写进部署记录换台机器照着执行一遍就行。-- 以 Windows 身份验证登录 SSMS 后在新查询窗口执行 -- LoginMode1 仅 Windows 身份验证2 SQL Server 和 Windows 身份验证模式 EXEC xp_instance_regwrite NHKEY_LOCAL_MACHINE, NSoftware\Microsoft\MSSQLServer\MSSQLServer, NLoginMode, REG_DWORD, 2; GO执行完必须重启 SQL Server 服务注册表改动才会被引擎读进去。重启后可以用下面这句确认当前模式返回 2 就对了SELECT SERVERPROPERTY(IsIntegratedSecurityOnly) AS [仅Windows验证]; -- 返回 0 表示混合模式已生效返回 1 表示仍然是仅 Windows 验证接下来是新建登录名。图形路径是「对象资源管理器」→「安全性」→ 右键「登录名」→「新建登录名」在「常规」页填登录名、选「SQL Server 身份验证」、输两遍密码、取消「用户在下次登录时必须更改密码」「服务器角色」页按需勾选。这里有个取舍不少人图省事直接给sysadmin或dbcreator现场能跑但一个只负责写数的报表账号拿到建库删库权限属于自己给自己埋雷。我的做法是登录名只给public到具体数据库里再映射用户、给db_datareader和db_datawriter够 Intouch 写、也够 Excel 读。-- 1) 新建 SQL 登录名关闭密码策略以便现场部署生产环境建议保留策略 CREATE LOGIN [scada_rw] WITH PASSWORD NScda#2012rw, CHECK_POLICY OFF, DEFAULT_DATABASE [SCADA_BB]; GO -- 2) 只给目标库的读写角色不给服务器级角色 USE [SCADA_BB]; GO CREATE USER [scada_rw] FOR LOGIN [scada_rw]; GO ALTER ROLE [db_datareader] ADD MEMBER [scada_rw]; ALTER ROLE [db_datawriter] ADD MEMBER [scada_rw]; GOCHECK_POLICY OFF是为了让现场部署时密码不受复杂度策略限制代价是安全性下降正式投运前建议改回ON并换成复杂密码。DEFAULT_DATABASE指向目标库这样登录进去默认就在SCADA_BB里Intouch 连接串里的Initial Catalog即使写漏也有兜底。如果现场已经有合适的用户名就不用新建直接在「登录名」属性里改密码和服务器角色即可改完记得在 Intouch 的连接串里同步。2.3 建库建表和列类型和 Intouch 绑定列表对齐建库这一步要把文件路径一次定到 E 盘别用默认的 C 盘路径。原因很实际后面数据库恢复、附加 .mdf 的操作默认都往E:\DataBase找路径不一致时要多走一遍「定位数据库文件」现场一着急就容易选错文件。建库脚本里把初始大小和增长量写死能避免频繁自动增长带来的日志碎片。-- 建库数据文件和日志文件都放 E:\DataBase目录需提前创建 CREATE DATABASE [SCADA_BB] ON PRIMARY ( NAME NSCADA_BB, FILENAME NE:\DataBase\SCADA_BB.mdf, SIZE 512MB, FILEGROWTH 256MB ) LOG ON ( NAME NSCADA_BB_log, FILENAME NE:\DataBase\SCADA_BB_log.ldf, SIZE 256MB, FILEGROWTH 128MB ); GOSIZE是初始大小FILEGROWTH是每次不够时扩多少。写死增长量比按百分比增长可控尤其是日志文件按百分比涨起来会很快吃掉磁盘。建库之前先确认E:\DataBase目录存在SQL Server 服务账户对它有写权限否则建库语句直接报操作系统错误 5拒绝访问。表结构要和 Intouch 的绑定列表一一对齐这是整条链路里最容易出错的地方。原文里的做法是让 Intouch 变量名与数据库列名对应、变量数据类型与列的数据类型对应我把它整理成一张对照表建表时照着填Intouch 标记类型SQL Server 列类型典型用途内存消息Messagenvarchar(32) / nvarchar(64)日期时间字符串、计算机名内存实型Realfloat温度、压力、流量等工艺参数内存整形Integerint计数、状态码、连接号内存离散Discretebit开关量、报警状态建表语句按这个对照关系落地主键用自增列日期列单独建索引报表按时间段查询时不会全表扫。USE [SCADA_BB]; GO CREATE TABLE [dbo].[TDays]( [RecID] [int] IDENTITY(1,1) NOT NULL, -- 自增主键报表排序用 [DateTimeS] [nvarchar](32) NULL, -- 对应内存消息 GetDateTimeS [NodeName] [nvarchar](64) NULL, -- 对应内存消息 NodeName [Tag001] [float] NULL, -- 对应内存实型工艺参数 [RunFlag] [bit] NULL, -- 对应内存离散状态位 CONSTRAINT [PK_TDays] PRIMARY KEY CLUSTERED ([RecID] ASC) ); GO CREATE INDEX [IX_TDays_DateTimeS] ON [dbo].[TDays]([DateTimeS]); GOIDENTITY(1,1)让每条记录自动编号避免 Intouch 侧还要维护一个序号变量IX_TDays_DateTimeS是给 Excel 报表的按时间段查询准备的。表名TDays要和后面 Intouch 绑定列表名保持一致因为SQLInsert的第一个字符串参数是表名、第二个是绑定列表名两者写成一样最省心也少一处改错的机会。3. Intouch 2014 R2 侧配置标记名、绑定列表与 SQLConnect 脚本时序数据库这头立住之后才轮到 Intouch 2014 R2。这一章要交付三样东西四个支撑标记、一张和数据库列严格对齐的绑定列表、以及能定时把数据推进库里的条件脚本。顺序不能反——先建标记再配绑定最后写脚本因为脚本里的变量名必须已经在标记名字典里存在否则编译不报错、运行时静默失败属于最难查的一类问题。3.1 先把系统日期时间格式改成 yyyy-MM-dd这一步在原文里只是一句「更改日期和时间格式」但它决定了后面报表能不能按时间段查出来。Intouch 从系统取时间拼成字符串写库如果系统短日期格式是yyyy/M/d或者MM-dd-yy写进DateTimeS列的值就是这种格式Excel 报表里按yyyy-mm-dd hh:nn:ss去比较字符串一条都对不上页面上就是空表——现象和数据没写进去一模一样非常容易误判。改法控制面板 → 区域和语言 → 格式选项卡 → 短日期选yyyy-MM-dd长日期选yyyy-MM-dd时间选HH:mm:ss再到「管理」→「更改系统区域设置」确认不是英文或其他区域。改完重启 Intouch 运行态让它重新读系统格式。工控机如果做过Ghost 还原或者被人改过区域设置这一项特别容易回到默认值我一般在部署记录里单独列一条每次重装都检查一遍。3.2 标记名字典里必建的四个标记在 Intouch 的「标记名字典」里新建四个标记它们不参与画面显示纯粹是给数据库链路做支撑。标记名数据类型用途Connid1内存整形保存 SQLConnect 返回的连接号0 表示未连上GetDateTimeS内存消息保存写入数据库的时间字符串NodeName内存消息保存本机计算机名用于区分哪台操作站写的数据WSQLS内存离散写入防重标志真表示本轮已写过假表示未写Connid1是整条链路的状态指示器值非 0 才说明 SQL 连接建立成功排查时在画面上放一个文本对象直接显示它比翻日志快得多。NodeName用GetNodeName函数填充长度给 32 就够工控机名一般不会太长。WSQLS的初值设成假0后面条件脚本靠它判断本轮是否已经写过数据。这四个标记建完之后建议先做一次「全部重新编译」Intouch 的标记名字典改动不会自动同步到已经打开的脚本编辑器编译一次能提前暴露变量名拼写错误。3.3 SQL 访问管理器绑定列表列名和类型必须一一对上绑定列表在 Intouch 左侧工具视图最下面的「SQL 访问管理器」里选「绑定列表」。新建一个列表名字就叫TDays和数据库表名一致。列表里逐条添加要记录的变量变量名必须和数据库表的列名完全一致包括大小写虽然Chinese_PRC_CI_AS不敏感但保持一致的写法后面排查省事变量类型必须和列类型对应上。对应关系按上一章的对照表来GetDateTimeS是内存消息对应nvarchar(32)NodeName是内存消息对应nvarchar(64)工艺参数是内存实型对应float状态位是内存离散对应bit。这里最常见的翻车是长度不匹配——Intouch 内存消息如果设了 64 字符而数据库列只给nvarchar(32)插入时会被截断或者直接报错SQLInsert返回失败但 Intouch 不会弹窗。我的习惯是数据库列长度一律比 Intouch 标记长度多留一倍余量宁可浪费几个字节。还有一个细节绑定列表里不要放RecID这类自增列它是数据库自己生成的放进去反而会让插入失败。3.4 应用程序脚本里的 SQLConnect 与关闭时 SQLDisconnect连接动作写在「脚本」视图的「应用程序」里的「启动时」脚本中函数原型是SQLConnect(联接数据库号, SQL 联接字符串)。原文里的连接串是五个分号分隔的键值对我把示例值换成占位符现场按实际替换 Intouch 应用程序脚本 - 启动时 参数1Connid1内存整形接收连接号0 表示连接失败 参数2OLEDB 连接串五段用分号分隔每段格式为 键值 SQLConnect(Connid1, providersqloledb;Data SourceSQLHOST01;Initial CatalogSCADA_BB;UserIDscada_rw;PasswordScda#2012rw);五段参数逐个说清楚providersqloledb是固定值表示走 SQL Server 的 OLEDB 提供程序不要写成sqloledb.1之外的变体Data Source是数据库所在计算机名默认实例只写主机名命名实例要写成主机名\实例名Initial Catalog是数据库名要和建库时的一致UserID和Password是 2.2 节新建的 SQL 登录名和密码不要用sasa一旦被改密码所有操作站全断。连接串里最容易写错的是Data Source写成 IP 有时候能通、有时候不通取决于是否启用了 TCP/IP 和是否配了别名写错一个字符则完全不报错。我的做法是连接串统一用计算机名并且在部署记录里把这个名字单独列一行换机器时只改这一处。关闭连接写在「关闭时」脚本里只有一行 Intouch 应用程序脚本 - 关闭时 不写这一行运行态退出后连接不会立刻释放重启后可能撞上连接数上限 SQLDisconnect(Connid1);这一行看着可有可无实际影响很大Intouch 运行态被强制结束、或者操作员反复开关画面时没有SQLDisconnect的连接会挂在数据库侧时间长了Connid1拿不到新连接号表现就是「昨天还好好的今天突然不写数了」。3.5 条件脚本$Second5 触发与 WSQLS 防重写入动作放在「脚本」视图的「条件」里新建一个条件脚本条件写$Second5条件类型选「为真时」。含义是每秒钟判断一次秒数等于 5 时执行一次也就是每分钟执行一次。这个触发方式比用定时器简单缺点是 Intouch 运行态如果正好在那一秒卡顿这一分钟就跳过了对报表类数据可以接受。原文的脚本逻辑是取本机计算机名 → 判断是不是指定操作站 → 判断分钟数是否大于等于 58 → 判断是否已写过 → 执行SQLInsert→ 置位/复位标志。我按这个逻辑给出修正后的写法并把它拆开说明 条件脚本$Second5条件类型为真时 131 为 GetNodeName 的取节点名参数结果放入 NodeName 标记 GetNodeName(NodeName, 131); IF NodeName OP_01 THEN IF $Minute 58 THEN IF WSQLS 0 THEN 时间字符串按系统格式拼装写入前先赋值给 GetDateTimeS GetDateTimeS $DateString $TimeString; 参数1连接号参数2数据库表名参数3绑定列表名 SQLInsert(Connid1, TDays, TDays); WSQLS 1; 置位表示本小时已写过防止重复插入 ENDIF; ELSE WSQLS 0; 离开 58 分窗口后复位为下一小时做准备 ENDIF; ENDIF;和原文相比关键改动在最后那个ELSE WSQLS 0;。原文把置位和复位写在同一个条件块里插完立刻复位防重标志等于没起作用只要那一分钟内秒数再走到 5实际不会但换个触发条件就会就会重复插入一条。复位动作放到「分钟数小于 58」的分支里语义才对进入 58 分之后的窗口写一次出了窗口再清零。IF NodeName OP_01这一行的字符串必须和实际计算机名完全一致。原文注释里写的是OP_01代码里写的是OP_OP1这种不一致在现场非常常见后果是脚本永远不执行、数据库一条记录都没有而脚本本身编译通过、没有任何报错。我的习惯是先用一个临时文本对象把NodeName显示在画面上肉眼确认实际值再回来改脚本里的字符串。如果现场有多台操作站都要写数就把这个判断去掉或者改成IF NodeName THEN靠数据库里的NodeName列区分来源。4. Excel 报表模板控制面板页、参数日报页与 VBA 引用报表这一端要交付的是一个能双击打开、点一下按钮就从 SQL Server 2012 拉数据、按班次出参数日报的 Excel 文件。原文给的结构是两张工作表「控制面板」放查询条件和按钮「参数日报」放数据区和 VBA。这个结构比我见过的一些单表方案好维护因为查询参数和数据区分开了换班次只要改控制面板上的两个单元格不用动代码。4.1 Excel 宏安全与信任中心设置模板拿到手第一件事不是打开看而是先配信任中心否则一开文件宏就被禁用按钮点了没反应很容易误判成模板坏了。路径是文件 → 选项 → 信任中心 → 信任中心设置 → 宏设置选「启用所有宏」并勾选「信任对 VBA 工程对象模型的访问」再到「受信任位置」把模板所在目录加进去。这台机器如果同时装了 Intouch 2014 R2需要注意 Excel 和 Intouch 的位数要匹配——Intouch 的 SQL 访问管理器是 32 位组件如果 Excel 装的是 64 位版本跨组件调用偶尔会出问题。我的做法是报表机器上统一装 32 位 Office和工控软件保持一致省掉一类说不清的兼容问题。4.2 模板结构控制面板页与参数日报页「控制面板」页放三类东西查询起始时间、查询结束时间、一个「刷新报表」按钮。起始和结束时间用两个单元格格式设成yyyy-mm-dd hh:mm:ss并且把单元格格式显式设成文本或者自定义格式避免 Excel 自动把日期转成序列号后又按本地格式显示回去——这一项和 3.1 节的系统时间格式是联动的两边不一致查出来的数据就会偏移或者为空。「参数日报」页第一行是表头列名和数据库TDays表的列一一对应时间、计算机名、工艺参数、状态位。数据区从第二行开始VBA 每次刷新先清空再写入。表头下面不要合并单元格ADO 记录集往单元格里写的时候合并区域会导致写入位置错乱。4.3 VBA 引用至少要勾的三项在「参数日报」标签上右键 →「查看代码」进入 VBA 编辑器菜单「工具」→「引用」这个窗口里至少要勾三项Visual Basic for Applications默认已勾、Microsoft Excel 对象库默认已勾、以及一个数据访问库。第三项是重点原文写的是「至少钩选以下三项」但没展开现场按机器上实际有的版本选优先找Microsoft ActiveX Data Objects 6.1 Library没有就退到2.8或2.5三者选一个即可不要同时勾多个版本否则会出现「用户定义类型未定义」的编译错误。除了 ADO如果模板里用了Scripting.Dictionary或者文件系统对象还要补勾Microsoft Scripting Runtime。判断方法很直接按 F5 编译一次报哪一行「用户定义类型未定义」就是缺哪个引用报的变量类型名基本能对应上库名。4.4 取数脚本与刷新节奏取数用 ADO 连接 SQL Server 2012连接串和 Intouch 那边保持同样的五段结构这样现场只维护一套参数。下面这段放在「参数日报」的代码模块里 参数日报页按控制面板上的时间段从 SQL Server 2012 取数 Sub RefreshDailyReport() Dim conn As Object, rs As Object Dim connStr As String, sqlStr As String Dim t1 As String, t2 As String Dim wsData As Worksheet, wsPanel As Worksheet Dim r As Long Set wsData ThisWorkbook.Worksheets(参数日报) Set wsPanel ThisWorkbook.Worksheets(控制面板) 时间参数统一格式化为 yyyy-mm-dd hh:nn:ss与数据库中的字符串格式对齐 t1 Format(wsPanel.Range(B2).Value, yyyy-mm-dd hh:nn:ss) t2 Format(wsPanel.Range(B3).Value, yyyy-mm-dd hh:nn:ss) connStr ProviderSQLOLEDB;Data SourceSQLHOST01;Initial CatalogSCADA_BB; _ User IDscada_rw;PasswordScda#2012rw; sqlStr SELECT DateTimeS, NodeName, Tag001, RunFlag FROM dbo.TDays _ WHERE DateTimeS BETWEEN t1 AND t2 _ ORDER BY RecID Set conn CreateObject(ADODB.Connection) conn.Open connStr Set rs conn.Execute(sqlStr) 清空旧数据从第 2 行开始写保留表头 wsData.Range(A2:D10000).ClearContents r 2 Do While Not rs.EOF wsData.Cells(r, 1).Value rs.Fields(DateTimeS).Value wsData.Cells(r, 2).Value rs.Fields(NodeName).Value wsData.Cells(r, 3).Value rs.Fields(Tag001).Value wsData.Cells(r, 4).Value rs.Fields(RunFlag).Value rs.MoveNext r r 1 Loop rs.Close conn.Close Set rs Nothing Set conn Nothing End SubFormat(..., yyyy-mm-dd hh:nn:ss)是关键它保证不管控制面板上显示成什么样传到 SQL 里的字符串格式都是固定的和DateTimeS列存的格式对得上。BETWEEN两端都包含如果班次是 08:00 到 20:00结束时间写20:00:00会把整点那条也带上需要精确的话改成 t1 AND t2。ClearContents的范围写 10000 行是经验值按现场数据量调整不要用UsedRange.Clear它会把表头一起清掉。连接用完必须Close否则 Excel 进程退出后连接还挂着下次刷新拿不到新连接。刷新节奏上不建议在 Excel 里做定时器自动刷。报表是给人看的操作员点按钮刷新就够了真要做自动刷新用Application.OnTime设 5 分钟一次但必须在Workbook_BeforeClose里OnTime取消调度否则关掉文件后 Excel 进程会一直驻留。原文里 Intouch 是每 5 秒判断一次、每 5 分钟量级写一次库报表侧跟着这个节奏走5 分钟刷一次完全够。5. 避坑与排查从连接串到数据库附加的五条血泪记录这一章是我这几年在这套环境上实际踩过的、以及帮别人查过的记录按「现象 → 原因 → 解决」整理。每条都出现过不止一次新手照着自己对一遍能省掉大量瞎猜的时间。5.1 现象SQLConnect 返回值一直是 0绑定列表配好了也不写数原因排查下来有四种SQL Server 只开了 Windows 身份验证连接串里的用户名密码无效TCP/IP 协议没启用或者启用了没重启服务Data Source写成了 IP 但服务器没监听该地址登录名没有目标库的db_datawriter角色。四种原因的现象完全一样Intouch 都不报错。解决要按顺序查先在 SSMS 里执行SELECT SERVERPROPERTY(IsIntegratedSecurityOnly)返回 0 才说明混合模式生效再用sqlcmd -S 主机名 -U scada_rw -P 密码 -d SCADA_BB -Q SELECT 1从 Intouch 那台机器上试连能通说明网络和账号没问题不通就回到协议和防火墙最后确认登录名在目标库里有写权限。这三步走完还没通基本就是连接串字符串本身写错了逐字符对比。5.2 现象脚本编译通过、运行态也跑着数据库一张表都没多原因条件脚本里的计算机名判断和实际计算机名不一致。原文示例里注释写OP_01、代码写OP_OP1这种笔误在现场极其常见另一个变体是工控机改过名字脚本没跟着改。解决建一个临时文本对象显示NodeName标记的实时值肉眼抄下来逐字符改进脚本里的字符串或者干脆把判断放宽成IF NodeName THEN用数据库里的NodeName列区分来源。这个坑的隐蔽之处在于脚本没有任何错误提示条件判断为假就静默跳过。5.3 现象SQLInsert 执行了数据库里有记录但字段是空的或者被截断原因绑定列表的变量类型或长度和数据库列不匹配。内存消息标记长度 64、列给nvarchar(32)超长部分被截断内存实型对应到int列小数部分丢失内存离散对应到nvarchar列写入的是字符串0/1而不是布尔值。解决按第 2 章的对照表把每一列重新核一遍数据库列长度一律给 Intouch 标记长度的两倍不确定的就先在测试库上插入一条用SELECT * FROM TDays看实际落库内容。这类问题不会报错只能靠对数据。5.4 现象Intouch 里数据明明在变化Excel 报表查出来是空的原因DateTimeS存进去的格式和报表查询用的格式不一致。系统短日期是yyyy/M/d报表 VBA 里Format成yyyy-mm-dd字符串比较一条都匹配不上另一种情况是控制面板上的时间单元格被 Excel 自动识别成日期序列号Format之后偏移了几个小时。解决两边统一到yyyy-mm-dd hh:nn:ss。系统区域设置里把短日期改成yyyy-MM-dd见 3.1 节报表侧单元格格式设成文本VBA 里统一Format验证方法是直接在 SSMS 里跑同样条件的SELECTSSMS 能查出来而 Excel 查不出来问题一定在格式转换上。5.5 现象附加 .mdf 文件时报错或者附加成功但数据库显示「只读」原因有三种只拷了 .mdf 没拷 .ldfSQL Server 找不到日志文件E:\DataBase目录对 SQL Server 服务账户没有完全控制权限附加时报操作系统错误 5.mdf 来自更高版本的 SQL Server2012 无法附加。解决.mdf和_log.ldf两个文件必须一起拷贝到E:\DataBase路径和原机器保持一致给 SQL Server 服务账户默认NT Service\MSSQLSERVER对该目录「完全控制」版本不匹配只能回到源机器导出脚本和数据不能硬附。附加操作路径是SSMS 里右键「数据库」→「附加」→「添加」→ 定位到E:\DataBase→ 选.mdf→ 确定附加完成后立刻做一次DBCC CHECKDB确认文件完整。6. 验证跑通从 $Second 触发到报表刷新的闭环检查装完之后不要急着交付按下面这个顺序走一遍每一步都有明确的通过标准。我把这套检查固化成了一张清单每次部署完照着勾比凭感觉「看着差不多」可靠得多。第一步数据库侧确认表结构。在 SSMS 里执行SELECT TOP 10 * FROM dbo.TDays ORDER BY RecID DESC能查出列名、类型符合预期即可此时表里应该是空的。第二步确认连接建立。在 Intouch 画面上放一个文本对象显示Connid1切到运行态值非 0 说明SQLConnect成功值是 0 就回到 5.1 节排查。这一步通过之前后面所有验证都没有意义。第三步手动触发写入。把条件脚本的触发条件临时从$Second5改成$Second5 AND $Minute任意当前分钟或者直接把$Minute 58改成$Minute 0让它在当前分钟就执行一次。改完重新编译、切运行态等一个触发周期然后回 SSMS 再查一次TDays应该多出一条记录DateTimeS是yyyy-mm-dd hh:nn:ss格式NodeName是实际计算机名。第四步验证防重。保持上面的放宽条件不动观察两分钟TDays里不应该每分钟都多一条——WSQLS置位后应该挡住重复写入。如果每分钟都在涨说明 3.5 节的复位分支写错了。第五步验证报表。打开 Excel 模板控制面板上把起止时间设成刚才那条记录的时间范围点刷新参数日报页应该出现数据。查不到就按 5.4 节对格式。验证项通过标准失败先查表结构列名、类型与对照表一致建表脚本SQLConnectConnid1 非 0混合验证、TCP/IP、连接串单条写入TDays 新增一条、格式正确计算机名判断、绑定列表类型防重一个窗口内只写一条WSQLS 置位/复位分支报表取数参数日报页有数据时间格式、VBA 引用数据库恢复附加后 DBCC CHECKDB 无错文件权限、mdf/ldf 是否成对第六步恢复演练。把E:\DataBase下的.mdf和_log.ldf拷一份到测试机按 5.5 节的路径附加一次能附加成功并且SELECT COUNT(*)和源库一致才算这套环境的备份链路是通的。这一步很多人省略真出事的时候才发现日志文件没拷。从那以后我每次部署完这套环境都会强制走一遍第三步和第六步——手动插一条、再恢复一次。这两步花不了十分钟但能挡掉后面百分之八十的「数据没进库」和「恢复不起来」。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站