调用ADO存储过程(SQL SERVER2000)第一次没问题,第二次就出错,晕!!!

SeaFish 2003-10-16 12:02:05
调用过程:
//执行存储过程
try
{
//关闭存储过程对象
pSmsMT->m_pADOSP->Close();
pSmsMT->m_pADOSP->ProcedureName = "cp_AfterSend";
pSmsMT->m_pADOSP->Parameters->Refresh();
pSmsMT->m_pADOSP->Parameters->ParamByName("@IdMap")->DataType = ftString;
pSmsMT->m_pADOSP->Parameters->ParamByName("@IdMap")->Value = strRSMap;
pSmsMT->m_pADOSP->Parameters->ParamByName("@MaxSendId")->DataType = ftLargeint;
pSmsMT->m_pADOSP->Parameters->ParamByName("@MaxSendId")->Value = 0;
pSmsMT->m_pADOSP->Prepared = true;
pSmsMT->m_pADOSP->ExecProc();
}
catch(...)
{
//记录错误日志
pSmsMT->m_pLogFile->AddLine(CLogFile::EP_FATAL_ERROR,"执行存储过程cp_AfetrSend失败!");

}

存储过程:


ALTER proc cp_AfterSend
@IdMap varchar(256),
@MaxSendId bigint OUTPUT
/*
返回:
如果成功返回 0,失败返回负数
*/

AS
DECLARE
@strIdMap varchar(256),
@Rid bigint,
@nPkg smallint,
@nBegin bigint,
@nPos int,
@nPos1 int,
@nPos2 int,
@i int,
@nRet int

set @nRet = 0
set @strIdMap = @IdMap
set @MaxSendId = -1

WHILE(LEN(@strIdMap) > 0)
BEGIN
/*先分解参数*/
set @nPos = CHARINDEX('#',@strIdMap,1)
set @nPos1 = CHARINDEX('*',@strIdMap,1)
set @nPos2 = CHARINDEX(',',@strIdMap,1)

set @Rid = CONVERT(int,SUBSTRING(@strIdMap,1,@nPos-1))
set @nPkg = CONVERT(int,SUBSTRING(@strIdMap,@nPos+1,@nPos1-@nPos-1))
set @nBegin = CONVERT(smallint,SUBSTRING(@strIdMap,@nPos1+1,@nPos2-@nPos1-1))

set @strIdMap = STUFF(@strIdMap,1,@nPos2,NULL)

--更新数据库
begin tran
-- 从 Wait表复制到Sending表
insert into tSentlog_sending select * from tSentLog_wait where RandId = @Rid
if @@error <> 0 OR @@rowcount =0
goto ERR
-- 更新SentTime,ItemCount字段
update tSentLog_sending set SentTime = GetDate(),ItemCount = @nPkg where RandId = @Rid
if @@error <> 0 OR @@rowcount =0
goto ERR
-- 删除Wait表中原记录
delete tSentLog_wait where RandId = @Rid
if @@error <> 0 OR @@rowcount =0
goto ERR
-- 建立RandId 与 SendId 映射关系
set @i = 0
while(@i < @nPkg)
begin
insert into tRandIdMap(SendId,RandId) values(@nBegin+@i,@Rid)
if @@error <> 0 OR @@rowcount =0
goto ERR
else
set @i = @i+1
end
commit tran
continue
ERR:
rollback tran
set @nRet = -1
END
-- 退出前取SendId 字段的最大值`
set @MaxSendId = @@identity
RETURN @nRet
...全文
127 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
delphiseabird 2003-10-17
  • 打赏
  • 举报
回复
结贴吧兄弟
Alanwn 2003-10-17
  • 打赏
  • 举报
回复
up
mxk19791116 2003-10-17
  • 打赏
  • 举报
回复
用另一种方法,实现同一种效果,这是非常好的一种解决方法。

恭喜!
wuzongjie 2003-10-17
  • 打赏
  • 举报
回复
首先要清空參數,
pSmsMT->m_pADOSP->Parameters->Clear!!!!
kevin218 2003-10-17
  • 打赏
  • 举报
回复
我笔记本上装不了sqlserver,没办法现场给你调试;不过看你的error提示,数据库装的可能有点问题,不能排除掉;
你那个调用procedure的模块程序也有点问题,try应该没写完吧;我有个例子你看看:
……
// 调用存储过程
// procEmployeeNo.StoredProcName := 'PROEMPLOYEENO';
// procEmployeeNo.Params.Clear ;
// procEmployeeNo.Params.CreateParam(ftString, 'SYEAR', ptInput) ;
// procEmployeeNo.Params.CreateParam(ftString, 'RETURNEMPLOYEENO', ptOutput) ;

// 创建并调用函数
adofunDispatchId:= TADOStoredProc.Create(nil);
adofunDispatchId.ProcedureName :='funGetSendDocId';
adofunDispatchId.ConnectionString:='Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=PubDoc;Data Source=localhost';

adofunDispatchId.Parameters.CreateParameter('@RETURN_VALUE',ftString,pdReturnValue,50,0);
adofunDispatchId.Parameters.CreateParameter('@ParaId',ftString,pdInput,50,0);
adofunDispatchId.Parameters.CreateParameter('@ParaDate',ftString,pdInput,10,0);

if adofunDispatchId.Active then adofunDispatchId.Close;
adofunDispatchId.Parameters[1].Value:=sPlace;
adofunDispatchId.Parameters[2].Value:=sYear;
try
adofunDispatchId.ExecProc;
edtDispatchId.Text:= adofunDispatchId.Parameters.ParamByName('@RETURN_VALUE').Value;
//edtDispatchId.Text:=adofundispatchId.Parameters[0].Value;
//showmessage(adofundispatchId.Parameters[0].Value);
edtNum.Text:=copy(edtDispatchId.Text,(length(sPlace)+length(sYear)+2+1),(length(edtDispatchId.Text)-length('号')));
edtNum.Text:=copy(edtNum.Text,1,length(edtNum.text)-2);
except
Application.MessageBox(pchar('产生函数有错,请重试'), '提示', MB_OK);
exit;
end;
……
首先要保证自己的存储过程在后台调试测试正确,才能在前台调用成功;
再一个是,调用函数或存储过程的时候,最好是自己定义控件,直接引用常常出错,这个原因我也解释不了。你试试
SeaFish 2003-10-17
  • 打赏
  • 举报
回复
wuzongjie(吴飞) :
用你说的办法也不行

结贴了
wooden954 2003-10-16
  • 打赏
  • 举报
回复
估计是你SQL Server的事,和你的程序没有关系,看一下你的存储过程有没有问题,如果没有问题的话建议将你的SQl Server重装一次吧!
SeaFish 2003-10-16
  • 打赏
  • 举报
回复
错误提示:
project project.exe raised exception class eaccessviolation with message 'access violation at address 0190a292 in module 'sqloledb.dll' . read of address 00000018' . process stopped . use step or run to continue .
SeaFish 2003-10-16
  • 打赏
  • 举报
回复
问题基本解决了
不能算解决而是绕过了问题,用ADOQuery来执行存储过程,如果有返回的数据,用结果集来处理.
kevinwzh 2003-10-16
  • 打赏
  • 举报
回复
我也遇到过你这个问题:现在可以肯定不是db server的原因,有可能与output参数有关,你先把output参数屏蔽了再看看有没问题。顺便说一句:我用的是dbexpress引擎。
liuri璇玑 2003-10-16
  • 打赏
  • 举报
回复
顶一下,感觉象是你SQLSERVER的问题:)
SeaFish 2003-10-16
  • 打赏
  • 举报
回复
up
SeaFish 2003-10-16
  • 打赏
  • 举报
回复
很奇怪:
我把程序放在本地(win2k个人版)就不出那个错误,放在服务器(win2k server)上就出错

2,497

社区成员

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

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