Web/ASP & ASP.NET2009. 4. 10. 00:47

< 출처 : korea.internet.com, 지은이 : 최현진 >

CursorLocation 속성

CursorLocation 속성은 커서 엔진의 위치를 지정하는 속성이며, 다음 상수 중에 하나를 지정할 수 있다.


상수 설명
AdUseNone 커서 서비스를 사용하지 않는다. (이 상수는 단지 하위 버전과의 호환성을 위해서 제공되는 것이다.)
AdUseClient 로컬 커서 라이브러리에 의해서 제공되는 클라이언트 사이드 커서를 사용한다. 로컬 커서 엔진은 종종 드라이버가 제공하는 서버 사이드 커서가 제공하지 못하는 기능들을 제공하기 위해서 사용된다. 또한 하위 버전과의 호환성 때문에 adUseClientBatch도 역시 지원한다.
adUseServer 디폴트, 데이터 Provider 또는 드라이버가 제공하는 커서로서, 매우 유연하고 다양한 기능들을 제공한다. 그렇지만, 마이크로소프트의 클라이언트 커서가 제공하는 몇몇 기능을 제공하지 못한다.


이 속성은 Provider가 제공하는 다양한 커서 라이브러리를 선택하도록 한다. 개발자는 상황에 따라 클라이언트 사이드 또는 서버 사이드 커서를 사용할 수 있다.

CursorLocation 속성은 Connection 개체와 Recordset 개체가 모두 가지고 있으며, 디폴트 값은 서버 사이드 커서(adUseServer)이다. Recordset 개체의 CursorLocation 속성은 상위의 Connection 개체로부터 값을 상속받으며, Recordset 개체를 생성할 때 추가로 다른 CursorLocation으로 지정을 하였다면 Connection 개체의 CursorLocation 속성과 다른 값을 갖게 된다.

이 속성은 읽기/쓰기가 가능하며, Recordset 개체의 경우에는 Recordset 개체가 열려진 후에는 변경할 수 없다.

Remote Data Service 환경에서 클라이언트 사이드 Recordset 개체(ADOR) 또는 Connection 개체를 사용하기 위해서는 CursorLocation 속성을 클라이언트 사이드(adUseClient)로 설정해야 한다.

RDO에서는 rdoConnection 개체를 생성할 때 CursorDriver라는 속성을 사용해서 커서의 위치를 결정하게 했다. 여기에서 커서는 데이터베이스에서 사용자가 원하는 레코드를 요청했을 때 메모리에 생성되는 레코드셋이라고 이해하면 된다. RDO에서는 서버 사이드, 클라이언트 사이드, ODBC 사이드 이렇게 세가지 타입의 커서 위치를 지원했으며, 클라이언트 사이드 커서는 반환되는 레코드의 개수가 적을 경우에 주로 사용되었으며, 서버 사이드 커서는 반환되는 레코드의 개수가 많을 경우에 주로 사용되었다. 하지만, rdoConnection에서만 지정할 수 있었기 때문에 rdoResultset을 생성할 때 유연하게 설정할 수 없는 이유로 대부분의 개발자들은 자동으로 커서의 위치가 설정되는 ODBC 사이드 커서를 사용해 왔다. 이런 제약들이 ADO에서는 Connection 개체와 Recordset 개체에 모두 CursorLocation 속성을 지원함으로 해결되었다.

[예제]
다음의 예제는 Pubs 데이터베이스의 Employee 테이블에 있는 레코드의 값을 보여주는 것이다. 예제에서 볼 수 있듯이 Recordset 개체의 RecordCount 속성과 AbsolutePosition 속성은 클라이언트 사이드 커서일 경우에만 값을 가지며 서버 사이드 커서일 경우에는 -1을 갖는다.

Private Sub cmdCursorLocation_Click()
  Dim adoRs As New Recordset
  Dim strConn As String

  strConn = "Provider=sqloledb;Data Source=Chris;Initial Catalog=Pubs;User Id=sa;Password=; "

  adoRs.CursorLocation = adUseClient
  adoRs.Open "Employee", strConn, , , adCmdTable

  Do While Not adoRs.EOF
    Debug.Print "Employee: " & adoRs!lName & _
      " ( " & adoRs.AbsolutePosition; " / " & _
      adoRs.RecordCount & " 번째 레코드)"

    adoRs.MoveNext
  Loop

  adoRs.Close
  Set adoRs = Nothing
End Sub

위의 예제에서 볼 수 있듯이, RecordCount 속성과 AbsolutePosition 속성 같은 몇몇 속성들은 CursorLocation 속성과 CursorType 속성에 영향을 받는다. CursorLocation 속성과 CursorType의 관계는 다음과 같다.


CursorType/CursorLocation Server Side Client Side
adOpenForwardOnly O X
adOpenKeyset O X
adOpenDynamic O X
adOpenStatic O O


위의 표에서 볼수 있듯이, ADO에서 클라이언트 사이드의 CursorLocation 일 경우에는 Static 커서만 사용가능하다. 그리고 RDO에서 CursorDriver나 CursorType을 잘 못 지정하면 오류가 발생하지만, ADO에서는 잘 못 지정하더라도 Provider가 알아서 수정하기 때문에 개발자가 정확하게 알고 지정해야만 오류를 피할 수 있다.

예를 들어, 다음과 같은 코딩을 실행해 본다.

Dim adoCn As New ADODB.Connection
Dim adoRs As New ADODB.Recordset
Dim strConn As String

strConn = "Provider=sqloledb;Data Source=(local);Initial Catalog=Pubs;User Id=sa;Password=;"

adoCn.CursorLocation = adUseClient
adoCn.Open strConn

adoRs.Open "Authors", adoCn, adOpenDynamic, adLockOptimistic

Stop

adoRs.Close
Set adoRs = Nothing

adoCn.Close
Set adoCn = Nothing 

위의 코드에서 개발자는 커서 유형을 Dynamic(adOpenDynamic-2)으로 지정했다. 그러나 Recordset 개체가 열려진 후에 adoRs의 CursorType 속성을 조사해 보면, Static(adOpenStatic-3)임을 알 수 있을 것이다. 이렇기 때문에 CursorLocation과 CursorType에 대해서 개발자는 명확히 알고 있는 상태에서 개발을 해야한다.

CursorLocation에 따라 CursorType이 영향을 받는 것과 유사하게, RecordCount 또는 AbsolutePosition과 같은 속성도 CursorLocation과 CursorType에 따라 사용가능 여부가 결정된다. 다음 표는 이것들에 대한 관계이다.


CursorType/CursorLocation Server Side Client Side
adOpenForwardOnly X X
adOpenKeyset O X
adOpenDynamic X X
adOpenStatic O O


RecordCount과 AbsolutePosition과 같은 속성들은 CursorLocation이 서버 사이드일 경우에는 CursorType이 Static과 Keyset일 때만 사용이 가능하고, 그렇지 않을 경우에는 -1을 반환한다. CursorLocation이 클라이언트 사이드일 경우에는 CursorType이 Static일 때만 사용이 가능하다.


CursorType 속성

CursorType 속성은 Recordset 개체의 커서 유형을 지정한다. 커서 유형은 네 가지가 있으며, 다음과 같이 설정할 수 있다.


상수 설명
adOpenForwardOnly 디폴트, Forward-only 커서. Static 커서와 동일하며 단지 다음 레코드로만 이동할 수 있는 커서이다. 이 타입은 Recordset 개체가 생성될 때 다음 레코드에 대한 포인터만 가지도록 생성되므로 다른 유형의 커서 보다 생성되는 속도가 빠르다.
adOpenKeyset Keyset 커서. Recordset 개체가 생성된 후에 다른 사용자에 의해서 추가되거나 삭제된 내용만 반영하지 못하며, 변경된 내용은 반영한다.
adOpenDynamic Dynamic 커서. Recordset 개체가 생성된 후에 다른 사용자에 의해서 추가, 수정, 삭제된 내용을 반영하며, Recordset 개체를 통한 모든 이동 형식을 허용한다. 단, Provider가 Bookmark를 지원하지 못하는 경우에는 Bookmark를 지원하지 않는다.
adOpenStatic Static 커서. 데이터베이스에 있는 레코드들의 정적인 복사본을 제공하는 커서이다. 즉 레코드를 가져오는 시점의 데이터를 가지고 있기 때문에 레코드를 가져온 후에 다른 사용자에 의해서 추가, 수정, 삭제된 내용이 반영되지 않는다.


이 속성은 Recordset이 생성되기 전에는 읽기/쓰기가 모두 가능하며, Recordset 이 생성된 후에는 읽기 전용이다.

만약 개발자가 지정한 커서 유형을 Provider가 지원하지 못할 경우에는 적절한 커서 유형으로 변경해서 지정하게 되며, 오류는 발생하지 않는다. 그렇기 때문에 개발자는 자신이 지정한 커서 유형으로 커서가 생성되었는지를 확인하는 습관을 가지는 것이 좋다. 이렇듯 Provider가 커서 유형을 지원하는 지를 확인하기 위해서 Supports 메서드를 사용할 수 있다.


커서 타입 아래의 상수에 대해서 True를 반환하면 지원하는 것이다.
adOpenForwardOnly 없음
adOpenKeyset adBookmark, adHoldRecords, adMovePrevious, adResync
adOpenDynamic AdMovePrevious
adOpenStatic adBookmark, adHoldRecords, adMovePrevious, adResync


Remote Data Service 환경에서 클라이언트 사이드 Recordset 개체(ADOR)를 사용하기 위해서는 CursorType 속성을 반드시 adOpenStatic으로 설정해야 한다.

[예제]
다음 예제는 Authors 테이블을 Static 커서 유형으로 생성한 예이다.

Private Sub cmdCursorType_Click()
  Dim adoRs As New Recordset
  Dim strConn As String

  strConn = "Provider=sqloledb;Data Source=Chris;Initial Catalog=Pubs;User Id=sa;Password=;"

  adoRs.CursorLocation = adUseClient
  adoRs.Open "Select * from Authors", strConn, adOpenStatic, adLockOptimistic

  While Not adoRs.EOF
    Debug.Print adoRs(0)

    adoRs.MoveNext
  Wend

  adoRs.Close
  Set adoRs = Nothing
End Sub


DataMember 속성

DataMember 속성은 DataSource 속성이 참조하는 개체에서 검색할 데이터 구성원의 이름을 나타낸다. 이 속성은 String 값을 설정하거나 반환한다.

이 속성은 비주얼베이직에서 Data Environment를 사용할 때 데이터 바운드 컨트롤을 생성하기 위해서 사용하며, Data Environment는 Recordset 개체로 표현되는 명명된 개체(데이터 구성원)를 포함하는 데이터 컬렉션(데이터 원본)을 유지 관리한다.

DataMember 속성과 DataSource 속성은 함께 사용되어야 한다.

DataMember 속성은 Recordset 개체로 표현되고 DataSource 속성에 의해 지정되는 개체를 결정한다. 이 속성을 설정하기 전에 먼저 Recordset 개체를 닫아야 한다. DataSource 속성을 설정하기 전에 DataMember 속성을 설정하지 않거나 또는 DataSource 속성으로 지정된 개체가 DataMember 이름을 인식하지 못하면 오류가 발생한다.

사용 예는 DataSource 속성를 참조한다.


DataSource 속성

DataSource 속성은 Recordset 개체로 나타낼 데이터를 포함하는 개체를 지정한다.

이 속성은 DataMember가 속한 Data Environment 내에 있는 개체를 저정한다.

참조된 개체는 IDataSource 인터페이스를 구현해야 하며 IRowset 인터페이스를 포함해야 한다.

[예제]
비주얼베이직 프로젝트에 Data Environment를 추가하고, Command를 추가한다.
Dim adoRs As New Recordset

adoRs.DataMember = "Command1" '바인딩할 열 집합의 이름

Set adoRs.DataSource = DataEnvironment1 'IRowset을 포함하는 개체 이름

위의 예제에서 Command1은 DataEnvironment1의 명령이다.


EditMode 속성

EditMode 속성은 현재 레코드의 편집 상태를 나타낸다. 이 속성은 아래의 상수 값(EditModeEnum)들 중에서 하나의 값을 가진다.


상수 설명
AdEditNone 편집 작업이 진행되지 않고 있음을 나타낸다.
AdEditInProgress 현재 레코드가 편집 중이며, 아직 저장되지 않았음을 나타낸다.
AdEditAdd Recordset 개체의 AddNew 메서드를 사용해서 새로운 레코드를 편집하고 있음을 나타내며, 아직 저장되지 않은 상태이다.
AdEditDelete 현재 레코드가 삭제 되었음을 나타낸다.


ADO는 현재 레코드와 관련 있는 편집 버퍼를 유지보수하며, 이 버퍼의 내용이 변경되었거나, 새로이 추가된 경우를 나타낸다.

[예제]
다음 예제는 EditMode를 보여주는 예이다.

Private Sub cmdEditMode_Click()
  Dim adoCn As New Connection
  Dim adoRs As New Recordset

  adoCn.Open "Provider=sqloledb;Data Source=(local);Initial Catalog=pubs;User Id=sa;Password=;"

  Set adoRs.ActiveConnection = adoCn
  adoRs.CursorType = adOpenKeyset
  adoRs.LockType = adLockOptimistic
  adoRs.Open "Employee", , , , adCmdTable

  adoRs!fname = "test"
  'Edit 후의 EditMode, adEditInProgress(1)
  Debug.Print adoRs.EditMode
  adoRs.CancelUpdate

  adoRs.AddNew
  adoRs!emp_id = "T-T55555M"
  adoRs!fname = "temp_fname"
  adoRs!lname = "temp_lname"
  'AddNew 후의 EditMode, adEditAdd(2)
  Debug.Print adoRs.EditMode

  adoRs.UpdateBatch
  'UpdateBatch 후의 EditMode, adEditNone(0)
  Debug.Print adoRs.EditMode

  adoRs.Close
  Set adoRs = Nothing

  adoCn.Execute "DELETE FROM Employee WHERE emp_id = 'T-T55555M'"
  adoCn.Close

  Set adoCn = Nothing
End Sub


Filter 속성

Filter 속성은 Recordset 개체 내의 데이터에 대한 필터를 나타낸다. 이 속성은 다음 표중 하나를 포함할 수 있는 Variant 값을 설정하거나 반환한다.


수식문자열 And 또는 Or 연산자를 사용해서 작성할 수 있다. 예를 들어 "LasrName = 'Choi'"(FieldName-Opertor-Value)와 같이 작성하면 된다.
- FieldName은 Recordset 개체 내에 존재하는 필드명을 사용해야 하며, 만약 필드 명에 스페이스가 포함되어져 있다면 중괄호([ ])로 묶어야 한다.
- 사용할 수 있는 Operator는 <,>, <=,>=, <>, =, or LIKE 이다.

- And와 Or 연산자 사이에 우선 순위는 없으며, 괄호를 사용해서 그룹으로 묶어서 사용할 수 있다. 하지만, Or에 의해 생성한 그룹을 다른 그룹과 And로 묶을 수는 없다. 다음과 같은 경우는 사용할 수 없다. (LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John'
- 대신 아래와 같이 사용할 수 있다. (LastName = 'Smith' AND FirstName = 'John') OR (LastName = 'Jones' AND FirstName = 'John')Like 문을 사용하는 예는 일반적인 경우와 동일하며, WildCard 문자(*)를 사용할 수 있다.
Bookmark들의 배열 Recordset 개체 내의 레코드들을 가리키는 유일한 Bookmark들의 배열
FilterGroupEnum 값들 중 하나 다음 표를 참조한다.


FilterGroupEnum 값은 다음 표와 같다.


상수 설명
adFilterNone 현재의 Filter를 제거하고, Recordset 개체를 원상태로 복구한다.
adFilterPendingRecords 변경은 되었지만, 아직 서버에 전송되지 않은 레코드들만 보여지도록 한다. 단지 BatchUpdate 모드에서만 사용할 수 있다.
adFilterAffectedRecords Delete, Resync, UpdateBatch, 또는 CancelBatch 메서드의 호출 후에 영향을 받은 레코드들만 보여지도록 한다.
adFilterFetchedRecords 현재 캐쉬 내에 있는 레코드들만 보여지도록 한다. 즉, 데이터베이스로부터 생성한 마지막 Recordset만 보여지도록 한다.
adFilterConflictingRecords 가장 최근에 BatchUpdate 처리를 실패한 레코드들만 보여지도록 한다.


Filter 속성은 Recordset 개체 내의 데이터를 필터링해서 원하는 레코드들만을 보여지도록 설정한다. Filter를 설정할 경우 레코드의 위치는 필터에 의해서 생성된 Recordset 개체의 부분 집합인 레코드들의 처음으로 이동하게 된다. 필터를 해제할 경우에는 Filert 프로퍼티에 길이가 0인 문자열("")을 지정하거나, adFilterNone상수를 지정하면 된다. 이렇게 필터를 해제했을 경우에도 Recordset 개체의 위치는 처음으로 이동하게 된다.

Filter 속성과 함께 사용할 수 있는 Bookmark들의 배열을 만들 수 있으며, Bookmark에 대한 설명은 Recordset 개체의 Bookmark 속성을 참조한다.

[예제]
생성한 Recordset 개체와 바인딩하기 위해서 비주얼 베이직의 프로젝트 메뉴의 구성요소(Components)... 메뉴에서 Microsoft DataGrid Control 6.0(OLEDB)을 선택한다.

다음 예제는 Pubs 데이터베이스의 Authors 테이블의 레코드를 DataGrid1에 바인딩하여 Filter 속성을 사용해서 레코드를 필터링하는 예제이다.

Dim adoCn As New Connection
Dim adoRs As New Recordset

Private Sub cmdOpenRecordset_Click()
  adoCn.Open "Provider=sqloledb;Data Source=(local);Initial Catalog=pubs;User Id=sa;Password=;"
  adoRs.Open "Select * from Authors", adoCn, adOpenStatic, adLockOptimistic

  Set DataGrid1.DataSource = adoRs

  Debug.Print adoRs.RecordCount
End Sub

Private Sub cmdFilter_Click()
  adoRs.Filter = "State='CA'"

  Debug.Print adoRs.RecordCount
End Sub

Private Sub cmdReleaseFilter_Click()
  adoRs.Filter = adFilterNone

  Set DataGrid1.DataSource = adoRs
End Sub

위의 예제에서 Filter를 해제하더라도 바인딩한 컨트롤에 반영이 되지 않을 경우에는 Set DataGrid1.DataSource = adoRs 문장을 사용해서 다시 초기화해 주어야 한다.

그리고 Filter 속성을 사용해서 Recordset 개체 내의 레코드들에 대해서 필터링을 했을 경우에 Recordset 개체의 RecordCount 속성은 필터링된 레코드들에 대한 개수를 나타낸다.
Posted by Huikyun