您的位置:首页 > 其它

存储过程+游标,第一回开发使用

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主键值,从而作下步操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: