执行存储过程错误(1000分)

henrynj 2003-10-20 04:13:49
我在程序里有一个serversocket侦听5100端口

当收到报文请求时 就创建一个线程
SocketThread := TServerThread.Create(False, ClientSocket);

这个线程会有选择地执行存储过程
前n次好好的,到了n+1次时就会出来一个

access violatino at address 4be345a0 in modulo 'idapi32.dll'

一旦出现这个错误就完了

{******************************************************
* 作者:*****
* 日期:20030805
* 功能:socket线程类
* 此线程当用户请求时启动用来执行存储过程并将结果返回用户
*******************************************************
}
type
TServerThread = class(TServerClientThread)
private
strLength : integer ; //报文长度
strTradeCode : string ; //交易码
strSerNO : string ; //流水号
strParameters : string ; //参数
strReturn : string ; //返回值

Msg : string;
public
procedure ClientExecute; override ; //主控
procedure WriteLog; //写日志
procedure Trade7301; //7301交易
procedure Trade7302; //7302交易
procedure Trade7303; //7303交易
procedure Trade7304; //7304交易
end;


以下是用于执行存储过程的语句
procedure TServerThread.Trade7301;
var
I:integer;
handleresult,amount,note:string;
iLoop,iNum:integer;
cErrorMsg : string;
begin
with dmglobal.StoredProc7301 do
try
ParamByName('TRANSTYPE').Value := NULL;
ParamByName('UID').AsString := copy(strParameters,9,6);
ParamByName('BANKCODE').Value := NULL;
ParamByName('SAVINGACCOUNT').Value := NULL;
ParamByName('PAYTRANSCODE').Value := NULL;
ParamByName('CONTRACTNO').AsString := copy(strParameters,1,8);
ParamByName('AMOUNT').AsString := ''; //output
ParamByName('MONEYTYPE').Value := NULL;
ParamByName('AS400SERIAL').Value := NULL;
ParamByName('PID').Value := NULL;
ParamByName('PAYSERIAL').Value := NULL;
ParamByName('TRANSTIME').Value := NULL;
ParamByName('STOCKTRANSPIN').Value := NULL;
ParamByName('CRYPTOGRAM').Value := NULL;
ParamByName('HANDLERESULT').AsString := ''; //output
ParamByName('OLDBALANCE').Value := NULL;
ParamByName('NOTE').AsString := ''; //output
if not Prepared then Prepare;

ExecProc;

handleresult := copy(ParamByName('handleresult').AsString,1,2);

if (handleresult='99') or (handleresult='21') then //99成功 //21 已缴费
begin
amount := copy(ParamByName('amount').AsString,1,13);
note := ParamByName('note').AsString;

while length(amount)<13 do amount:='0'+amount;
if copy(note,131,4)='未销' then note:=copy(note,1,134)+' '+copy(note,135,5); //未销


if length(note)<147 then
begin
handleresult:='04';
amount:= '0000000000000';
note:='';
for I:=0 to 147 do note:=note+'0';
self.strReturn:='0174'+strSerNO+handleresult+amount+note;
Msg := '返回码note长度不够'+note;
exit;
end;

self.strReturn:='0174'+strSerNO+handleresult+amount+note;
Msg := '交易成功.';
Close;
end else
if (handleresult='39') or (handleresult='40') or (handleresult='03') then //39气费为0 //40超期 //03无此户号
begin
amount:= '0000000000000';
note:='';
for I:=0 to 147 do note:=note+'0';
self.strReturn:='0174'+strSerNO+handleresult+amount+note;
Msg := '39气费为0 40超期 03无此户号.';
end else
begin
handleresult := '06';
amount := '0000000000000';
note:='';
for I:=0 to 147 do note:=note+'0';
self.strReturn:='0174'+strSerNO+handleresult+amount+note; //未知返回码handleresult
Msg := '未知返回码'+handleresult;
end;
except
on E: Exception do
begin
handleresult:='00';
amount:= '0000000000000';
note:='';
for I:=0 to 147 do note:=note+'0';
self.strReturn:='0174'+strSerNO+handleresult+amount+note;

Msg := '执行后台oracle存储过程QUERYBAL时遇到一个错误.错误信息:'+E.Message;
WriteLog;

if pos('address',E.Message)>0 then
begin
clientsocket.SendText(strReturn);
Msg := '致命错误,异常ODBC连接!系统退出!';
WriteLog;
halt(0);
end;

if (E is EDBEngineError) then
begin
iNum:=(E as EDBEngineError).ErrorCount; // 取错误的总数
// 循环取每个错误的号和信息
for iLoop:=0 to iNum-1 do
begin
cErrorMsg := (E as EDBEngineError).Errors[iLoop].Message; //取错误号
if pos('ORA-03114',cErrorMsg)>0 then
begin
Msg := '数据库失去连接,系统将尝试重新连接oracle数据库...';
WriteLog;

if not frmmain.ConnectOracle then
begin
Msg := '重新连接oracle数据库失败,系统稍候将会重新连接.';
WriteLog;
end
else
begin
Msg := '重新连接oracle数据库成功.';
WriteLog;

try
if not Prepared then Prepare;
ExecProc;

handleresult := copy(ParamByName('handleresult').AsString,1,2);

if (handleresult='99') or (handleresult='21') then //99成功 //21 已缴费
begin
amount := copy(ParamByName('amount').AsString,1,13);
note := ParamByName('note').AsString;

while length(amount)<13 do amount:='0'+amount;
if copy(note,131,4)='未销' then note:=copy(note,1,134)+' '+copy(note,135,5); //未销


if length(note)<147 then
begin
handleresult:='04';
amount:= '0000000000000';
note:='';
for I:=0 to 147 do note:=note+'0';
self.strReturn:='0174'+strSerNO+handleresult+amount+note;
Msg := '返回码note长度不够'+note;
exit;
end;

self.strReturn:='0174'+strSerNO+handleresult+amount+note;
Msg := '交易成功.';
Close;
end else
if (handleresult='39') or (handleresult='40') or (handleresult='03') then //39气费为0 //40超期 //03无此户号
begin
amount:= '0000000000000';
note:='';
for I:=0 to 147 do note:=note+'0';
self.strReturn:='0174'+strSerNO+handleresult+amount+note;
Msg := '39气费为0 40超期 03无此户号.';
end else
begin
handleresult := '06';
amount := '0000000000000';
note:='';
for I:=0 to 147 do note:=note+'0';
self.strReturn:='0174'+strSerNO+handleresult+amount+note; //未知返回码handleresult
Msg := '未知返回码'+handleresult;
end;
except
on E: Exception do
begin
handleresult:='00';
amount:= '0000000000000';
note:='';
for I:=0 to 147 do note:=note+'0';
self.strReturn:='0174'+strSerNO+handleresult+amount+note;

Msg := '执行后台oracle存储过程QUERYBAL时遇到一个错误.错误信息:'+E.Message;
WriteLog;
end;
end;
end;
end;
end;
end;
end;
end;
end;
...全文
75 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
henrynj 2003-10-20
  • 打赏
  • 举报
回复
stThreadBlocking
aiirii 2003-10-20
  • 打赏
  • 举报
回复
clientsocket 等是否為阻塞??? 懷疑是處理過程阻塞, 或過長, 後一個線程又創建, 引起衝突!!
henrynj 2003-10-20
  • 打赏
  • 举报
回复
{ TServerThread }

procedure TServerThread.ClientExecute;
var
Stream: TWinSocketStream;
strIn: string;
handleresult,amount,note:string;
I:integer;
begin
FreeOnTerminate:=true;
while (not Terminated) and ClientSocket.Connected do
begin
try
Stream := TWinSocketStream.Create(ClientSocket, timeout);
try
setlength(strIn,57);
if Stream.WaitForData(timeout) then
begin
if Stream.Read(strIn[1], 57) = 0 then { if can't read in 60 seconds }
begin
if ClientSocket.Connected then ClientSocket.Close;
exit;
end
else
begin
try // 处理请求
strLength := StrToInt (Copy (strIn, 1, 4));
except
Msg := '报文内容前4位无法转换成数值类型.';
Synchronize(WriteLog);

StrTradeCode := Copy (strIn, 5, 4);
strSerNO := Copy (strIn, 9, 8);

while length(strSerNO)<8 do strSerNO:=strSerNO+'0';
{拼装}
handleresult := '05';
amount := '0000000000000';
note := '';
for I:=0 to 147 do note:=note+'0';
if StrTradeCode='7301' then clientsocket.SendText('0174'+strSerNO+handleresult+amount+note)
else if StrTradeCode='7302' then clientsocket.SendText('0014'+strSerNO+handleresult)
else if StrTradeCode='7303' then clientsocket.SendText('0014'+strSerNO+handleresult)
else if StrTradeCode='7304' then clientsocket.SendText('0014'+strSerNO+handleresult)
else clientsocket.SendText('0014'+strSerNO+handleresult); //报文内容前4位无法转换成数值类型

if ClientSocket.Connected then ClientSocket.Close;
exit;
end;

if length(strIn)<strLength then
begin
Msg := '接收报文长度小于指定长度.';
Synchronize(WriteLog);

StrTradeCode := Copy (strIn, 5, 4);
strSerNO := Copy (strIn, 9, 8);

while length(strSerNO)<8 do strSerNO:=strSerNO+'0';
handleresult := '04';
amount := '0000000000000';
note := '';
for I:=0 to 147 do note:=note+'0';
if StrTradeCode='7301' then clientsocket.SendText('0174'+strSerNO+handleresult+amount+note)
else if StrTradeCode='7302' then clientsocket.SendText('0014'+strSerNO+handleresult)
else if StrTradeCode='7303' then clientsocket.SendText('0014'+strSerNO+handleresult)
else if StrTradeCode='7304' then clientsocket.SendText('0014'+strSerNO+handleresult)
else clientsocket.SendText('0014'+strSerNO+handleresult); //接收报文长度小于指定长度

if ClientSocket.Connected then ClientSocket.Close;
exit;
end;

StrTradeCode := Copy (strIn, 5, 4);
strSerNO := Copy (strIn, 9, 8);
strParameters := copy (strIn, 17, strLength-16);

Msg := '交易代码: ' + strTradeCode;
Synchronize(WriteLog); //写日志

Msg := '交易流水号: ' + strSerNO;
Synchronize(WriteLog); //写日志

Msg := '交易参数: ' + strParameters;
Synchronize(WriteLog); //写日志

if strTradeCode = '7301' then
begin
if length(strParameters)<14 then
begin
Msg := '所请求的交易参数不足.';
Synchronize(WriteLog); //写日志

while length(strSerNO)<8 do strSerNO:=strSerNO+'0';
handleresult := '01';
amount := '0000000000000';
note := '';
for I:=0 to 147 do note:=note+'0';

clientsocket.SendText('0174'+strSerNO+'05'+handleresult+amount+note);
if ClientSocket.Connected then ClientSocket.Close;
exit;
end;
Synchronize(Trade7301);
end
else if strTradeCode = '7302' then
begin
if length(strParameters)<41 then
begin
Msg := '所请求的交易参数不足.';
Synchronize(WriteLog); //写日志

handleresult := '01';

clientsocket.SendText('0014'+strSerNO+handleresult); //所请求的交易参数不足,系统将强行中断该连接.
if ClientSocket.Connected then ClientSocket.Close;
exit;
end;
Synchronize(Trade7302);
end
else if strTradeCode = '7303' then
begin
if length(strParameters)<41 then
begin
Msg := '所请求的交易参数不足.';
Synchronize(WriteLog); //写日志

handleresult := '01';

clientsocket.SendText('0014'+strSerNO+handleresult); //所请求的交易参数不足,系统将强行中断该连接.
if ClientSocket.Connected then ClientSocket.Close;
exit;
end;
Synchronize(Trade7303);
end
else if strTradeCode = '7304' then
begin
if length(strParameters)<41 then
begin
Msg := '所请求的交易参数不足.';
Synchronize(WriteLog); //写日志

handleresult := '01';

clientsocket.SendText('0014'+strSerNO+handleresult); //所请求的交易参数不足,系统将强行中断该连接.
if ClientSocket.Connected then ClientSocket.Close;
exit;
end;
Synchronize(Trade7304);
end
else
begin
Msg := '无此交易.';
Synchronize(WriteLog); //写日志
handleresult := '02';
clientsocket.SendText('0014'+strSerNO+handleresult); //无此交易,系统将强行中断该连接.
if ClientSocket.Connected then ClientSocket.Close;
exit;
end;

// 返回处理结果
clientsocket.SendText(strReturn);
Synchronize(WriteLog);
if ClientSocket.Connected then ClientSocket.Close;
end;
end
else
begin
ClientSocket.Close; { if client doesn't start, close }
end;
finally
Stream.Free;
Terminate;
end;
except
on E: Exception do
begin
Msg := '运行时错误,错误信息:'+E.Message;
Synchronize(WriteLog);
Terminate;
end;
end;
end;
end;
tiexinliu 2003-10-20
  • 打赏
  • 举报
回复
估计是线程使用后资源没释放的缘故,

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧