关于id字段大家是怎么处理的?不能用数据库的自动加一,因为有的用户需要自己录入、修改。

时间:2021-09-14 15:35:25
每次新录入时必须要从数据库里取出最小的,但这样的话多用户同时录入时就会出问题,大家怎么解决的?(不能保存的瞬间生成id号,因为有的用户需要自己录入)

29 个解决方案

#1


数据库中得有一个ID字段让其自加,这样符合关系数据库的原则,程序也好写,因为这样,一条记录的ID 号是唯一的,可以用该ID号做为唯一标示

#2


自动增加的用户不好修改啊,并且有的用户想自己录入呢,我要新增时就产生id号,不知道怎么办

#3


自动增加的ID对用户来说他看不到,我们在程序里面控制。哦棵?

#4


得了  做一个自动增加的字段  再作一个id字段  如果没有输入的话  就和自动增加的字段相同就是了

#5


id字段不能和自动增加的字段相同的,因为用户可以看到,所以它有一定的编码规则

#6


这样的关键字段应该与业务无关
你可以采用时间磋来实现

#7


另加入一个TQuery在Form上,他的Sql语句:select max(Id) from maindb
每当maindb执行插入操作时,都调用这个query的requery属性,重新找到ID最大值,然后,把最大值的值自动加1,赋给新插入的字段就可以了

#8


up,有经验的帮帮忙!

#9


我最不喜欢用自增字段了。  用它之后,删都删不掉,无限制增加。

特虽是在主从关系表的时候, 用它你麻烦就来了。

还是用sql语句自己写。

insert into table(bh) values  select isnull(max(bh),0)+1 as bh from table

这样自己控件。
用户自己改就用
update table
set bh='000000'

#10


自增字段一旦建立,除非把表结构给重建,要不然永远的自增,

也有删除自增的方法,不过很复杂。

#11


多用户同时添加记录怎么办?

#12


插入之前也就是BeforPost你应该控制呀!

#13


学习!关注!

#14


多用户同时添加记录那你就得看着办了。

如果你会存储过程,就用存储过程来写了。

不过我个人的习惯 是用Adoconnection.
来连接数据源。 其它的adoquery,adocommond,连接到这个adoconnection
上,当多用户同时操作。
用行锁和,事务进行控件了。

Try
Adoconnection.beginstran;
adoquery1.append;  //or edit;
adoquery1('id'):=Getmax(id);  //调用这个取最大 id过程.
adoquery1.fieldbyname('field').asstring:='aaa';
adoquery1.post;
adoconnection.commition;
except
adoconnection.rollback;
//在这里根据相应的ado错误 代码进行控件了.
showmessage('其它用户正在操作此记录'); //关键字重复。等等了.
end;

少用dbedit,用edit来取代edit. 将锁定时间做到最少。

配上select * from table where  /  unlock;

用条件。

#15


gz

#16


解决多用户一般采用   (IP地址+有用信息包括id)生成最终id号  再post
这样同一时间保存id就不会重复。

#17


如果你用SQL SERVER ,
那么你可以用全局临时表法,
用原表名加你的ID创建一张临时表,
当另外的用户来新增时取一个ID,
如果这个ID没有全局临时表,
则表明这个ID没有其它用户在用,
如果有全局临时表,则ID加1再判断,
本方法用的是全局临时表的一个特性,
当创建者的连接断开后,全局临时表自动删除!

但是你的系统如果是用多层做的,
则不能用本方法,本方法只适用于C/S结构!

#18


我有一个方法:

假如你定三位的ID(Char型,长度为3),
procedure ***
var
  IDmax: Integer;
  sID: string;
begin
  with ADOQuery1 do
  begin
    try
      Close;
      SQL.Clear;
      SQL.Add('Select Max(ID) as IDmax from ***');
      Open;
      IDmax:=FieldByName('IDmax').AsInteger;
      if IDmax<9 then sID:='00'+InttoStr(IDmax+1)
      else if (IDmax>=9) and (IDmax<99) then sID:='0'+InttoStr(IDmax+1)
      else sID:=InttoStr(IDmax+1);
      try
        Close;
        SQL.Clear;
        SQL.Add('Insert into *** (ID) values ('+sID+')');
        ExecSQL;
      finally
        Close; 
      end; 
    finally
      Close;
    end;
  end;
end;

#19


从表中取最小值!

Select top 1 bh from Table1 order by bh asc

不知道是不是想要的?!

关于多用户,我想即使大家都在增加的话!在每用户增加时记录也会被锁定的?!

#20


如果同时有多个用户添加新纪录的话,那么他们取得的最小ID值是一样地,这样就会出问题,造成ID重复。
这应该是个常见问题呀,请有经验的出招。谢谢

#21


还有,我的系统是三层

#22


看你用什么数据库,oracle:
select max(Id) from maindb update nowait;
进行锁记录操作。这样多用户也没问题!

#23


多用户操作的时候取得的max(id)是一样的呀,这样同时新增时的id是重复的,我用的是sql server库

#24


1 首先劝你不要把用户需要更改的那个所谓 ID 号作为表的主键
2 其次你可以另设一个字段(哪怕是增加一个字段)作为表主键
3 如果1 中提到的字段需要一个默认值的话,让程序生成一个默认值show给用户,供他修改
4 至于表主键怎么生成,楼上有很多同仁都已作出回答
5 祝你成功!

#25


用户可修改的ID不是主键,主键我是调用生成GUID的函数得到的,用户可修改的那个字段(ID)不能重复,每次新增时都要给个ID值给用户,问题是怎么样生成这个ID呢,而且最好要连续。

#26


在我以前的毕业设计时做的

问题: 解决自动流水号的问题。
难点: 第一个。最后一个。中间删掉的(不能重复的)补充。
解决方法:一个一个与数据库作比较。每一次加一。如果是第一个赋值为一。
procedure TFormJLB.UserLsh();//自己定义的人员流水号码。
var m:Integer;               //定义两个int型变量
b:Integer;
begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('select personID from person ORDER BY  personID');//做降序排列。
Query1.Open;
Query1.First;//从排列的第一个开始
b:=1;
if Query1.RecordCount=0 then Edit1.Text:=IntToStr(1)//如果没有第一个,则Edit1为1。
else
     begin
          while  not Query1.Eof do //如果没有到最后一个,开始。
          begin
             m:=Query1.FieldByName('personID').Value;//让m等于循环到的流水号。
             if b<>m then  //如果b不等于m的话 
             begin
                break;    //跳出循环
             end;
             b:=b+1;      
             Query1.Next;//Query1继续循环
          end;
          Edit1.Text:=IntToStr(b);//Edit1等于b
      end;
      Edit1.Enabled:=false;

#27


保存之前先要对数据库中的已有ID作一个查询,看看没有有和现在ID重复的记录,如果有的话就不能存盘,这个方法,我想还是能处理多用户的情况的。

#28


procedure Get_ID;
begin
with query do
begin
close;
sql.clear;
unprepare;
sql.add('select max(id) as Mid from TableX');
prepare;
open;
if recordcount>0 then
edit1.text:=inttostr(fieldbyname('Mid').asinteger+1);
else
edit1.text:='00001';
end;
end;
按下"新增时调用这个过程,会取得ID,用户也可以自已在EDIT1.TEXT中输入

#29


学习

#1


数据库中得有一个ID字段让其自加,这样符合关系数据库的原则,程序也好写,因为这样,一条记录的ID 号是唯一的,可以用该ID号做为唯一标示

#2


自动增加的用户不好修改啊,并且有的用户想自己录入呢,我要新增时就产生id号,不知道怎么办

#3


自动增加的ID对用户来说他看不到,我们在程序里面控制。哦棵?

#4


得了  做一个自动增加的字段  再作一个id字段  如果没有输入的话  就和自动增加的字段相同就是了

#5


id字段不能和自动增加的字段相同的,因为用户可以看到,所以它有一定的编码规则

#6


这样的关键字段应该与业务无关
你可以采用时间磋来实现

#7


另加入一个TQuery在Form上,他的Sql语句:select max(Id) from maindb
每当maindb执行插入操作时,都调用这个query的requery属性,重新找到ID最大值,然后,把最大值的值自动加1,赋给新插入的字段就可以了

#8


up,有经验的帮帮忙!

#9


我最不喜欢用自增字段了。  用它之后,删都删不掉,无限制增加。

特虽是在主从关系表的时候, 用它你麻烦就来了。

还是用sql语句自己写。

insert into table(bh) values  select isnull(max(bh),0)+1 as bh from table

这样自己控件。
用户自己改就用
update table
set bh='000000'

#10


自增字段一旦建立,除非把表结构给重建,要不然永远的自增,

也有删除自增的方法,不过很复杂。

#11


多用户同时添加记录怎么办?

#12


插入之前也就是BeforPost你应该控制呀!

#13


学习!关注!

#14


多用户同时添加记录那你就得看着办了。

如果你会存储过程,就用存储过程来写了。

不过我个人的习惯 是用Adoconnection.
来连接数据源。 其它的adoquery,adocommond,连接到这个adoconnection
上,当多用户同时操作。
用行锁和,事务进行控件了。

Try
Adoconnection.beginstran;
adoquery1.append;  //or edit;
adoquery1('id'):=Getmax(id);  //调用这个取最大 id过程.
adoquery1.fieldbyname('field').asstring:='aaa';
adoquery1.post;
adoconnection.commition;
except
adoconnection.rollback;
//在这里根据相应的ado错误 代码进行控件了.
showmessage('其它用户正在操作此记录'); //关键字重复。等等了.
end;

少用dbedit,用edit来取代edit. 将锁定时间做到最少。

配上select * from table where  /  unlock;

用条件。

#15


gz

#16


解决多用户一般采用   (IP地址+有用信息包括id)生成最终id号  再post
这样同一时间保存id就不会重复。

#17


如果你用SQL SERVER ,
那么你可以用全局临时表法,
用原表名加你的ID创建一张临时表,
当另外的用户来新增时取一个ID,
如果这个ID没有全局临时表,
则表明这个ID没有其它用户在用,
如果有全局临时表,则ID加1再判断,
本方法用的是全局临时表的一个特性,
当创建者的连接断开后,全局临时表自动删除!

但是你的系统如果是用多层做的,
则不能用本方法,本方法只适用于C/S结构!

#18


我有一个方法:

假如你定三位的ID(Char型,长度为3),
procedure ***
var
  IDmax: Integer;
  sID: string;
begin
  with ADOQuery1 do
  begin
    try
      Close;
      SQL.Clear;
      SQL.Add('Select Max(ID) as IDmax from ***');
      Open;
      IDmax:=FieldByName('IDmax').AsInteger;
      if IDmax<9 then sID:='00'+InttoStr(IDmax+1)
      else if (IDmax>=9) and (IDmax<99) then sID:='0'+InttoStr(IDmax+1)
      else sID:=InttoStr(IDmax+1);
      try
        Close;
        SQL.Clear;
        SQL.Add('Insert into *** (ID) values ('+sID+')');
        ExecSQL;
      finally
        Close; 
      end; 
    finally
      Close;
    end;
  end;
end;

#19


从表中取最小值!

Select top 1 bh from Table1 order by bh asc

不知道是不是想要的?!

关于多用户,我想即使大家都在增加的话!在每用户增加时记录也会被锁定的?!

#20


如果同时有多个用户添加新纪录的话,那么他们取得的最小ID值是一样地,这样就会出问题,造成ID重复。
这应该是个常见问题呀,请有经验的出招。谢谢

#21


还有,我的系统是三层

#22


看你用什么数据库,oracle:
select max(Id) from maindb update nowait;
进行锁记录操作。这样多用户也没问题!

#23


多用户操作的时候取得的max(id)是一样的呀,这样同时新增时的id是重复的,我用的是sql server库

#24


1 首先劝你不要把用户需要更改的那个所谓 ID 号作为表的主键
2 其次你可以另设一个字段(哪怕是增加一个字段)作为表主键
3 如果1 中提到的字段需要一个默认值的话,让程序生成一个默认值show给用户,供他修改
4 至于表主键怎么生成,楼上有很多同仁都已作出回答
5 祝你成功!

#25


用户可修改的ID不是主键,主键我是调用生成GUID的函数得到的,用户可修改的那个字段(ID)不能重复,每次新增时都要给个ID值给用户,问题是怎么样生成这个ID呢,而且最好要连续。

#26


在我以前的毕业设计时做的

问题: 解决自动流水号的问题。
难点: 第一个。最后一个。中间删掉的(不能重复的)补充。
解决方法:一个一个与数据库作比较。每一次加一。如果是第一个赋值为一。
procedure TFormJLB.UserLsh();//自己定义的人员流水号码。
var m:Integer;               //定义两个int型变量
b:Integer;
begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('select personID from person ORDER BY  personID');//做降序排列。
Query1.Open;
Query1.First;//从排列的第一个开始
b:=1;
if Query1.RecordCount=0 then Edit1.Text:=IntToStr(1)//如果没有第一个,则Edit1为1。
else
     begin
          while  not Query1.Eof do //如果没有到最后一个,开始。
          begin
             m:=Query1.FieldByName('personID').Value;//让m等于循环到的流水号。
             if b<>m then  //如果b不等于m的话 
             begin
                break;    //跳出循环
             end;
             b:=b+1;      
             Query1.Next;//Query1继续循环
          end;
          Edit1.Text:=IntToStr(b);//Edit1等于b
      end;
      Edit1.Enabled:=false;

#27


保存之前先要对数据库中的已有ID作一个查询,看看没有有和现在ID重复的记录,如果有的话就不能存盘,这个方法,我想还是能处理多用户的情况的。

#28


procedure Get_ID;
begin
with query do
begin
close;
sql.clear;
unprepare;
sql.add('select max(id) as Mid from TableX');
prepare;
open;
if recordcount>0 then
edit1.text:=inttostr(fieldbyname('Mid').asinteger+1);
else
edit1.text:='00001';
end;
end;
按下"新增时调用这个过程,会取得ID,用户也可以自已在EDIT1.TEXT中输入

#29


学习