在C/S模式下:
我做企业单据录入的摸块时, 其中有个"单据号"的字段是我软件里面自动生成的,
我的方法是这样的:
1,从数据库该表里面取"单据号"最大的一条记录,然后将他的"单据号"加上1,作为
新的单据.(也就是用户在点"新建"按钮的时候,我自动生成一个新的单据号).这种方式如果多个用户使用的时候会出现错误,
比如:两个用户同时操作的时候,他们获得的单据号都是一样的,
谁先保存单据的人能成功,后者就会出现关键字重复了,
因为这张单据现在已经存在了!弟兄们,有什么好的办法解决啊?我用的是DELPHI6+SERVER7.0,
我听说这种可以在SQLSERVER端控制的,
也搞不清楚了,大家帮忙啊!!!
我做企业单据录入的摸块时, 其中有个"单据号"的字段是我软件里面自动生成的,
我的方法是这样的:
1,从数据库该表里面取"单据号"最大的一条记录,然后将他的"单据号"加上1,作为
新的单据.(也就是用户在点"新建"按钮的时候,我自动生成一个新的单据号).这种方式如果多个用户使用的时候会出现错误,
比如:两个用户同时操作的时候,他们获得的单据号都是一样的,
谁先保存单据的人能成功,后者就会出现关键字重复了,
因为这张单据现在已经存在了!弟兄们,有什么好的办法解决啊?我用的是DELPHI6+SERVER7.0,
我听说这种可以在SQLSERVER端控制的,
也搞不清楚了,大家帮忙啊!!!
我现在就是在客户端用CreateGuid来得到数据库表中的新增记录的主键值,巨好使!其实你说的问题也困扰我很长时间的,呵呵。
(*******************************************************************************
* 函数名:GetAutoCode
*
* 函数说明: 根据数据库中的表内容,取得一个比原来记录最大的编号+1的值
*
* 参数说明:
* ADOConnection1 :对数据进行查询的数据库连接
* TableName :需要读取的表的名称
* Column :需要读取的字段的名称
* CurrDate :编号左边的固定值,取的是服务器的当前日期
* CodeLen :编号长度
*******************************************************************************)
function GetAutoCode(ADOConnection1 : TADOConnection; Table_str : string; Column_str : string ; CurrDate_str : String; CodeLen : integer) : string;
var
tmpNum,i : integer;
MaxBillNo, tmpMax : String;
tmp_format : array[0..20] of char;
ADOdatasettmp : TADODataSet;
begin
ADOdatasettmp := TADODataSet.Create(nil);
ADOdatasettmp.Connection := ADOConnection1;
FillChar(tmp_format, CodeLen, '0');
ADOdatasettmp.CommandText := 'select max(' + Column_str + ') MaxBillNO from ' + Table_str + ' where ' + Column_str + ' like''' + CurrDate_str + '%''' ;
ADOdatasettmp.Open;
MaxBillNo := ADOdatasettmp.FieldByName('MaxBillNO').AsString;
if MaxBillNo<>'' then
begin
tmpMax := copy(MaxBillNo,9,length(MaxBillNo) - 8);
tmpNum := StrToInt(tmpMax) + 1;
tmpMax := InttoStr(tmpNum);
end
else
tmpMax := '1';
tmpMax := copy(tmp_format,1,CodeLen - 8 - length(tmpMax)) + tmpMax;
Result := CurrDate_str + tmpMax;
end;
我生成的单据号的格式如下;200212200001前四位:前八位刚好是日期:2002年12月20号,
后面五位是序号,
单据号的字段类型是"char"的,
我不知道你方法是写代码实现的!
将单据编码在中间服务器中生成,响应DataProvider.BeforeUpdateRecord事件。下面是我以前程序中的代码,和你的情况差不多,不过用了两个字段做主键,共参考(Delphi5的,高版本事件的参数有些不一样):
procedure TZfInfoServer.NewProviderBeforeUpdateRecord(Sender: TObject;
SourceDS: TDataSet; DeltaDS: TClientDataSet; UpdateKind: TUpdateKind;
var Applied: Boolean);
begin
// 如果客户程序插入信息记录同时未设定主键,
// 从主窗口获取唯一的记录主键(发送时间和当日记录序号)
if (UpdateKind = ukInsert) and (DeltaDS.FieldByName('NUM').Asinteger <= 0)
begin
DeltaDS.Edit;
DeltaDS.FieldByName('NUM').AsInteger := ServerMainForm.RecNumber;
DeltaDS.FieldByName('SENDDATE').AsDateTime := ServerMainForm.SendDate;
end;
end;
谢谢你提供的涵数,
生成单据号的代码我自己写了一个,不过没你的通用简洁
不过你这里还是解决不了我的问题的,
因为比如两个用户,照你的生成单据号的方法,他们申请到的单据号应该是一样的,
如果已经存在就重新生成一个单据号,如果没有的话就最好!!
各位觉的这方法可行吗?怎么样啊?