自增进字段值的总是递增实现

背景

在上1篇《数据库操作类SqlHelper》博文的结尾,提到了1个实施应用中遭遇的难题,正是数据库表中的自增加字段的赋值不受人为控制。比如数据库有叁个tb_Department表,DeptNO字段为自拉长主键。

图片 1

现今布置1行数据

图片 2

哎呀!DeptNO字段怎么正是22了呢,不应当是从肆初步吧?

由来:这些表此前进行过众多安排操作,数据库针对自增进字段的历次插入都会活动+1,后来剔除了1部分行数据,然后重新插入的时候,数据库不会依据表中缺点和失误的字段值实行赋值,而是在原本的底子上接轨+一赋值。

结果:在新插入的“哈哈系”数据行在此以前,其实数据库已经向表里插入过二十五遍了,只是DeptNO字段值大于三的行数据被删去了,现在要新插入行数据来说,就会在贰壹的底蕴上+一,约等于第2个表中出现的2二了。

期望:

  1. 在插入新数据的时候,针对自拉长字段能够人为操纵;
  2. 其实使用中,其实用户并不知道数据表中自增进字段缺点和失误的是哪些值,程序需求活动提供缺点和失误依然缺省值。

设计

一.在插入新数据的时候,针对自拉长字段能够人为控制

数据库中针对自增进字段在插入时,不得以钦定显式值的。

insert into tb_Department(DeptNO,DeptName) values(4,N'嘿嘿系')

那般插入数据会报错的,提醒您“当Identity_Insert设置为off时,不能够为表’tb_Department’中的标识列插入显式值”。很扎眼,第二个希望的消除方案正是将Identity_Insert设置on,然后实施显式值插入,最终关闭标识列插入开关。

set identity_insert tb_Department on
insert into tb_Department(DeptNO,DeptName) values(4,N'嘿嘿系')
set identity_insert tb_Department off

执行看看能还是不能够插入,哇哦,成功了,棒棒哒。

图片 3

2.实在选取中,用户并不知道数据表中自拉长字段未利用有何值,程序须要活动提供缺点和失误照旧缺省值

自增加字段的值分为缺点和失误值和缺省值(那么些术语是自家本人定的,为了便于描述)

缺点和失误值:比如数据表中自增进字段的值为(一,二,三,伍),则缺点和失误值为四。要想让程序自动物检疫索到缺点和失误值,须要对数据表实行完美扫描,逐行判断自增加字段的值是不是一连递增,只要检索到不总是的值就将对应体系的值重返,并出示在窗体上,无需用户本人输入。

缺省值:比如数据表中自增进字段的值为(一,二,叁,4),则缺省值为五。就算原先有十行数据,然后将高于4的行删除后,自增加字段本人依然接二连三递增的,只供给找到缺省值,重回给用户。

利用SQL脚本创设存款和储蓄进度达成:(注意:该兑现重临当前自拉长字段中首先个缺点和失误值/缺省值,只适用于每一趟插入一行数据的状态)

--创建一个存储过程用于自动提取自增长字段的第一个缺失值和缺省值
create procedure NumOfDeptNOForInsert
@temp int output  --定义一个输出参数,用于返回缺失值/缺省值
as
declare @Count int   --定义一个当前表中的行数
select @Count=COUNT(1) from tb_Department   --给变量@Count赋值
declare @I int, @IsOK bit = 0,@num int = 1  --定义一个用于循环的@I变量,一个用于判断是缺失值还是缺省值的变量@IsOK,一个记录缺省值的变量@num
set @I = 1;   --变量@I赋值为1
while(@I <= @Count)   --开始循环扫描行数据
begin
    select @temp=DeptNO from tb_Department where DeptNO=@I   --检索DeptNO值=@I值的行数据
    if(@temp != @I)  --判断@I值与DeptNO值是否比对不成功
    begin
        set @temp = @I  --将@I值赋值给@temp
        set @IsOK = 0   --标记为缺失值
        break    --退出循环     
    end
    else    --判断@I值与DeptNO值是否比对成功
    begin
        set @I = @I +1  --@I+1
        set @num = @I   --将@I赋值给@num
        set @IsOK = 1   --标记为缺省值
    end 
end   

if(@IsOK =0)   --判断是缺失值还是缺省值,如果是缺失值
begin
    select @temp  --直接返回@temp
end
else    --如果是缺省值
begin
    set @temp = @num  --将@num赋值给@temp
    select @temp      --再返回@temp
end

自增进字段的一而再递增插入的积存进度设计好后,首先在SQL
Server中检查一下。

declare @temp int --定义输出参数
exec dbo.NumOfDeptNOForInsert @temp  --调用储存过程
print @temp  --打印输出参数
  •  缺失值的检查评定:

图片 4             图片 5

调用存款和储蓄进度看看缺点和失误的第三个值是否5,结果跟预期一样。

  • 缺省值的检查:

图片 6           
图片 7

调用存储进程,找到的第贰个缺省值为七,结果跟预期的壹致。

 实践

前边的辨析规划做好后,当然正是使用于履行了,首假诺编写获取自增加字段的缺点和失误值/缺省值的不二等秘书诀: 

        /// <summary>
        /// 获取自增长字段的第一个缺失值或者缺省值
        /// </summary>
        /// <returns>缺失值/缺省值</returns>
        private int GetDeptNO()
        {
            string cmdText = @"NumOfDeptNOForInsert";
            SqlParameter[] parameters =
            {
                new SqlParameter("@temp",SqlDbType.Int)
            };
            parameters[0].Direction = ParameterDirection.Output;
            int deptNO = (int)SqlHelper.ExecuteScalar(SqlHelper.ConnString, CommandType.StoredProcedure, cmdText,parameters);
            return deptNO;
        }

次第全体的UI设计和编码在博文《数据库操作类SqlHelper》中都早就讲述,那里就不在反复讲了。相对于事先来说,需求转移代码的地点为“扩张”按钮的点击处理程序和InsertData()方法: 

        private void tsbInsert_Click(object sender, EventArgs e)
        {
            cmdType = CmdType.Insert;
            //将gbDept控件设置可用,textbox控件设为可用,并将Text属性清空
            this.gbDept.Enabled = true;
            this.txtDeptName.Enabled = true;
            this.txtDeptName.Text = string.Empty;
            //显示即将插入的DeptNO值
            this.lbDeptNO.Text = GetDeptNO().ToString();
        }

        /// <summary>
        /// 插入数据
        /// </summary>
        private void InsertData()
        {
            //判断系部名称是否为空
            if (string.IsNullOrEmpty(this.txtDeptName.Text.Trim()))
            {
                MessageBox.Show("系部名称不能为空!");
                return;
            }
            //定义插入数据的SQL脚本,其中set identity_insert tb_Department on/off主要是为了能让自增长主键连续有序地插入
            string cmdText = @"set identity_insert tb_Department on 
                               insert into tb_Department(DeptNO,DeptName) values(@DeptNO,@DeptName)
                               set identity_insert tb_Department off";
            ////定义插入数据的Sql脚本
            //string cmdText = @"insert into tb_Department(DeptName) values(@DeptName)";
            //SQL脚本参数设置
            SqlParameter[] parameters =
            {
                new SqlParameter("@DeptNO",(object)this.lbDeptNO.Text),
                new SqlParameter("@DeptName",(object)this.txtDeptName.Text.Trim())
            };
            //执行插入,并返回受影响的行数
            int rows = SqlHelper.ExecuteNonQuery(SqlHelper.ConnString, CommandType.Text, cmdText, parameters);
            //判断是否插入成功,并提示
            if (rows > 0)
            {
                //更新datagridview控件的数据
                LoadData();
                //显示即将插入的DeptNO值
                this.lbDeptNO.Text = GetDeptNO().ToString();
                //将系部名称设为空
                this.txtDeptName.Text = string.Empty;
                MessageBox.Show("插入成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("插入失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            //执行增删改操作
            switch (cmdType)
            {
                case CmdType.Insert:
                    InsertData();
                    break;
                case CmdType.Delete:
                    DeleteData();
                    break;
                case CmdType.Update:
                    UpdateData();
                    break;
            }
        }

结果

UI和编码实现后,调节和测试程序是很关键的,能从调节和测试的进程中再次出现整个职能的思绪,也能找到一些难点所在,修复bug,然后重编码。废话不多说看结果吗:

1.缺失值:

要是壹初阶的tb_Department表如下图所示,理论上缺点和失误的值为(四,5,七),未来往表里插入新值,看看结果什么。点击“扩充”按钮,窗体下方系部编号自动出现第二个缺点和失误值四,系部名称大家设置为“嘟嘟系”,提交添加成功后,系部编号会活动呈现下一个缺点和失误值5。为了后面包车型大巴缺省值的结果,咱们再追加缺点和失误值(5,七)两行数据,使DeptNO字段连续递增。

 图片 8图片 9

2.缺省值:

当DeptNO字段接二连三递增时,如下图所示,点击“增减”按钮,窗体下方的系部编号成功地提取到第1个缺省值9,系部名称输入“物理系”,提交扩大成功后,系部编号会自动展现下三个缺省值10。

 图片 10图片 11

调剂结果展现大家提议的急需已经得到消除。

一.总结

正文重要针对数据表中自增加字段的插入难题进行讲解,不管表中的数据增加和删除过多少次,程序连接能提供自增进字段的缺失值或然缺省值用于新数据行的插入,从而完成插入自增加字段值的连天递增性情。

 

相关文章