4、数据更新与删除:UPDATE语句、DELETE语句、在Intouch中实现数据维护功能
好,咱们继续往下走。前面几章我们把数据怎么存进去、怎么查出来都聊透了。这一章要聊的,是数据维护里最敏感的两个操作——更新和删除。
说实话,我在项目现场见过太多因为UPDATE和DELETE写错了,导致整个生产数据库乱套的情况。有一次半夜两点,运维小哥一条DELETE忘加WHERE条件,直接把整张历史报警表清空了……嗯,那场面,厂长脸都绿了。所以这一章,我会把我在实战中踩过的坑、总结的经验,全都掰开揉碎讲给你听。
4.1 UPDATE语句:改数据,你得小心点
UPDATE说白了就是“改”。语法很简单,但陷阱全在细节里。
UPDATE 表名
SET 列1 = 新值1, 列2 = 新值2
WHERE 条件;
你看,核心就三部分:告诉数据库改哪张表、改哪些列、改哪些行。
我个人习惯:写UPDATE之前,一定先用SELECT查一遍WHERE条件,确认命中范围对不对。你想想看,要是WHERE写错了,把A车间的温度数据改到B车间去了,那整个批次都得报废。
实战案例:在Intouch中,我们经常需要批量修正某个时间段的错误数据。比如传感器漂移,导致某天8:00-10:00的温度值整体偏高了5度。
-- 先确认要改哪些数据
SELECT TagName, Value, TimeStamp
FROM History
WHERE TimeStamp BETWEEN '2024-01-15 08:00:00' AND '2024-01-15 10:00:00'
AND TagName = 'Tank_Temperature';
-- 确认无误后执行更新
UPDATE History
SET Value = Value - 5.0
WHERE TimeStamp BETWEEN '2024-01-15 08:00:00' AND '2024-01-15 10:00:00'
AND TagName = 'Tank_Temperature';
⚠️ 我曾经犯过的错:有一次我直接在生产库上执行UPDATE,忘了加WHERE条件。结果整张表20万条记录全被改成了同一个值。还好有备份,不然就真凉了。所以我的铁律是:生产环境永远先SELECT确认,再执行UPDATE。而且最好在事务里跑:
BEGIN TRANSACTION;
UPDATE History
SET Value = Value - 5.0
WHERE ...;
-- 检查影响行数,确认无误后提交
-- ROLLBACK; -- 如果不对就回滚
COMMIT;
4.2 DELETE语句:删数据,比改数据更危险
DELETE的语法和UPDATE很像:
DELETE FROM 表名
WHERE 条件;
但我要说一句大实话:DELETE比UPDATE危险十倍。为什么?因为UPDATE改错了还能再改回来,DELETE删了就真没了(除非你有日志恢复)。
我在项目中遇到过一件事:一个新手工程师想删掉测试数据,写了DELETE FROM History,忘了加WHERE。结果整个历史库被清空,三个月的生产数据全没了。后来花了两天从备份里恢复,那两天生产线等于瞎了。
💡 我的建议:在Intouch项目里,能不删就别删。如果非要删,用“软删除”策略——加一个IsDeleted标志位,把数据标记为已删除,而不是物理删除。这样万一出问题,还能恢复。
-- 软删除:标记数据为已删除
UPDATE AlarmHistory
SET IsDeleted = 1, DeletedTime = GETDATE()
WHERE AlarmID = 12345;
-- 查询时过滤掉已删除的数据
SELECT * FROM AlarmHistory
WHERE IsDeleted = 0;
如果确实需要物理删除,记住我的三步法:
- 先SELECT确认:
SELECT COUNT(*) FROM 表 WHERE 条件 - 用事务包裹:BEGIN TRAN → DELETE → 检查影响行数 → COMMIT/ROLLBACK
- 备份当前数据:DELETE之前,先把要删的数据INSERT到一张备份表里
-- 第一步:备份要删除的数据
SELECT * INTO History_Backup_20240115
FROM History
WHERE TimeStamp < '2024-01-01';
-- 第二步:事务删除
BEGIN TRANSACTION;
DELETE FROM History
WHERE TimeStamp < '2024-01-01';
-- 检查影响行数
-- 如果正确则 COMMIT;
-- 否则 ROLLBACK;
COMMIT;
4.3 在Intouch中实现数据维护功能
好了,SQL语句讲完了。但咱们做SCADA的,不可能让操作员直接写SQL吧?所以要在Intouch界面上,给用户一个友好的维护界面。
我一般会在Intouch里做一个“数据维护”页面,包含三个核心功能:
- 数据修正:选择标签、时间段,输入修正值,执行UPDATE
- 数据清理:按时间范围批量删除旧数据(带二次确认)
- 操作日志:记录谁在什么时间改了哪些数据
核心逻辑:Intouch通过QuickScript调用SQL语句,但绝不直接拼接用户输入。我用参数化查询,防止SQL注入。
下面是一个典型的Intouch QuickScript示例,用于数据修正:
// Intouch QuickScript - 数据修正功能
// 假设界面上有:TagNameInput, StartTimeInput, EndTimeInput, CorrectionValueInput
Dim sqlStr As String
Dim conn As Object
Dim cmd As Object
// 使用参数化查询,避免SQL注入
sqlStr = "UPDATE History SET Value = Value + ? WHERE TagName = ? AND TimeStamp BETWEEN ? AND ?"
Set conn = CreateObject("ADODB.Connection")
conn.ConnectionString = "Provider=SQLOLEDB;Data Source=MyServer;Initial Catalog=SCADA_DB;User ID=sa;Password=***"
conn.Open
Set cmd = CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandText = sqlStr
// 添加参数
cmd.Parameters.Append cmd.CreateParameter("correction", adDouble, adParamInput, , CorrectionValueInput)
cmd.Parameters.Append cmd.CreateParameter("tagname", adVarChar, adParamInput, 50, TagNameInput)
cmd.Parameters.Append cmd.CreateParameter("starttime", adDBTimeStamp, adParamInput, , StartTimeInput)
cmd.Parameters.Append cmd.CreateParameter("endtime", adDBTimeStamp, adParamInput, , EndTimeInput)
// 执行
cmd.Execute
// 记录操作日志
LogUserOperation("数据修正", TagNameInput & " " & StartTimeInput & " - " & EndTimeInput)
conn.Close
Set conn = Nothing
Set cmd = Nothing
💡 避坑指南:我曾经在项目里直接用字符串拼接SQL,结果操作员在标签名里输入了一个单引号,整个脚本崩了。从那以后,所有Intouch的数据库操作我都改用参数化查询。虽然多写几行代码,但安全第一。
4.4 数据维护的权限控制
这个我必须单独拿出来说。数据维护功能,绝对不能开放给所有操作员。
我在Intouch里是这样设计的:
| 角色 | 查看数据 | 导出数据 | 修改数据 | 删除数据 |
|---|---|---|---|---|
| 操作员 | ✅ | ✅ | ❌ | ❌ |
| 工程师 | ✅ | ✅ | ✅(需审批) | ❌ |
| 管理员 | ✅ | ✅ | ✅ | ✅(需二次确认) |
你看,删除权限我只给了管理员,而且还要二次确认。修改权限工程师有,但必须填写修改原因,系统会自动记录日志。
我个人习惯:在Intouch的每个数据维护按钮后面,都加一个权限检查脚本。如果当前用户权限不够,直接弹窗拒绝,不给任何操作机会。
// 权限检查示例
If CurrentUserLevel < 50 Then
ShowMessage("您没有权限执行此操作,请联系管理员")
Exit Sub
End If
// 二次确认弹窗
If ShowYesNo("确定要删除 " & RecordCount & " 条历史数据吗?此操作不可恢复!") = False Then
Exit Sub
End If
4.5 本章知识体系
下面这张图,是我对本章核心逻辑的总结。你看一遍,应该就能把UPDATE、DELETE和Intouch维护功能串起来了。
嗯,这一章的内容就这些。UPDATE和DELETE,说白了就是“改”和“删”,但背后的风险意识比语法本身重要得多。我在项目里见过太多因为这两条语句出的事故,所以希望你记住:操作之前多确认一次,比事后补救强一百倍。