2014-05-14 4 views
1

그래서 이전 Classic ASP 웹 사이트를 업데이트하라는 요청을 받았습니다. 그것은 매개 변수화 된 쿼리를 사용하지 않았으며 입력 검증은 거의 이루어지지 않았습니다. 간단한 작업을 위해 필자는 데이터베이스 연결을 열고 매개 변수가있는 명령 개체를 설정하고 연결이 끊긴 레코드 세트를 만드는 도우미 함수를 작성했습니다. :)] 여기에 코드입니다 :기존 ASP 연결이 끊긴 레코드 집합 문제

Function GetDiscRS(DatabaseName, SqlCommandText, ParameterArray) 

    'Declare our variables 
    Dim discConn 
    Dim discCmd 
    Dim discRs 

    'Build connection string 
    Dim dbConnStr : dbConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ 
       "Data Source=" & rootDbPath & "\" & DatabaseName & ".mdb;" & _ 
       "Persist Security Info=False" 

    'Open a connection 
    Set discConn = Server.CreateObject("ADODB.Connection") 
    discConn.Open(dbConnStr) 

    'Create a command 
    Set discCmd = Server.CreateObject("ADODB.Command") 
    With discCmd 
     Set .ActiveConnection = discConn 
     .CommandType = adCmdText 
     .CommandText = SqlCommandText 

     'Attach parameters to the command 
     If IsArray(ParameterArray) Then 
      Dim cnt : cnt = 0 
      For Each sqlParam in ParameterArray 
       discCmd.Parameters(cnt).Value = sqlParam 
       cnt = cnt + 1 
      Next 
     End If 
    End With 

    'Create the Recordset object 
    Set discRs = Server.CreateObject("ADODB.Recordset") 
    With discRs 
     .CursorLocation = adUseClient  ' Client cursor for disconnected set 
     .LockType = adLockBatchOptimistic 
     .CursorType = adOpenForwardOnly 
     .Open discCmd 
     Set .ActiveConnection = Nothing ' Disconnect! 
    End With 

    'Return the Recordset 
    Set GetDiscRS = discRS 

    'Cleanup 
    discConn.Close() 
    Set discConn = Nothing 
    discRS.Close()     ' <=== Issue!!! 
    Set discRs = Nothing 
    Set discCmd = Nothing 
End Function 

내 문제는 내가 함수의 끝에서 discRS.Close()를 호출하는 경우, 다음 반환되는 레코드가 채워되지 않는 것입니다. 이로 인해 레코드 세트가 실제로 연결이 끊어 졌는지 아닌지 궁금하게되었습니다. 내가 그 라인에 대해 논평하면 모든 것이 제대로 작동한다. 또한 ActiveConnection = Nothing을 설정하기 전과 후에 discRS 값을 사용하는 함수 내에서 Response.Write()을 수행하고 레코드 세트 값을 올바르게 반환했습니다. 그래서 그것은 discRS.Close()으로 격리 된 것 같습니다.

이전 기사가 4guysfromrolla.com 인 것으로 밝혀졌으며 기능에 Close() 레코드 세트를 발행합니다. 다른 사이트에서도 똑같은 것을 보았습니다. 그게 실수 였는지, 아니면 뭔가가 바뀌 었는지 확실하지 않습니다.

참고 :

Set .ActiveConnection = Nothing ' Disconnect! 

그래서,이 레코드가 이미 폐쇄되지 않은 : 나는 내가 볼 수있는 코드에서

+0

getRows()를 사용하여 레코드 세트를 메모리 내 변수에 할당 할 수도 있습니다. 참조하십시오 : http://stackoverflow.com/questions/8916384/asp-getrows-count –

+1

Diodeus,하지만 가능하면 인덱스 대신 열 이름을 사용하는 대신 어떤 요소가 어떤 위치에 있는지 기억해야합니다. – Sam

답변

3

내가 아는 한 끊어진 레코드 세트는 데이터베이스가 아닌 수동으로 채워진 레코드 집합을 의미합니다. 예를 들어 다차원 배열 또는 해시 테이블의 종류로 사용됩니다.

데이터베이스에서 채워지므로 연결이 끊긴 레코드 집합이 아니며 연결을 삭제하면 코드가 제대로 작동하지 않게됩니다.

코드에 이미 Set discConn = Nothing이 있으므로 레코드 세트 나 명령 개체를 통해 아무 것도 설정하지 않아도되므로 동일한 연결 개체입니다. 그런 다음

  • Set .ActiveConnection = Nothing ' Disconnect!
  • discRS.Close() ' <=== Issue!!!
  • Set discRs = Nothing

또는 메모리 누수를 방지하기 위해 :

는 실제로 코드의 다음 줄 tho를 제거한다,이 모두를 요약하면 데이터베이스 잠금 문제가 발생하면 함수를 사용하여 코드에서 실제로 레코드 세트를 사용하고 닫은 후에 레코드 세트를 처리해야합니다.
Dim oRS 
Set oRS = GetDiscRS("mydatabase", "SELECT * FROM MyTable", Array()) 
Do Until oRS.EOF 
    'process current row... 
    oRS.MoveNext 
Loop 

oRS.Close ' <=== Close 
Set oRS = Nothing ' <=== Dispose 

복사하여 새로 생성 된 레코드에 모든 데이터를 사용자가 함수 반환 "진짜"연결이 끊긴 된 레코드를 가질 수 있습니다 모든 번거 로움을 피하려면. 관련이 있으면 알려 주시면 코드가 제공됩니다.

+0

+1 (예 : RecordSet을 사용한 후 닫음). 하지만 3 줄의 특정 코드를 제거하는 방법에 대한 조언은 확실하지 않습니다. 나는'disc.Close()'를 제거하는 것에 동의하지만, 다른 두 개의 미리보기를 그대로두면 모든 것이 여전히 작동합니다. 차라리 메모리 누수보다 과도하게 청소하고 싶습니다. – Sam

+0

이상한 VBScript는 개체를 아무 것도 설정하지 않아도 여전히 작동하면 정말 미스테리입니다. 건배! :) –

+0

새로 만든 레코드 세트에 데이터를 복사하는 코드를보고 싶습니다! –

0

비주얼 스튜디오 익스프레스 2013에 내장 된 IIS Express를 사용하고 있습니다?

+0

아니요, 레코드 집합이 닫히지 않지만 연결에서 연결이 끊어졌습니다. 내 생각에'Set GetDiscRS = discRS'는 아마도 복사본을 만드는 것보다는 참조로 할 수있다. 그래서'GetDiscRS'와'discRS'는 모두 메모리에있는 같은 객체를 가리키고 있습니다. 그래서'discRS.Close()'는 결국'discRS'뿐만 아니라'GetDiscRS' 리턴 값도 비 웁니다. 방금 찾은 예제가 모두 함수에서 레코드 세트를 닫는 이유가 궁금합니다. – Sam

1

함수에서 호출 프로세스로 반환하려면 레코드 집합을 닫고 정리할 수 없습니다.

모든 연결과 명령 개체는 정리할 수 있지만 레코드 집합을 다시 채울 수 있으려면 단순히 닫거나 처리하지 마십시오.

코드는 다음과 같이 끝나야 : 그는 참으로 연결이 끊긴 된 레코드를 사용하는

'Cleanup 
    discConn.Close() 
    Set discConn = Nothing 
    'discRS.Close() 
    'Set discRs = Nothing 
    'Set discCmd = Nothing 
end function 
0

. VB6에서 사용하기 시작했습니다. 당신은 connection = Nothing을 설정하고 기본적으로 레코드 세트의 편리한 메소드 (예 : 정렬, 찾기, 필터 등)가있는 콜렉션 클래스를 갖습니다. 또한 레코드를 가져 오는 데 걸리는 시간 동안 만 연결을 유지하므로 Microsoft에서 연결을 통해 서버의 라이선스를 허여 한 경우 이는 한 번에 몇 명의 사용자가 연결되었는지를 최소화하는 좋은 방법이었습니다.

레코드 세트는 완벽하게 작동하며 데이터 소스에 연결되어 있지 않습니다. 다시 연결 한 다음 변경 사항을 적용 할 수 있습니다.

오래 전에 기능이 제거 된 것으로 보입니다.