oracle返回记录集与VB程序的内存泄露,弱水三千,biti_rainy等高手帮帮忙!!!
--pkgRemote包的定义
TYPE t_CurGetCandListImg IS REF CURSOR ;
--pkgRemote包体的过程
/***********************************************************************
* PROCEDURE: sp_Get_CandidateImg
* DESCRIPTION: get Candidate imgae data
* PARAMETERS:
iRemote_ID_I IN VARCHAR2 (1) 远程编号
iResponseID IN NUMBER (2) 消息编号
* RETURNED:
io_cursor IN OUT t_CurGetCandListImg 返回的记录集
***********************************************************************/
PROCEDURE sp_Get_CandidateImg(iRemote_ID_I IN VARCHAR2,
iResponseID IN NUMBER,
io_cursor IN OUT t_CurGetCandListImg)
IS
v_Check NUMBER;
v_cursor t_CurGetCandListImg;
CURSOR cur_Check IS
SELECT ResponseID
FROM T_MResponse
WHERE Remote_ID_I = iRemote_ID_I
AND ResponseTYPE = gnMRCandidateImgTYPE
AND ResponseID = iResponseID;
BEGIN
--检查是否有需要处理的数据,如果没有,返回一个空的记录集
OPEN cur_Check;
FETCH cur_Check INTO v_Check;
IF (cur_Check%NOTFOUND) OR (cur_Check%NOTFOUND IS NULL) THEN
CLOSE cur_Check;
OPEN v_cursor FOR
SELECT * FROM T_CandidateImg
WHERE 1 = 0 ;
io_cursor := v_cursor;
RETURN;
END IF;
--如果有需要处理的数据,则返回需要处理的数据(一个记录集)
OPEN v_cursor FOR
SELECT * FROM T_CandidateImg
WHERE ResponseID = iResponseID;
io_cursor := v_cursor;
EXCEPTION
WHEN OTHERS THEN
CLOSE cur_Check;
END sp_Get_CandidateImg;
//以下是VB程序代码,执行该过程,作用是从远程数据库中获取数据(存取过程),保存到本地数据库
Public Function fReceiveCandImage(ByVal RemoteID As String, ByVal ResponseID As Long, ocKeyNo As String, oiFingerNo As Integer) As Boolean
Dim rsR As ADODB.Recordset
Dim Rs As ADODB.Recordset
Dim sWhere As String
Dim sErr As String
Dim cmdR As ADODB.Command
Dim Pram As ADODB.Parameter
Dim Result As Integer
Dim gImage() As Byte
Dim sKeyNo As String
Dim ImageLen As Long
'//写日志
sLog conINFO_Msg, "开始接收候补图象信息, ResponseID = " & ResponseID
On Error GoTo fReceiveCandImageErr
'//执行以上过程
Set cmdR = New ADODB.Command
With cmdR
.CommandText = "{call pkgRemote.sp_Get_CandidateImg(?,?,{resultset 0, io_cursor})}"
.CommandType = adCmdText 'adCmdText
Set Pram = .CreateParameter("iRemote_ID_I", adBSTR, adParamInput, , RemoteID)
.Parameters.Append Pram
Set Pram = .CreateParameter("iResponseID", adInteger, adParamInput, , ResponseID)
.Parameters.Append Pram
End With
'//得到记录集
Set rsR = fCenterCmdExecute(cmdR)
'//如果没有记录集,过程执行不成功
If rsR Is Nothing Then
sLog conERROR_Msg, "读取远程remote数据库发生错误"
fReceiveCandImage = False
GoTo fReceiveCandImageErr
End If
'//如果记录集为空,没有取到数据
If rsR.EOF Then
sLog conERROR_Msg, "没有该图象供接收:ResponseID = " & ResponseID
fReceiveCandImage = False
GoTo fReceiveCandImageExit
End If
'//如果记录集不为空,分析数据
sKeyNo = rsR!KeyNo
Select Case fGetKeyNoType(sKeyNo)
Case conKeyTypeIndex_TP
sWhere = "keyno='" & sKeyNo & "' and fingerno=" & rsR!FingerNo
Case conKeyTypeIndex_LP
sWhere = "keyno='" & sKeyNo & "'"
Case Else
sWhere = "keyno='" & sKeyNo & "'"
End Select
sErr = ""
Set Rs = CommFunc.fGetUpdatedRS(TBL_VERTPCANDIMAGE, sWhere, sErr)
If sErr <> "" Then
sLog conERROR_Msg, "读取数据库错误:" & sErr
fReceiveCandImage = False
GoTo fReceiveCandImageExit
End If
ImageLen = rsR!fpimagelen
If Not (ImageLen > 0) Then
sLog conERROR_Msg, "图象长度信息错误:ImageLen = " & ImageLen
fReceiveCandImage = False
GoTo fReceiveCandImageExit
End If
If IsNull(rsR!FPImage) Then
sLog conERROR_Msg, "接收到图象为空:ResponseID = " & ResponseID
fReceiveCandImage = False
GoTo fReceiveCandImageExit
End If
ReDim gImage(ImageLen - 1) As Byte
gImage = rsR.Fields("fpImage").GetChunk(ImageLen)
'//如果分析数据没有问题,写入本地表
If Rs.EOF Then Rs.AddNew
Rs!ResponseID = rsR!ResponseID
Rs!JobNo = rsR!JobNo
Rs!CardType = rsR!CardType
Rs!KeyNo = rsR!KeyNo
Rs!FingerNo = rsR!FingerNo
Rs!FingerGet = Left(rsR!FingerGet, 1)
Rs!ErrorMsg = rsR!ErrorMsg
Rs!FPImageX = rsR!FPImageX
Rs!FPImagey = rsR!FPImagey
Rs!fpimagelen = ImageLen
Rs!FPImage = gImage
Rs.Update
ocKeyNo = rsR!KeyNo
oiFingerNo = rsR!FingerNo
'//函数执行成功,数据获取成功
fReceiveCandImage = True
sLog conINFO_Msg, "接收候补图像结束"
fReceiveCandImageExit:
If Rs.Status = adStateOpen Then Rs.Close
Set Rs = Nothing
If rsR.Status = adStateOpen Then rsR.Close
Set rsR = Nothing
If Not (cmdR Is Nothing) Then Set cmdR = Nothing
On Error GoTo 0
Exit Function
fReceiveCandImageErr:
sLog conERROR_Msg, "接收候补图像失败:" & Err.Description
fReceiveCandImage = False
GoTo fReceiveCandImageExit
End Function
-------------------------
说明:操作系统NT,数据库oracle 805,连接方式,VB+ADO2.6+数据库直连
其中,连接与打开记录集的语句是包含在dll中的。
rsR是通过远程存取过程返回的,打开方式为adOpenStatic,锁方式为adLockReadOnly
RS是直接打开的本地记录集,打开方式为adOpenDynamic,锁方式为adLockOptimistic
以上函数被定时执行(10秒),检查远程数据库是否有自己的图象数据,如果有,则取回来。
但是,在执行和测试过程中,发现在这里有很严重的内存泄露,每次泄露的内存大小就是我取的数据的大小
(因为是图象,含有long raw类型,一般为30K左右,10秒泄露30k,太严重了)。
如果我的rsR不是通过存取过程返回,而是直接连接到远程数据库,直接打开,就不会泄露。
为什么,vb的错???oracle的错???还是我的程序错???
btw,最近csdn怎么啦,登录都登录不上来???