假定表A为客户表,字段有:ID,NAME
有一个下拉框,里面为新客户名称的列表:cbxNew
现在想把这个下拉列表中的客户名称批量导入表A,同时为每个新客户自动生成ID,代码如下:ADOConnection.BeginTrans;
try
for i:=0 to cbxNew.Items.Count-1 do
with ado do
begin
Append;
FieldByName('ID').AsString := GetID;//自动生成ID的一个函数
FieldByName('NAME').AsString := cbxNew.Items[i];
Post;
end;
ADOConnection.CommitTrans;
except
ADOConnection.RollbackTrans;
end;我发现,如果这样做的话,插入第一条记录后就锁死了,去掉事务正常,将GetID函数改为常量也正常。研究了一下,可能原因就在于GetID这个函数,因为生成ID需要读取表A中的字段ID,使用事务后,第一条记录虽然post了,但并未生效,致使函数在读取ID字段时对新插入的记录的处理出现问题。现在问题就是,在使用事务的时候,如果在对一个表进行插入记录的同时,又需要不断读取该表某个字段,该如何处理呢?
有一个下拉框,里面为新客户名称的列表:cbxNew
现在想把这个下拉列表中的客户名称批量导入表A,同时为每个新客户自动生成ID,代码如下:ADOConnection.BeginTrans;
try
for i:=0 to cbxNew.Items.Count-1 do
with ado do
begin
Append;
FieldByName('ID').AsString := GetID;//自动生成ID的一个函数
FieldByName('NAME').AsString := cbxNew.Items[i];
Post;
end;
ADOConnection.CommitTrans;
except
ADOConnection.RollbackTrans;
end;我发现,如果这样做的话,插入第一条记录后就锁死了,去掉事务正常,将GetID函数改为常量也正常。研究了一下,可能原因就在于GetID这个函数,因为生成ID需要读取表A中的字段ID,使用事务后,第一条记录虽然post了,但并未生效,致使函数在读取ID字段时对新插入的记录的处理出现问题。现在问题就是,在使用事务的时候,如果在对一个表进行插入记录的同时,又需要不断读取该表某个字段,该如何处理呢?
应该可以不用每次读数据库的
SELECT max(ID) FROM tablename WITH(NOLOCK)
begin
Result := 0;
while ado.Locate('ID',Result,[loCaseInsensitive])
Result := Result + 1;
end;
这是个例子,实际代码复杂一些,但原理一致
我建议你不如直接找MAX(ID),这样最简单,至于函数也不用了,批量更新前找到已用的最大ID,赋给变量i,更新的时候inc(i)就可以了
看来就是因为启用了事务而导致表锁死,谢谢各位!
begin
Append; //处于dsInsert状态
FieldByName('ID').AsString := GetID;//自动生成ID的一个函数
FieldByName('NAME').AsString := cbxNew.Items[i];
Post;
end;ado.Locate 你又用这个来定位,有问题,Locate之后
ado结果集已经定位到其他记录了.
有道理,如果你的ID必须查询数据库才能得到,建议用sql语句,用insert