存储过程+游标,第一回开发使用
2010-09-26 15:06
495 查看
为了方便查询出三种状态的机柜,即“正常状态”、“预警状态”、“过期状态”,需要在启动应用程序时对各机柜状态进行相关处理地,此处理过程用到了存储过程、游标,以及数据表以下:
------------->
set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go ALTER PROCEDURE [dbo].[PollingWarning] @Divide INT --预警临界值 AS BEGIN DECLARE CUR_CalcDifference CURSOR FOR SELECT CabinetID, PollingPeriod, LastPollingTime FROM BusCabinet; --打开游标 OPEN CUR_CalcDifference DECLARE @mSecond INT --最后巡检日期与当天日期的【毫秒差】 DECLARE @mDay INT --该【毫秒差】转换成的【天数差】 DECLARE @Difference INT --【巡检周期】与 【天数差】的差值 DECLARE @CabinetID NVARCHAR(4) --遍历过程中每一条记录的【机柜编号】 DECLARE @PollingPeriod INT --遍历过程中每一条记录的【巡检周期】 DECLARE @LastPollingTime DATETIME --遍历过程中每一条记录的【最后巡检时间】 FETCH FROM CUR_CalcDifference --拾取第一条记录(从而能够对 @@FETCH_STATUS进行判断) INTO @CabinetID,@PollingPeriod,@LastPollingTime WHILE @@FETCH_STATUS = 0 --执行成功 BEGIN PRINT @CabinetID; PRINT @PollingPeriod; PRINT @LastPollingTime; --当机柜刚生成时,其【最后巡检时间】往往是空的,这时机柜的巡检状态默认为 1(绿色正常)。 IF @LastPollingTime = '' OR @LastPollingTime IS NULL BEGIN UPDATE BusCabinet SET CabinetStatusID = 1 WHERE CURRENT OF CUR_CalcDifference END --经过一次数据同步后,【最后巡检时间】有了一个确定的时间戳 ELSE BEGIN SET @mSecond = DATEDIFF(millisecond,@LastPollingTime,GETDATE()); --最后巡检日期与今天的毫秒差 SET @mDay = @mSecond / (1000 * 60 * 60 * 24); --该毫秒差转换成的【天数差】 PRINT '@mDay = '+CONVERT(CHAR(20),@mDay); SET @Difference = @PollingPeriod - @mDay; --求出 【巡检周期】与 【天数差】的差值 PRINT '@Difference = '+CONVERT(CHAR(20),@Difference); /* * 设 @Difference 为一变量 X,且预警临界值 @Divide为变量 Y * 当 X <= 0 时:红色过期; * 当 0 < X < Y:黄色预警; * 当 X >= Y : 绿色正常。 */ IF @Difference <=0 BEGIN UPDATE BusCabinet SET CabinetStatusID = 3 WHERE CURRENT OF CUR_CalcDifference PRINT '红色过期!' END ELSE IF @Difference>0 and @Difference<@Divide BEGIN UPDATE BusCabinet SET CabinetStatusID = 2 WHERE CURRENT OF CUR_CalcDifference PRINT '黄色预警!' END ELSE IF @Difference>=@Divide BEGIN UPDATE BusCabinet SET CabinetStatusID = 1 WHERE CURRENT OF CUR_CalcDifference PRINT '绿色正常!' END END PRINT '-----------------------------------------------------' --继续拾取下一条记录 FETCH NEXT FROM CUR_CalcDifference INTO @CabinetID,@PollingPeriod,@LastPollingTime IF(@@FETCH_STATUS <>0) PRINT '当前@@FETCH_STATUS = '+CONVERT(CHAR(20),@@FETCH_STATUS)+'退出' END CLOSE CUR_CalcDifference deallocate CUR_CalcDifference END
上述存储过程在前台 以多线程方式调用,代码如下:
Thread RefreshCabinetThread; BusCabinetDal cabinetDal = new BusCabinetDal();//数据访问层 //构造函数 public FrmClientMain() { InitializeComponent(); RefreshCabinetThread = new Thread(new ThreadStart(StartRefresh)); RefreshCabinetThread.Start(); } private void StartRefresh() { //刷新机柜状态【预警临界线,从App.config文件中读取】 int divide = Convert.ToInt32(ConfigurationManager.AppSettings["divide"]); cabinetDal.RefreshCabinetStatus(divide);//它的定义在下面 }
public void RefreshCabinetStatus(int divide) { SqlParameter[] parameters = { new SqlParameter("@Divide", SqlDbType.Int,4)}; parameters[0].Value = divide; SqlHelper.ExecuteNonQuery(ConnectionFactory.CreateConnection(), CommandType.StoredProcedure, "PollingWarning", parameters); }
上面的基本步骤完成后,机柜的状态都该尘埃落定,下面只需要通过 CabinetStatusID 来“各取所需”了,
即 巡检状态“绿色正常”只要查询 CabinetStatusID = 1 的就可以;
巡检状态“黄色预警”只要查询 CabinetStatusID = 2 的就可以;
巡检状态“红色过期”只要查询 CabinetStatusID = 3 的就可以。
实现函数如下:
/// <summary> /// PutCabinetIntoPanel() 将机柜放置到 FlowLayoutPanel /// </summary> /// <param name="queryString">根据查询条件的不同,区分不同机柜</param> /// <param name="flowLayoutPanel">机柜放置的Panel</param> /// <param name="color">机柜显示的颜色</param> private void PutCabinetIntoPanel(string queryString, FlowLayoutPanel flowLayoutPanel, Color color) { DataTable dtCabinet = cabinetDal.GetCabinetForToolBar(queryString).Tables[0]; if (dtCabinet.Rows.Count > 0) { for (int i = 0; i < dtCabinet.Rows.Count; i++) { UCCabinet cabinetEntoty = new UCCabinet(); string cabinetID = dtCabinet.Rows[i]["CabinetID"].ToString(); string cabinetName = dtCabinet.Rows[i]["CabinetName"].ToString(); string pollingPeriod = dtCabinet.Rows[i]["PollingPeriod"].ToString(); string lastPollingTime = dtCabinet.Rows[i]["LastPollingTime"].ToString(); cabinetEntoty.Name = cabinetID; cabinetEntoty.ToolTip = String.Format("机柜名称:{0}\n巡检周期:{1}天\n最后巡检时间:{2}", cabinetName, pollingPeriod, lastPollingTime); cabinetEntoty.SetBackColor = color; cabinetEntoty.OnButtonClick += new CabinetButtonClick(cabinetEntoty_OnButtonClick);//订阅用户控件单击事件 flowLayoutPanel.Controls.Add(cabinetEntoty); } } }
void cabinetEntoty_OnButtonClick(string cabinetID) { MessageBox.Show(cabinetID); }
显示于 TabControl面板上的每个方格,都是一个用户控件:
public delegate void CabinetButtonClick(string cabinetID); public partial class UCCabinet : UserControl { //显示名称 public string Name { get { return btnEntity.Text; } set { btnEntity.Text = value; } } //提示 public string ToolTip { set { btnEntity.Tooltip = value; } } //背景色 public Color SetBackColor { set { btnEntity.BackColor = value; } } //定义单击事件 public event CabinetButtonClick OnButtonClick; public UCCabinet() { InitializeComponent(); btnEntity.BackColor = Color.Transparent; } //单击传递机柜编号 private void btnEntity_Click(object sender, EventArgs e) { if (OnButtonClick != null) { OnButtonClick(Name); } } }
经过存储过程把机柜作了分类,再让 CabinetStatusID 一一查询到相对应的 TabControl分页中,每一个机柜以用户控件呈现,点击可获取 CabinetID主键值,从而作下步操作。
相关文章推荐
- 数据库开发之存储过程、触发器、游标
- 存储过程中游标和临时表的使用
- MySql 存储过程游标使用示例
- mysql存储过程以及游标的使用
- 存储过程使用游标
- oracle使用游标 触发器的存储过程
- oracle存储过程中游标的使用
- <Oracle游标>存储过程中使用游标
- mysql 存储过程中使用多游标
- Oracle8i中使用Java语言来开发存储过程
- oracle中建表、游标、存储过程的使用方法入门
- Mysql存储过程循环内嵌套使用游标示例代码
- 在存储过程中使用循环——即使用游标
- oracle存储过程之insert的使用,含游标的使用
- 在SqlServer存储过程中使用Cursor(游标)操作记录
- Mysql存储过程优化——使用临时表代替游标(转)
- SQL Server学习:存储过程中Cursor(游标)的使用
- 原创:SQL Server的通用分页存储过程,未使用游标,速度更快!
- 关于在存储过程中使用游标操作数据库
- mysql 数据库 简单存储过程游标使用