为了方便查询出三种状态的机柜,即“正常状态”、“预警状态”、“过期状态”,需要在启动应用程序时对各机柜状态进行相关处理地,此处理过程用到了存储过程、游标,以及数据表以下:
------------->
1 set ANSI_NULLS ON
2 set QUOTED_IDENTIFIER ON
3 go
4
5 ALTER PROCEDURE [dbo].[PollingWarning]
6 @Divide INT --预警临界值
7 AS
8 BEGIN
9 DECLARE CUR_CalcDifference CURSOR
10 FOR SELECT CabinetID, PollingPeriod, LastPollingTime FROM BusCabinet;
11 --打开游标
12 OPEN CUR_CalcDifference
13
14 DECLARE @mSecond INT --最后巡检日期与当天日期的【毫秒差】
15 DECLARE @mDay INT --该【毫秒差】转换成的【天数差】
16 DECLARE @Difference INT --【巡检周期】与 【天数差】的差值
17
18 DECLARE @CabinetID NVARCHAR(4) --遍历过程中每一条记录的【机柜编号】
19 DECLARE @PollingPeriod INT --遍历过程中每一条记录的【巡检周期】
20 DECLARE @LastPollingTime DATETIME --遍历过程中每一条记录的【最后巡检时间】
21
22 FETCH FROM CUR_CalcDifference --拾取第一条记录(从而能够对 @@FETCH_STATUS进行判断)
23 INTO @CabinetID,@PollingPeriod,@LastPollingTime
24
25 WHILE @@FETCH_STATUS = 0 --执行成功
26 BEGIN
27 PRINT @CabinetID;
28 PRINT @PollingPeriod;
29 PRINT @LastPollingTime;
30
31 --当机柜刚生成时,其【最后巡检时间】往往是空的,这时机柜的巡检状态默认为 1(绿色正常)。
32 IF @LastPollingTime = '' OR @LastPollingTime IS NULL
33 BEGIN
34 UPDATE BusCabinet SET CabinetStatusID = 1 WHERE CURRENT OF CUR_CalcDifference
35 END
36 --经过一次数据同步后,【最后巡检时间】有了一个确定的时间戳
37 ELSE
38 BEGIN
39 SET @mSecond = DATEDIFF(millisecond,@LastPollingTime,GETDATE()); --最后巡检日期与今天的毫秒差
40 SET @mDay = @mSecond / (1000 * 60 * 60 * 24); --该毫秒差转换成的【天数差】
41
42 PRINT '@mDay = '+CONVERT(CHAR(20),@mDay);
43
44 SET @Difference = @PollingPeriod - @mDay; --求出 【巡检周期】与 【天数差】的差值
45
46 PRINT '@Difference = '+CONVERT(CHAR(20),@Difference);
47
48 /*
49 * 设 @Difference 为一变量 X,且预警临界值 @Divide为变量 Y
50 * 当 X <= 0 时:红色过期;
51 * 当 0 < X < Y:黄色预警;
52 * 当 X >= Y : 绿色正常。
53 */
54
55 IF @Difference <=0
56 BEGIN
57 UPDATE BusCabinet SET CabinetStatusID = 3 WHERE CURRENT OF CUR_CalcDifference
58 PRINT '红色过期!'
59 END
60 ELSE IF @Difference>0 and @Difference<@Divide
61 BEGIN
62 UPDATE BusCabinet SET CabinetStatusID = 2 WHERE CURRENT OF CUR_CalcDifference
63 PRINT '黄色预警!'
64 END
65 ELSE IF @Difference>=@Divide
66 BEGIN
67 UPDATE BusCabinet SET CabinetStatusID = 1 WHERE CURRENT OF CUR_CalcDifference
68 PRINT '绿色正常!'
69 END
70
71 END
72
73 PRINT '-----------------------------------------------------'
74
75 --继续拾取下一条记录
76 FETCH NEXT FROM CUR_CalcDifference
77 INTO @CabinetID,@PollingPeriod,@LastPollingTime
78
79 IF(@@FETCH_STATUS <>0)
80 PRINT '当前@@FETCH_STATUS = '+CONVERT(CHAR(20),@@FETCH_STATUS)+'退出'
81
82 END
83 CLOSE CUR_CalcDifference
84 deallocate CUR_CalcDifference
85
86 END
87
88
上述存储过程在前台 以多线程方式调用,代码如下:
1 Thread RefreshCabinetThread;
2 BusCabinetDal cabinetDal = new BusCabinetDal();//数据访问层
3
4 //构造函数
5 public FrmClientMain()
6 {
7 InitializeComponent();8 RefreshCabinetThread = new Thread(new ThreadStart(StartRefresh));
11 RefreshCabinetThread.Start();
12 }
13
14 private void StartRefresh()
15 {
16 //刷新机柜状态【预警临界线,从App.config文件中读取】
17 int divide = Convert.ToInt32(ConfigurationManager.AppSettings["divide"]);
18 cabinetDal.RefreshCabinetStatus(divide);//它的定义在下面
19 }
1 public void RefreshCabinetStatus(int divide)
2 {
3 SqlParameter[] parameters = {
4 new SqlParameter("@Divide", SqlDbType.Int,4)};
5 parameters[0].Value = divide;
6 SqlHelper.ExecuteNonQuery(ConnectionFactory.CreateConnection(), CommandType.StoredProcedure, "PollingWarning", parameters);
7 }
上面的基本步骤完成后,机柜的状态都该尘埃落定,下面只需要通过 CabinetStatusID 来“各取所需”了,
即 巡检状态“绿色正常”只要查询 CabinetStatusID = 1 的就可以;
巡检状态“黄色预警”只要查询 CabinetStatusID = 2 的就可以;
巡检状态“红色过期”只要查询 CabinetStatusID = 3 的就可以。
实现函数如下:
1 /// <summary>
2 /// PutCabinetIntoPanel() 将机柜放置到 FlowLayoutPanel
3 /// </summary>
4 /// <param name="queryString">根据查询条件的不同,区分不同机柜</param>
5 /// <param name="flowLayoutPanel">机柜放置的Panel</param>
6 /// <param name="color">机柜显示的颜色</param>
7 private void PutCabinetIntoPanel(string queryString, FlowLayoutPanel flowLayoutPanel, Color color)
8 {
9 DataTable dtCabinet = cabinetDal.GetCabinetForToolBar(queryString).Tables[0];
10 if (dtCabinet.Rows.Count > 0)
11 {
12 for (int i = 0; i < dtCabinet.Rows.Count; i++)
13 {
14 UCCabinet cabinetEntoty = new UCCabinet();
15 string cabinetID = dtCabinet.Rows[i]["CabinetID"].ToString();
16 string cabinetName = dtCabinet.Rows[i]["CabinetName"].ToString();
17 string pollingPeriod = dtCabinet.Rows[i]["PollingPeriod"].ToString();
18 string lastPollingTime = dtCabinet.Rows[i]["LastPollingTime"].ToString();
19
20 cabinetEntoty.Name = cabinetID;
21 cabinetEntoty.ToolTip = String.Format("机柜名称:{0}\n巡检周期:{1}天\n最后巡检时间:{2}", cabinetName, pollingPeriod, lastPollingTime);
22 cabinetEntoty.SetBackColor = color;
23 cabinetEntoty.OnButtonClick += new CabinetButtonClick(cabinetEntoty_OnButtonClick);//订阅用户控件单击事件
24 flowLayoutPanel.Controls.Add(cabinetEntoty);
25 }
26 }
27 }
void cabinetEntoty_OnButtonClick(string cabinetID)
{
MessageBox.Show(cabinetID);
}
显示于 TabControl面板上的每个方格,都是一个用户控件:
1 public delegate void CabinetButtonClick(string cabinetID);
2 public partial class UCCabinet : UserControl
3 {
4 //显示名称
5 public string Name
6 {
7 get { return btnEntity.Text; }
8 set { btnEntity.Text = value; }
9 }
10
11 //提示
12 public string ToolTip
13 {
14 set { btnEntity.Tooltip = value; }
15 }
16
17 //背景色
18 public Color SetBackColor
19 {
20 set { btnEntity.BackColor = value; }
21 }
22 //定义单击事件
23 public event CabinetButtonClick OnButtonClick;
24
25 public UCCabinet()
26 {
27 InitializeComponent();
28 btnEntity.BackColor = Color.Transparent;
29 }
30
31 //单击传递机柜编号
32 private void btnEntity_Click(object sender, EventArgs e)
33 {
34 if (OnButtonClick != null)
35 {
36 OnButtonClick(Name);
37 }
38 }
39
40 }
经过存储过程把机柜作了分类,再让 CabinetStatusID 一一查询到相对应的 TabControl分页中,每一个机柜以用户控件呈现,点击可获取 CabinetID主键值,从而作下步操作。