一、基础架构与数据类型:先搞清楚“房子”长什么样
1. 架构 (Schema)
这是和 MySQL 最大的逻辑差异。SQL Server 的层级是:实例 -> 数据库 -> Schema -> 表。
- Schema 是一个逻辑容器,用于对表、视图、存储过程等对象进行分组和权限管理。默认 Schema 是
dbo。 - 访问表时,推荐使用完全限定名:
[数据库名].[Schema名].[表名],例如EAPDB.dbo.Equipment。
2. 核心数据类型
把 MySQL 的类型在心里做个映射:
| 场景 | MySQL 类型 | SQL Server 类型 (最常用) | 备注 |
|---|---|---|---|
| 整数主键 | INT | INT | 完全一样 |
| 自增主键 | INT AUTO_INCREMENT | INT IDENTITY(1,1) | 这是必须记住的关键区别 |
| 变长字符串 | VARCHAR(n) | VARCHAR(n)或NVARCHAR(n) | NVARCHAR存 Unicode,推荐用它以支持中文和多语言 |
| 文本 | TEXT | VARCHAR(MAX)或NVARCHAR(MAX) | MAX取代了旧式TEXT类型 |
| 日期时间 | DATETIME | DATETIME2 | DATETIME2精度更高、范围更广,是推荐类型 |
| 布尔值 | TINYINT(1)或BOOL | BIT | SQL Server 没有布尔类型,BIT存 0/1/NULL |
| 浮点数 | FLOAT,DOUBLE | FLOAT,REAL | 通常用FLOAT就行 |
二、核心编程对象:从表到逻辑的封装
这也是一个重要的思维转变。MySQL 通常将复杂逻辑写在业务代码中,而 SQL Server 这类商业数据库更倾向于将数据处理逻辑封装在数据库内部,你拿到的 EAP 框架很可能就是这样。
1. 视图 (View)
就是一个保存下来的SELECT查询。
-- 创建一个视图,方便查询设备及其当前状态CREATEVIEWdbo.vw_EquipmentStatusASSELECTe.EquipmentID,e.EquipmentName,s.StatusName,s.LastUpdateTimeFROMdbo.Equipment eINNERJOINdbo.EquipmentStatusLog sONe.EquipmentID=s.EquipmentIDWHEREs.IsCurrent=1;-- 假设有一个字段标记是否为当前状态GO2. 存储过程 (Stored Procedure)
数据库的核心利器,用于封装事务性业务逻辑。你的 EAP 框架里,诸如“下发工单”、“报工”等操作,极有可能就是调用一个存储过程完成的。
-- 创建一个完成工单下发的存储过程CREATEPROCEDUREdbo.usp_DispatchWorkOrder@WorkOrderIDVARCHAR(50),-- 参数@EquipmentIDINT,@OperatorNameNVARCHAR(50)ASBEGIN-- 防止数据集返回影响后续逻辑SETNOCOUNTON;BEGINTRYBEGINTRANSACTION;-- 开启事务-- 1. 插入工单记录INSERTINTOdbo.WorkOrder(OrderID,EquipmentID,Status,CreateTime)VALUES(@WorkOrderID,@EquipmentID,'Dispatched',GETDATE());-- 2. 更新设备状态为“工作中”UPDATEdbo.EquipmentSETCurrentStatus='Running'WHEREEquipmentID=@EquipmentID;-- 3. 记录操作日志INSERTINTOdbo.OperationLog(Action,Operator,LogTime)VALUES('下发工单 '+@WorkOrderID,@OperatorName,GETDATE());COMMITTRANSACTION;-- 提交事务ENDTRYBEGINCATCHROLLBACKTRANSACTION;-- 回滚事务-- 抛出错误信息THROW;ENDCATCHENDGO3. 函数 (Function)
与存储过程不同,函数必须有返回值,且通常放在SELECT语句里用。
-- 创建一个函数,计算设备的OEE(简化示例)CREATEFUNCTIONdbo.fn_CalculateOEE(@GoodPartsINT,@TotalRunTimeINT,@PlannedProductionTimeINT)RETURNSFLOATASBEGINRETURNCAST(@GoodPartsASFLOAT)/(@TotalRunTime/@PlannedProductionTime);ENDGO三、查询增强:你熟悉的基础之上的强大特性
这些是你必须掌握的,在项目中会大量使用。
1. TOP 关键字
用于限制返回的行数,功能等同于 MySQL 的LIMIT,但写法不同。
SELECTTOP10*FROMdbo.AlarmLogORDERBYLogTimeDESC;-- 最近10条报警2. OVER() 子句 (窗口函数)
这是从 MySQL 进阶到商业数据库最需要掌握的特性。它可以在不改变原始行的情况下进行聚合计算。
-- 1. ROW_NUMBER():为结果集的行编号,常用于分页-- 这是 SQL Server 2012 之前最经典的分页方式SELECT*FROM(SELECT*,ROW_NUMBER()OVER(ORDERBYCreateTimeDESC)ASRowNumFROMdbo.WorkOrder)AStmpWHERERowNumBETWEEN21AND30;-- 2. 与 PARTITION BY 结合:按组编号,非常强大-- 查询每台设备最新的5条报警记录SELECT*FROM(SELECT*,ROW_NUMBER()OVER(PARTITIONBYEquipmentIDORDERBYLogTimeDESC)ASRowNumFROMdbo.AlarmLog)AStmpWHERERowNum<=5;3. 通用表表达式 (CTE)
用WITH ... AS定义一个临时结果集,让复杂查询逻辑更清晰。
-- 查询设备运行时长超过平均值的设备WITHEquipmentRunTimeAS(SELECTEquipmentID,SUM(RunSeconds)ASTotalRunTimeFROMdbo.StatusLogWHEREStatus='Running'GROUPBYEquipmentID)SELECTe.EquipmentName,rt.TotalRunTimeFROMEquipmentRunTime rtJOINdbo.Equipment eONe.EquipmentID=rt.EquipmentIDWHERErt.TotalRunTime>(SELECTAVG(TotalRunTime)FROMEquipmentRunTime);四、常用系统函数:需要查帮助时知道去哪儿找
SQL Server 提供了丰富的内置函数,以下是你需要熟悉的关键词:
- 字符串处理:
CHARINDEX,PATINDEX,SUBSTRING,REPLACE,UPPER/LOWER。 - 日期时间:
GETDATE(),DATEADD,DATEDIFF,YEAR/MONTH/DAY(),FORMAT。 - 数据类型转换:
CAST(expr AS type),CONVERT(type, expr, style)。 - 空值处理:
ISNULL(check_expr, replacement_value)。
给你的上手建议
你现在可以这样开始:
- 连接上 SQL Server,对照着上面的例子,亲手敲一遍
CREATE TABLE,INSERT,SELECT。 - 重点练习
OVER()和CTE,这是分析复杂数据(比如设备效率、不良品统计)的利器。 - 将你项目里的一个表,尝试用 MySQL 和 SQL Server 两种语法都实现一遍,比如“查询所有‘运行’状态设备的最新一条日志”,你会发现差异和共通点。
这样系统性地过一遍,你拿到的 PLDEAPSolution 项目里的数据访问层代码,读起来就会非常顺畅了。