问题没解决。再次发问。。。(200分)

  • 主题发起人 主题发起人 少爷的拐杖
  • 开始时间 开始时间

少爷的拐杖

Unregistered / Unconfirmed
GUEST, unregistred user!
代码如下:
procedure TForm7.SpeedButton7Click(Sender: TObject);
var
i,loop:integer;
begin
if application.MessageBox('可以将出库清单中的药品入二级库吗?','药品出库登记',mb_yesno+mb_iconquestion)=6 then
begin
loop:=ListView2.Items.Count-1;
Form1.Database1.StartTransaction;
try
for i:=0 to loop do
begin
showmessage('当前行号'+inttostr(i));
//修改基本药品库
UpData_Xiyao_ku_out.ParamByName('库存').AsInteger:=StrToInt(Listview2.Items.Item.SubItems.Strings[4]);
UpData_Xiyao_ku_out.ParamByName('OLD_药品名称').AsString:=Listview2.Items.Item.Caption;
UpData_Xiyao_ku_out.ParamByName('OLD_规格').AsString:=Listview2.Items.Item.SubItems.Strings[0];
UpData_Xiyao_ku_out.ParamByName('OLD_单位').AsString:=Listview2.Items.Item.SubItems.Strings[1];
//======这里有错误,注释掉excesql后能完成循环======
Updata_Xiyao_ku_out.ExecSQL;
//登记出库单据
Updata_Xiyao_out.ParamByName('药品名称').AsString:=ListView2.Items.Item.Caption;
Updata_Xiyao_out.ParamByName('规格').AsString:=Listview2.Items.Item.SubItems.Strings[0];
Updata_Xiyao_out.ParamByName('单位').AsString:=Listview2.Items.Item.SubItems.Strings[1];
Updata_Xiyao_out.ParamByName('批发价').AsFloat:=StrToFloat(Listview2.Items.Item.SubItems.Strings[2]);
Updata_Xiyao_out.ParamByName('零售价').AsFloat:=StrToFloat(Listview2.Items.Item.SubItems.Strings[3]);
Updata_Xiyao_out.ParamByName('出库数量').AsInteger:=StrToInt(Listview2.Items.Item.SubItems.Strings[4]);
Updata_Xiyao_out.ParamByName('药品去向').AsString:=Listview2.Items.Item.SubItems.Strings[5];
Updata_Xiyao_out.ParamByName('出库日期').AsDateTime:=StrToDate(Listview2.Items.Item.SubItems.Strings[6]);
Updata_Xiyao_out.ExecSQL;
//修改二级药品库
Query_Set.Close;
Query_Set.SQL.Clear;
Query_Set.SQL.Add('select count(药品名称) from XiYao_ku_Second');
Query_Set.SQL.Add('where 药品名称='''+ListView2.Items.Item.Caption+'''');
Query_Set.SQL.Add('and 规格='''+Listview2.Items.Item.SubItems.Strings[0]+'''');
Query_Set.SQL.Add('and 单位='''+Listview2.Items.Item.SubItems.Strings[1]+'''');
Query_Set.Open;
if Query_Set.Fields.Fields[0].AsInteger>0 then
begin //药品已经存在,修改数据
Updata_Query_Second.Close;
Updata_Query_Second.SQL.Clear;
Updata_Query_Second.SQL.Text:=ListBox2.Items.Strings[0];
Updata_Query_Second.ParamByName('OLD_药品名称').AsString:=Listview2.Items.Item.Caption;
Updata_Query_Second.ParamByName('OLD_规格').AsString:=Listview2.Items.Item.SubItems.Strings[0];
Updata_Query_Second.ParamByName('OLD_单位').AsString:=Listview2.Items.Item.SubItems.Strings[1];
end
else //药品不存在,新增加数据
begin
Updata_Query_Second.Close;
Updata_Query_Second.SQL.Clear;
Updata_Query_Second.SQL.Text:=Listbox2.Items.Strings[1];
end;
Updata_Query_Second.ParamByName('药品名称').AsString:=ListView2.Items.Item.Caption;
Updata_Query_Second.ParamByName('规格').AsString:=Listview2.Items.Item.SubItems.Strings[0];
Updata_Query_Second.ParamByName('单位').AsString:=Listview2.Items.Item.SubItems.Strings[1];
Updata_Query_Second.ParamByName('库存').AsInteger:=StrToInt(Listview2.Items.Item.SubItems.Strings[4]);
Updata_Query_Second.ParamByName('批发价').AsFloat:=StrToFloat(Listview2.Items.Item.SubItems.Strings[2]);
Updata_Query_Second.ParamByName('零售价').AsFloat:=StrToFloat(Listview2.Items.Item.SubItems.Strings[3]);
Updata_Query_Second.ParamByName('有效期').AsDateTime:=StrToDate(Listview2.Items.Item.SubItems.Strings[7]);
Updata_Query_Second.ParamByName('拥有单位').AsString:=Listview2.Items.Item.SubItems.Strings[5];
Updata_Query_Second.ParamByName('类别').AsString:=Listview2.Items.Item.SubItems.Strings[8];
//======这里有错误,注释掉excesql后能完成循环======
Updata_Query_Second.ExecSQL;
end;
Form1.Database1.Commit;
except //写入时发生错误
Form1.Database1.Rollback;
showmessage('错误!');
exit;
end;
ListView2.Items.Clear;
end;
end;

错误的部分我找到了。可是奇怪的是我把那出错的部分单独放到一个循
环里执行却又什么毛病没有了。连在一起执行就出错。现象是没有任何
错误信息,光标显示“漏斗”
另外,如果这整段代码中的循环只执行一次的话正确。执行两次或两次
以上则出现“漏斗”单独执行某个更新操作又结果正确。
百思不得其解!
 
你把Form1.Database1.StartTransaction;之类关于事务代码去掉看看。
另请仔细检查你的sql语句,及字段名,参数名,参数是不是可以换成英文的试试?
再则出错的代码及错误信息是什么?
 
to sonie:
要是有出错的代码和错误信息就好啦。问题就是什么都不发生。循环第一次正确完成后
就僵死在第二次循环上。显示一个系统忙的光标,程序就没响应了。windows没死。
另外。此段代码中有三个更新表的段落。我分离出来放到循环中执行结果正确。
所以我想sql语句大概没有问题。否则单独执行也会出现错误的。
只是三个同时放到循环中就会“僵死”。还请各位多多帮忙。
 
看看三个同时放到循环中就会“僵死”时,数据库是不是死锁?
 
to wind_cloudy:
现在只有我一个人在用。

三个更新的语句是这样的:
===1===
update xiyao_ku
set
库存 = 库存-:库存
where
药品名称 = :OLD_药品名称 and
规格 = :OLD_规格 and
单位 = :OLD_单位

===2===
insert into xiyao_ku_out
(药品名称, 规格, 单位, 批发价, 零售价, 出库数量, 出库日期, 药品去向)
values
(:药品名称, :规格, :单位, :批发价, :零售价, :出库数量, :出库日期, :药品去向)

===3===
update XiYao_ku_Second
set
类别 = :类别,药品名称 = :药品名称, 规格 = :规格,
单位 = :单位, 库存 = 库存+:库存, 批发价 = :批发价,
零售价 = :零售价, 有效期 = :有效期,
拥有单位 = :拥有单位
where
药品名称 = :OLD_药品名称
and 规格 = :OLD_规格
and 单位 = :OLD_单位

insert into XiYao_ku_Second
(药品名称,规格,单位,库存,批发价,零售价,有效期,拥有单位,类别)
values
(:药品名称,:规格,:单位,:库存,:批发价,:零售价,:有效期,:拥有单位,:类别)
数据库是sql7+sp1
d5三个补丁打全了。
奇怪啊!!
看不出来那儿有问题啊。

 
我认为可能有两个问题
1.关于事务的代码写在循环内(你的事务不会是要完成整个循环吧?)
2.是不是你的后台设置了锁级别为表锁,应改为行锁。(第一次写后设置了表锁,第二次就只能死等了,
当然事务commit后就解除了,所以第一种方法是值得一试的)
 
代码太长,累,简明扼要一点。
 
我本意是要循环完全结束后提交事务。
否则如果循环中出现错误将会出现提交了几个记录但是余下几个没有被提交的情况。

现在问题已经解决。我把所有执行更新的TQuery都换成了一个,每次动态付给sql语句。
就能正确执行了。

但是为什么出现这样的问题呢?能给出答案的还是给200分。
 
因为你在事务中间使用了查询,当使用太多的时候,由于SQL SERVER要维护QUERY 的游标
因此十分容易发生不确定的死锁:
可以如下处理
//循环
//依条件生成 SQL 语句 加入 TSTRINGLIST 串
//开始事务
//提交SQL
//结束事务
 
这么复杂的事务处理还是放到存储过程里比较好
 
为什么我用一个Query,每次清空内容然后添加语句执行更新就可以执行了呢?
同样的循环,同样的更新操作,一个Query就可以。三个事先写好Sql语句的Query就出错。
没有道理啊?
为什么?

本问题7月8日前结束。请各位大侠给我个答案。
 
多人接受答案了。
 
本人也遇到这个情况,代码在access里一切正常,可是到sql server 2000里程序好象进行
死循环一样,
 
后退
顶部