我试着用了ACCESS的自动编码类型的字段但实在是太烂了,而且在INSERT时,该字段对应的DBEdit是不可见的(而且不能编辑),最好不用自动编码类型的字段。而用文本型的(00000001~~99999999),求助一个较好的自动生成图书ID代码的方法(算法)。
29 个解决方案
#1
function GetGUID:string;
var
id:tguid;
begin
if CoCreateGuid(id)=s_ok then
result:=guidtostring(id);
end;
var
id:tguid;
begin
if CoCreateGuid(id)=s_ok then
result:=guidtostring(id);
end;
#2
理论上几乎没有重复的可能。
#3
function CoCreateGuid(out guid: TGUID): HResult; stdcall; external 'ole32.dll' name 'CoCreateGuid';
#4
又学了一招!
#5
还可以在数据库后端, 定义一个触发器, 通过生成器自动生成字段.
#6
还是用触发器把
GUID太长
GUID太长
#7
在程序里写自动编号的方法
#8
formatdataTime('YYYYMMDDHHmmss',now)+inttostr(random('99999'));
#9
还有没有更好的方法???最好是生成的ID在00000000~~~99999999之间就更好了。
#10
自动编号或者用条形码
#11
没必要guid吧..
#12
求表中最大记录号。
#13
GUID 太长了,可以根据系统当前的年月日再加上时间就可以生成唯一的id了
#14
求最大记录号
#15
可以建一个表,作为流水帐号。每插入一条记录,先取流水帐号表的ID,在修改流水帐号表的ID,使它加一,这样取出来的ID号就不可能有重复的了
#16
可以建一个表,作为流水帐号。每插入一条记录,先取流水帐号表的ID,在修改流水帐号表的ID,使它加一,这样取出来的ID号就不可能有重复的了
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
#17
给我分吧,我分太少了!!
function GetNextRecNo(var ATableName,AFieldName,ACondition,
ADesFieldName:String;AFieldLen:integer):String;
var
lMax,I:Integer;
lID,lDef:String;
myQuery:TAdoQuery;
begin
lDef:= '000000000000000';
SetLength(lDef,AFieldLen-1);
myQuery:=TAdoQuery.Create(nil);
try
//---- ×Ô¶¯¼ÓÈë±àºÅ
with myQuery do
begin
SQL.Clear;
if ACondition<>'' then
SQL.Add('Select Distinct '+AFieldName+' from '+TableName+' where '+ACondition+' Order By '+ADesFieldName+' Desc')
else
SQL.Add('Select Distinct '+AFieldName+' from '+TableName+' Order By '+ADesFieldName+' Desc');
Open;
if ADesFieldName='' then ADesFieldName:=AFieldName;
if not eof then
begin
lMax:=StrToInt('0'+FieldByName(ADesFieldName).AsString);
if RecordCount=lMax then
lID:= Copy(lDef+IntToStr(RecordCount+1),Length(lDef+IntToStr(RecordCount+1))-(AFieldLen-1),AFieldLen)
else
begin
for I:=RecordCount downto 0 Do
begin
lMax:=StrToInt('0'+FieldByName(ADesFieldName).AsString);
if I=lMax then begin
lID:= Copy(lDef+IntToStr(I+1),Length(lDef+IntToStr(I+1))-(AFieldLen-1),AFieldLen);
Break;
end
else
Next;
if I=0 then lID:=lDef+'1';
end;
end;
end else
lID:=lDef+'1';
Close;
end;
Result:= lID;
finally
myQuery.Free;
end;
end;
function GetNextRecNo(var ATableName,AFieldName,ACondition,
ADesFieldName:String;AFieldLen:integer):String;
var
lMax,I:Integer;
lID,lDef:String;
myQuery:TAdoQuery;
begin
lDef:= '000000000000000';
SetLength(lDef,AFieldLen-1);
myQuery:=TAdoQuery.Create(nil);
try
//---- ×Ô¶¯¼ÓÈë±àºÅ
with myQuery do
begin
SQL.Clear;
if ACondition<>'' then
SQL.Add('Select Distinct '+AFieldName+' from '+TableName+' where '+ACondition+' Order By '+ADesFieldName+' Desc')
else
SQL.Add('Select Distinct '+AFieldName+' from '+TableName+' Order By '+ADesFieldName+' Desc');
Open;
if ADesFieldName='' then ADesFieldName:=AFieldName;
if not eof then
begin
lMax:=StrToInt('0'+FieldByName(ADesFieldName).AsString);
if RecordCount=lMax then
lID:= Copy(lDef+IntToStr(RecordCount+1),Length(lDef+IntToStr(RecordCount+1))-(AFieldLen-1),AFieldLen)
else
begin
for I:=RecordCount downto 0 Do
begin
lMax:=StrToInt('0'+FieldByName(ADesFieldName).AsString);
if I=lMax then begin
lID:= Copy(lDef+IntToStr(I+1),Length(lDef+IntToStr(I+1))-(AFieldLen-1),AFieldLen);
Break;
end
else
Next;
if I=0 then lID:=lDef+'1';
end;
end;
end else
lID:=lDef+'1';
Close;
end;
Result:= lID;
finally
myQuery.Free;
end;
end;
#18
guid
time
no++
...
time
no++
...
#19
用select count(*) as rowcount from XXXX计算表中的行数
所得结果加一
插入时用它做ID
good luck
所得结果加一
插入时用它做ID
good luck
#20
恩,呵呵~~~~~~hkbarton(→Beginner←) 的方法是个好的办法,wuxiangyang() 的方法看了半天没看懂,能给些注释吗??我感觉也有点太麻烦了,呵呵~~~~上面有人说采用条形码的方法,说仔细些???怎么样生成条形码???
#21
hkbarton(→Beginner←) 的方法我以前也用,但不能保证唯一,如果用户修改了时间呢?如果是多用户呢?
#22
miky(miky) 说的有道理。就没什么好的办法吗??继续关注。。。。。。
#23
可以建一个表,作为流水帐号。每插入一条记录,先取流水帐号表的ID,在修改流水帐号表的ID,使它加一,这样取出来的ID号就不可能有重复的了
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
----
完全同意
GUID太长了,自增字段问题多多。用时间既不安全,也有些长,影响效率。
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
----
完全同意
GUID太长了,自增字段问题多多。用时间既不安全,也有些长,影响效率。
#24
可以建一个表,作为流水帐号。每插入一条记录,先取流水帐号表的ID,在修改流水帐号表的ID,使它加一,这样取出来的ID号就不可能有重复的了
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
----
这不正是自增字段为我们做的吗?
我不明白自增字段有什么问题,我觉得非常好用。
只有一种情况,就是你有多个不连网的客户端,为了保证他们的数据ID也不重复,这时候才不能用。
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
----
这不正是自增字段为我们做的吗?
我不明白自增字段有什么问题,我觉得非常好用。
只有一种情况,就是你有多个不连网的客户端,为了保证他们的数据ID也不重复,这时候才不能用。
#25
自增字段在用DBEdit开发时,如果你调用了ADOTable.Append;方法后,该DBEdit上Text内容是不可见的(不能让用户立即看见新生成的流水号)。只有保存后POST才能看见。我想让它马上显示出新增的ID。另外本人用是access+ado是个单机的系统,求教好的方法!!!
#26
那你不能不用DBedit吗?怎么能怪到自增字段的头上呢?
其实什么DBedit,DBGrid之类的,会给你的开发带来很大的限制,想要方便,就必须放弃一定的*度,有得必有失。
其实什么DBedit,DBGrid之类的,会给你的开发带来很大的限制,想要方便,就必须放弃一定的*度,有得必有失。
#27
呵呵~~各位我已经想出来个办法了,可能比较蠢,但挺灵的,请各位指教。
//ID为ACCESS中的长整形字段,代表图书的唯一性代码
procedure TForm1.Button1Click(Sender: TObject);
var
j,k: Integer;
begin
ADOTable1.Sort:='ID ASC';
ADOTable1.First;
j:=ADOTable1['ID'];
ADOTable1.Next;
k:=ADOTable1['ID'];
while (k-j=1) do
begin
j:=k;
ADOTable1.Next;
k:=ADOTable1['ID'];
end;
Edit1.Text:=Inttostr(j+1);
//ID为ACCESS中的长整形字段,代表图书的唯一性代码
procedure TForm1.Button1Click(Sender: TObject);
var
j,k: Integer;
begin
ADOTable1.Sort:='ID ASC';
ADOTable1.First;
j:=ADOTable1['ID'];
ADOTable1.Next;
k:=ADOTable1['ID'];
while (k-j=1) do
begin
j:=k;
ADOTable1.Next;
k:=ADOTable1['ID'];
end;
Edit1.Text:=Inttostr(j+1);
#28
可能我的办法有点笨了。呵呵~~~~~自动查找到不连续的那个ID的开始处,然后插入新的ID号。
#29
identity
#1
function GetGUID:string;
var
id:tguid;
begin
if CoCreateGuid(id)=s_ok then
result:=guidtostring(id);
end;
var
id:tguid;
begin
if CoCreateGuid(id)=s_ok then
result:=guidtostring(id);
end;
#2
理论上几乎没有重复的可能。
#3
function CoCreateGuid(out guid: TGUID): HResult; stdcall; external 'ole32.dll' name 'CoCreateGuid';
#4
又学了一招!
#5
还可以在数据库后端, 定义一个触发器, 通过生成器自动生成字段.
#6
还是用触发器把
GUID太长
GUID太长
#7
在程序里写自动编号的方法
#8
formatdataTime('YYYYMMDDHHmmss',now)+inttostr(random('99999'));
#9
还有没有更好的方法???最好是生成的ID在00000000~~~99999999之间就更好了。
#10
自动编号或者用条形码
#11
没必要guid吧..
#12
求表中最大记录号。
#13
GUID 太长了,可以根据系统当前的年月日再加上时间就可以生成唯一的id了
#14
求最大记录号
#15
可以建一个表,作为流水帐号。每插入一条记录,先取流水帐号表的ID,在修改流水帐号表的ID,使它加一,这样取出来的ID号就不可能有重复的了
#16
可以建一个表,作为流水帐号。每插入一条记录,先取流水帐号表的ID,在修改流水帐号表的ID,使它加一,这样取出来的ID号就不可能有重复的了
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
#17
给我分吧,我分太少了!!
function GetNextRecNo(var ATableName,AFieldName,ACondition,
ADesFieldName:String;AFieldLen:integer):String;
var
lMax,I:Integer;
lID,lDef:String;
myQuery:TAdoQuery;
begin
lDef:= '000000000000000';
SetLength(lDef,AFieldLen-1);
myQuery:=TAdoQuery.Create(nil);
try
//---- ×Ô¶¯¼ÓÈë±àºÅ
with myQuery do
begin
SQL.Clear;
if ACondition<>'' then
SQL.Add('Select Distinct '+AFieldName+' from '+TableName+' where '+ACondition+' Order By '+ADesFieldName+' Desc')
else
SQL.Add('Select Distinct '+AFieldName+' from '+TableName+' Order By '+ADesFieldName+' Desc');
Open;
if ADesFieldName='' then ADesFieldName:=AFieldName;
if not eof then
begin
lMax:=StrToInt('0'+FieldByName(ADesFieldName).AsString);
if RecordCount=lMax then
lID:= Copy(lDef+IntToStr(RecordCount+1),Length(lDef+IntToStr(RecordCount+1))-(AFieldLen-1),AFieldLen)
else
begin
for I:=RecordCount downto 0 Do
begin
lMax:=StrToInt('0'+FieldByName(ADesFieldName).AsString);
if I=lMax then begin
lID:= Copy(lDef+IntToStr(I+1),Length(lDef+IntToStr(I+1))-(AFieldLen-1),AFieldLen);
Break;
end
else
Next;
if I=0 then lID:=lDef+'1';
end;
end;
end else
lID:=lDef+'1';
Close;
end;
Result:= lID;
finally
myQuery.Free;
end;
end;
function GetNextRecNo(var ATableName,AFieldName,ACondition,
ADesFieldName:String;AFieldLen:integer):String;
var
lMax,I:Integer;
lID,lDef:String;
myQuery:TAdoQuery;
begin
lDef:= '000000000000000';
SetLength(lDef,AFieldLen-1);
myQuery:=TAdoQuery.Create(nil);
try
//---- ×Ô¶¯¼ÓÈë±àºÅ
with myQuery do
begin
SQL.Clear;
if ACondition<>'' then
SQL.Add('Select Distinct '+AFieldName+' from '+TableName+' where '+ACondition+' Order By '+ADesFieldName+' Desc')
else
SQL.Add('Select Distinct '+AFieldName+' from '+TableName+' Order By '+ADesFieldName+' Desc');
Open;
if ADesFieldName='' then ADesFieldName:=AFieldName;
if not eof then
begin
lMax:=StrToInt('0'+FieldByName(ADesFieldName).AsString);
if RecordCount=lMax then
lID:= Copy(lDef+IntToStr(RecordCount+1),Length(lDef+IntToStr(RecordCount+1))-(AFieldLen-1),AFieldLen)
else
begin
for I:=RecordCount downto 0 Do
begin
lMax:=StrToInt('0'+FieldByName(ADesFieldName).AsString);
if I=lMax then begin
lID:= Copy(lDef+IntToStr(I+1),Length(lDef+IntToStr(I+1))-(AFieldLen-1),AFieldLen);
Break;
end
else
Next;
if I=0 then lID:=lDef+'1';
end;
end;
end else
lID:=lDef+'1';
Close;
end;
Result:= lID;
finally
myQuery.Free;
end;
end;
#18
guid
time
no++
...
time
no++
...
#19
用select count(*) as rowcount from XXXX计算表中的行数
所得结果加一
插入时用它做ID
good luck
所得结果加一
插入时用它做ID
good luck
#20
恩,呵呵~~~~~~hkbarton(→Beginner←) 的方法是个好的办法,wuxiangyang() 的方法看了半天没看懂,能给些注释吗??我感觉也有点太麻烦了,呵呵~~~~上面有人说采用条形码的方法,说仔细些???怎么样生成条形码???
#21
hkbarton(→Beginner←) 的方法我以前也用,但不能保证唯一,如果用户修改了时间呢?如果是多用户呢?
#22
miky(miky) 说的有道理。就没什么好的办法吗??继续关注。。。。。。
#23
可以建一个表,作为流水帐号。每插入一条记录,先取流水帐号表的ID,在修改流水帐号表的ID,使它加一,这样取出来的ID号就不可能有重复的了
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
----
完全同意
GUID太长了,自增字段问题多多。用时间既不安全,也有些长,影响效率。
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
----
完全同意
GUID太长了,自增字段问题多多。用时间既不安全,也有些长,影响效率。
#24
可以建一个表,作为流水帐号。每插入一条记录,先取流水帐号表的ID,在修改流水帐号表的ID,使它加一,这样取出来的ID号就不可能有重复的了
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
----
这不正是自增字段为我们做的吗?
我不明白自增字段有什么问题,我觉得非常好用。
只有一种情况,就是你有多个不连网的客户端,为了保证他们的数据ID也不重复,这时候才不能用。
-----------------------------------------------------------对的
如果是并发的可以用存储过程来控制生成
过程实现的:计算最大id,更新表id=id+1,返回最大id+1给客户端程序
----
这不正是自增字段为我们做的吗?
我不明白自增字段有什么问题,我觉得非常好用。
只有一种情况,就是你有多个不连网的客户端,为了保证他们的数据ID也不重复,这时候才不能用。
#25
自增字段在用DBEdit开发时,如果你调用了ADOTable.Append;方法后,该DBEdit上Text内容是不可见的(不能让用户立即看见新生成的流水号)。只有保存后POST才能看见。我想让它马上显示出新增的ID。另外本人用是access+ado是个单机的系统,求教好的方法!!!
#26
那你不能不用DBedit吗?怎么能怪到自增字段的头上呢?
其实什么DBedit,DBGrid之类的,会给你的开发带来很大的限制,想要方便,就必须放弃一定的*度,有得必有失。
其实什么DBedit,DBGrid之类的,会给你的开发带来很大的限制,想要方便,就必须放弃一定的*度,有得必有失。
#27
呵呵~~各位我已经想出来个办法了,可能比较蠢,但挺灵的,请各位指教。
//ID为ACCESS中的长整形字段,代表图书的唯一性代码
procedure TForm1.Button1Click(Sender: TObject);
var
j,k: Integer;
begin
ADOTable1.Sort:='ID ASC';
ADOTable1.First;
j:=ADOTable1['ID'];
ADOTable1.Next;
k:=ADOTable1['ID'];
while (k-j=1) do
begin
j:=k;
ADOTable1.Next;
k:=ADOTable1['ID'];
end;
Edit1.Text:=Inttostr(j+1);
//ID为ACCESS中的长整形字段,代表图书的唯一性代码
procedure TForm1.Button1Click(Sender: TObject);
var
j,k: Integer;
begin
ADOTable1.Sort:='ID ASC';
ADOTable1.First;
j:=ADOTable1['ID'];
ADOTable1.Next;
k:=ADOTable1['ID'];
while (k-j=1) do
begin
j:=k;
ADOTable1.Next;
k:=ADOTable1['ID'];
end;
Edit1.Text:=Inttostr(j+1);
#28
可能我的办法有点笨了。呵呵~~~~~自动查找到不连续的那个ID的开始处,然后插入新的ID号。
#29
identity