您的位置:威尼斯官方网站 > 威尼斯官方网站登录 > 【威尼斯官方网站】不畏数据库表中的自拉长字

【威尼斯官方网站】不畏数据库表中的自拉长字

发布时间:2019-11-12 15:39编辑:威尼斯官方网站登录浏览(158)

    背景

    在上后生可畏篇《数据库操作类SqlHelper》博文的最后,提到了一个施行应用中相见的题目,正是数据库表中的自增加字段的赋值不受人为调控。例如数据库有三个tb_Department表,DeptNO字段为自增进主键。

    威尼斯官方网站 1

    到现在安顿大器晚成行数据

    威尼斯官方网站 2

    哟!DeptNO字段怎么正是22了啊,不应当是从4始发吧?

    原因:那么些表在此之前开展过众多插入操作,数据库针对自增加字段的历次插入都会自动+1,后来剔除了生龙活虎部分行数据,然后再度插入的时候,数据库不会依赖表中缺点和失误的字段值进行赋值,而是在本来的基本功上继续+1赋值。

    结果:在新插入的“哈哈系”数据行以前,其实数据库已经向表里插入过25次了,只是DeptNO字段值大于3的行数据被删去了,将来要新插入行数据以来,就能够在21的根基上+1,也正是第三个表中现身的22了。

    期望:

    1. 在插入新数据的时候,针对自增加字段能够人为调整;
    2. 事实上使用中,其实客商并不知道数据表中自增加字段缺点和失误的是哪些值,程序供给活动提供缺点和失误依然缺省值。

    设计

    1.在插入新数据的时候,针对自增加字段能够人为调控

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

    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.实际应用中,顾客并不知道数据表中自增进字段未选择有何样值,程序需求活动提供缺点和失误依然缺省值

    自增加字段的值分为缺点和失误值和缺省值(这些术语是自个儿本身定的,为了便利描述卡塔 尔(阿拉伯语:قطر‎

    缺点和失误值:比方数据表中自增加字段的值为(1,2,3,5卡塔尔,则缺点和失误值为4。要想让程序自动检索到缺点和失误值,供给对数据表举办康健扫描,逐行剖断自拉长字段的值是还是不是一连依次增加,只要检索到不总是的值就将对应类别的值重返,并出示在窗体上,无需顾客本人输入。

    缺省值:例如数据表中自拉长字段的值为(1,2,3,4卡塔 尔(阿拉伯语:قطر‎,则缺省值为5。倘若原先有10行数据,然后将超过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

    调用存款和储蓄进程,找到的率先个缺省值为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表如下图所示,理论上缺点和失误的值为(4,5,7卡塔尔国,现在往表里插入新值,看看结果怎么着。点击“增添”开关,窗体下方系部编号自动现身第贰个缺点和失误值4,系部名称大家设置为“嘟嘟系”,提交加多成功后,系部编号会自行显示下贰个缺点和失误值5。为了后边的缺省值的结果,大家再充实缺点和失误值(5,7卡塔尔国两行数据,使DeptNO字段三番两次依次增加。

     威尼斯官方网站 8威尼斯官方网站 9

    2.缺省值:

    当DeptNO字段三番五次依次增加时,如下图所示,点击“增减”开关,窗体下方的系部编号成功地提取到第贰个缺省值9,系部名称输入“物理系”,提交扩充成功后,系部编号会活动彰显下三个缺省值10。

     威尼斯官方网站 10威尼斯官方网站 11

    调护医治结果展现大家提议的须要已经收获减轻。

    一.总结

    本文主要针对数据表中自增进字段的插入难点张开疏解,不管表中的数据增加和删除过多少次,程序连接能提供自拉长字段的缺点和失误值恐怕缺省值用于新数据行的插入,进而实现插入自拉长字段值的三回九转依次增加个性。

     

    本文由威尼斯官方网站发布于威尼斯官方网站登录,转载请注明出处:【威尼斯官方网站】不畏数据库表中的自拉长字

    关键词: