레코드 집합 작업
Recordset 개체에는 결과 집합의 데이터 순서를 다시 정렬하고, 제공된 조건에 따라 특정 레코드를 검색하고, 인덱스를 사용하여 이러한 검색 작업을 최적화할 수 있는 기본 제공 기능이 있습니다. 이러한 기능을 사용할 수 있는지 여부는 공급자에 따라 달라지며 경우에 따라 Index 속성과 같은 데이터 원본 자체의 구조가 달라집니다.
데이터 정렬
레코드 집합에서 데이터를 정렬하는 가장 효율적인 방법은 결과를 반환하는 데 사용되는 SQL 명령에서 ORDER BY 절을 지정하는 것입니다. 그러나 이미 만들어진 레코드 집합의 데이터 순서를 변경해야 할 수 있습니다. Sort 속성을 사용하여 레코드 집합의 행이 트래버스되는 순서를 설정할 수 있습니다. 또한 Filter 속성은 행을 트래버스할 때 액세스할 수 있는 행을 결정합니다.
Sort 속성은 정렬할 Recordset의 필드 이름을 나타내는 String 값을 설정하거나 반환합니다. 각 이름은 쉼표로 구분되며 필요에 따라 필드를 오름차순으로 정렬하는 공백 키워드와 키워드 ASC 또는 필드를 내림차순으로 정렬하는 DESC가 뒤따릅니다. 기본적으로 키워드를 지정하지 않으면 필드는 오름차순으로 정렬됩니다.
데이터가 물리적으로 다시 정렬되지 않고 인덱스가 지정한 순서대로 액세스하기 때문에 정렬 작업이 효율적입니다.
Sort 속성을 사용하려면 CursorLocation 속성을 adUseClient로 설정해야 합니다. 인덱스가 아직 없는 경우 Sort 속성에 지정된 각 필드에 대해 임시 인덱스가 만들어집니다.
Sort 속성을 빈 문자열로 설정하면 행이 원래 순서로 다시 설정되고 임시 인덱스가 삭제됩니다. 기존 인덱스는 삭제되지 않습니다.
Recordset에 firstName, middleInitial, lastName이라는 세 개의 필드가 포함되어 있다고 가정합니다. Sort 속성을 문자열 “lastName DESC, firstName ASC
”로 설정하면 Recordset에서 성을 내림차순으로 정렬한 다음, 이름을 오름차순으로 정렬합니다. 중간 이니셜은 무시됩니다.
정렬 조건 문자열에서 참조되는 필드의 이름은 ASC 및 DESC 키워드와 충돌하므로 “ASC” 또는 “DESC”로 지정할 수 없습니다. 레코드 집합을 반환하는 쿼리에서 AS 키워드를 사용하여 충돌하는 이름을 가진 필드에 별칭을 지정합니다.
레코드 집합 필터링에 대한 자세한 내용은 이 항목의 뒷부분에 있는 “결과 필터링”을 참조하세요.
특정 레코드 찾기
ADO는 레코드 집합에서 특정 레코드를 찾기 위한 Find 및 Seek 메서드를 제공합니다. Find 메서드는 다양한 공급자에서 지원되지만 단일 검색 기준으로 제한됩니다. Seek 메서드는 여러 조건 검색을 지원하지만 많은 공급자가 지원하지 않습니다.
필드의 인덱스는 Recordset 개체의 Find 메서드와 Sort 및 Filter 속성의 성능을 크게 향상시킬 수 있습니다. 동적 Optimize 속성을 설정하여 Field 개체에 대한 내부 인덱스를 만들 수 있습니다. CursorLocation 속성을 adUseClient로 설정하면 이 동적 속성이 Field 개체의 Properties 컬렉션에 추가됩니다. 이 인덱스는 ADO 내부에 있으며 액세스 권한을 얻거나 다른 용도로 사용할 수 없습니다. 또한 이 인덱스는 Recordset 개체의 Index 속성과 다릅니다.
Find 메서드는 레코드 집합의 열(필드) 내에서 값을 빠르게 찾습니다. Optimize 속성을 사용하여 열에서 인덱스 만들기를 통해 열에서 Find 메서드의 속도를 자주 개선할 수 있습니다.
Find 메서드는 검색을 한 필드의 내용으로 제한합니다. Seek 메서드를 사용하려면 인덱스가 있어야 하며 다른 제한 사항도 있어야 합니다. 인덱스 기반이 아닌 여러 필드를 검색해야 하거나 공급자가 인덱스를 지원하지 않는 경우 Recordset 개체의 Filter 속성을 사용하여 결과를 제한할 수 있습니다.
Find
Find 메서드는 지정된 조건을 충족하는 행에 대한 레코드 집합을 검색합니다. 필요에 따라 검색 방향, 시작 행, 시작 행으로부터의 오프셋을 지정할 수 있습니다. 조건이 충족되면 현재 행 위치가 찾은 레코드에 설정됩니다. 그렇지 않으면 검색 방향에 따라 위치가 레코드 집합의 끝(또는 시작)으로 설정됩니다.
기준의 경우 단일 열 이름만 지정할 수 있습니다. 즉, 이 메서드는 여러 열 검색을 지원하지 않습니다.
기준 비교 연산자는 “>”(보다 큼), “<”(보다 작음), “=”(같음), “>=”(크거나 같음), “<=”(작거나 같음), “<>”(같지 않음) 또는 “같음”(패턴 일치)일 수 있습니다.
기준 값은 문자열, 부동 소수점 숫자 또는 날짜일 수 있습니다. 문자열 값은 작은따옴표 또는 “#”(숫자 기호) 표시로 구분됩니다(예: “state = 'WA'” 또는 “state = #WA#”). 날짜 값은 "#"(숫자 기호) 표시로 구분됩니다(예: "start_date > #7/22/97#").
비교 연산자가 “like”인 경우 문자열 값에 별표(*)가 포함되어 문자 또는 하위 문자열이 하나 이상 나타날 수 있습니다. 예를 들어 “'M*'과 같은 주”는 메인과 메사추세츠와 일치합니다. 선행 및 후행 별표로 값 내에 포함된 하위 문자열을 찾을 수도 있습니다. 예를 들어 “'*as*'와 같은 주”는 알래스카, 아칸소 및 매사추세츠와 일치합니다.
별표는 위에 표시된 대로 조건 문자열의 끝이나 조건 문자열의 시작과 끝에서만 사용할 수 있습니다. 별표를 선행 와일드카드('*str') 또는 포함된 와일드카드('s*r')로 사용할 수 없습니다. 이로 인해 오류가 발생합니다.
검색 및 인덱스
기본 공급자가 Recordset 개체에 대한 인덱스를 지원하는 경우 Seek 메서드를 Index 속성과 함께 사용합니다. Supports(adSeek) 메서드를 사용하여 기본 공급자가 Seek를 지원하는지 여부를 결정하고 Supports(adIndex) 메서드를 사용하여 공급자가 인덱스를 지원하는지 여부를 결정합니다. (예를 들어 Microsoft Jet용 OLE DB 공급자는 Seek 및 Index를 지원합니다.)
Seek에서 원하는 행을 찾지 못하면 오류가 발생하지 않고 행이 레코드 집합의 끝에 배치됩니다. 이 메서드를 실행하기 전에 Index 속성을 원하는 인덱스로 설정합니다.
이 메서드는 서버 쪽 커서에서만 지원됩니다. Recordset 개체의 CursorLocation 속성 값이 adUseClient인 경우 Seek는 지원되지 않습니다.
이 메서드는 Recordset 개체가 adCmdTableDirect의 CommandTypeEnum 값으로 열린 경우에만 사용할 수 있습니다.
결과 필터링
Find 메서드는 검색을 한 필드의 내용으로 제한합니다. Seek 메서드를 사용하려면 인덱스가 있어야 하며 다른 제한 사항도 있어야 합니다. 인덱스 기반이 아닌 여러 필드를 검색해야 하거나 공급자가 인덱스를 지원하지 않는 경우 Recordset 개체의 Filter 속성을 사용하여 결과를 제한할 수 있습니다.
Filter 속성을 사용하여 Recordset 개체의 레코드를 선택적으로 차단합니다. 필터링된 레코드 집합은 현재 커서가 되므로 필터 조건을 충족하지 않는 레코드는 필터가 제거될 때까지 레코드 집합 에서 사용할 수 없습니다. 현재 커서를 기반으로 값을 반환하는 다른 속성(예: AbsolutePosition, AbsolutePage, RecordCount, PageCount)이 영향을 받습니다. Filter 속성을 특정 새 값으로 설정하면 현재 레코드가 값을 충족하는 첫 번째 레코드로 이동하기 때문입니다.
Filter 속성은 변형 인수를 사용합니다. 이 값은 Filter 속성을 사용하기 위한 세 가지 방법, 즉 조건 문자열, FilterGroupEnum 상수 또는 책갈피 배열 중 하나를 나타냅니다. 자세한 내용은 조건 문자열을 사용하여 필터링, 상수로 필터링, 이 항목의 뒷부분에 있는 책갈피를 사용하여 필터링을 참조하세요.
참고 항목
선택하려는 데이터를 알고 있는 경우 일반적으로 Filter 속성에 의존하지 않고 결과 집합을 효과적으로 필터링하는 SQL 문으로 Recordset을 여는 것이 더 효율적입니다.
레코드 집합에서 필터를 제거하려면 adFilterNone 상수를 사용합니다. Filter 속성을 길이가 0인 문자열(“”)로 설정하면 adFilterNone 상수 사용과 같은 효과가 있습니다.
조건 문자열을 사용하여 필터링
조건 문자열은 FieldName-Operator-Value 형식(예: "LastName = 'Smith'"
)의 절로 구성됩니다. 개별 절을 AND(예: "LastName = 'Smith' AND FirstName = 'John'"
) 및 OR(예: "LastName = 'Smith' OR LastName = 'Jones'"
)과 연결하여 복합 절을 만들 수 있습니다. 조건 문자열의 경우 다음 지침을 사용합니다.
FieldName은 레코드 집합의 유효한 필드 이름이어야 합니다. 필드 이름에 공백이 포함된 경우 이름을 대괄호로 묶어야 합니다.
연산자는 <, >, <=, >=, <>, = 또는 LIKE 중 하나여야 합니다.
Value은 필드 값을 비교할 값입니다(예:
'Smith'
,#8/24/95#
,12.345
또는$50.00
). 문자열이 있는 작은따옴표(')와 날짜가 있는 파운드 기호(#
)를 사용합니다. 숫자의 경우 소수점, 달러 기호 및 과학적 표기법을 사용할 수 있습니다. 연산자가 LIKE인 경우 값은 와일드카드 문자를 사용할 수 있습니다. 별표(*) 및 백분율 기호(%) 와일드카드 문자만 허용되며 문자열의 마지막 문자여야 합니다. 값은 null일 수 없습니다.참고 항목
값 필터에 작은따옴표(')를 포함하려면 두 개의 작은따옴표를 사용하여 작은따옴표 하나를 나타냅니다. 예를 들어 O'Malley를 필터링하려면 조건 문자열이
"col1 = 'O''Malley'"
여야 합니다. 필터 값의 시작과 끝에 작은따옴표를 포함하려면 문자열을 파운드 기호(#)로 묶습니다. 예를 들어 ‘1’을 필터링하려면 조건 문자열이"col1 = #'1'#"
여야 합니다.
AND와 OR 사이에는 우선 순위가 없습니다. 절은 괄호 안에 그룹화할 수 있습니다. 그러나 다음과 같이 OR에 의해 조인된 절을 그룹화한 다음, AND를 사용하여 그룹을 다른 절에 조인할 수 없습니다.
(LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John'
대신 다음과 같이 이 필터를 구성합니다.
(LastName = 'Smith' AND FirstName = 'John') OR (LastName = 'Jones' AND FirstName = 'John')
LIKE 절에서는 패턴의 시작과 끝에 와일드카드를 사용하거나(예:LastName Like '*mit*'
) 패턴의 끝(예: LastName Like 'Smit*'
)에만 사용할 수 있습니다.
상수를 사용하여 필터링
레코드 집합을 필터링하는 데 사용할 수 있는 상수는 다음과 같습니다.
상수 | 설명 |
---|---|
adFilterAffectedRecords | 마지막 Delete, Resync, UpdateBatch 또는 CancelBatch 호출의 영향을 받는 레코드만 보기 위한 필터입니다. |
adFilterConflictingRecords | 마지막 일괄 업데이트에 실패한 레코드를 보기 위한 필터입니다. |
adFilterFetchedRecords | 현재 캐시에서 레코드를 보기 위한 필터입니다. 즉, 데이터베이스에서 레코드를 검색하기 위한 마지막 호출의 결과입니다. |
adFilterNone | 현재 필터를 제거하고 보기 위해 모든 레코드를 복원합니다. |
adFilterPendingRecords | 변경되었지만 아직 서버로 전송되지 않은 레코드만 보기 위한 필터입니다. 일괄 업데이트 모드에만 적용됩니다. |
필터 상수는 다음 예제와 같이 마지막 UpdateBatch 메서드 호출 중에 영향을 받은 레코드만 볼 수 있으므로 일괄 업데이트 모드 중에 개별 레코드 충돌을 보다 쉽게 해결할 수 있도록 합니다.
Attribute VB_Name = "modExaminingData"
책갈피를 사용하여 필터링
마지막으로, 책갈피의 변형 배열을 Filter 속성에 전달할 수 있습니다. 결과 커서에는 책갈피가 속성에 전달된 레코드만 포함됩니다. 다음 코드 예제에서는 ProductName 필드에 “B”가 있는 레코드 집합의 레코드에서 책갈피 배열을 만듭니다. 그런 다음, 배열을 Filter 속성에 전달하고 필터링된 결과 레코드 집합에 대한 정보를 표시합니다.
'BeginFilterBkmk
Dim vBkmkArray() As Variant
Dim i As Integer
'Recordset created using "SELECT * FROM Products" as command.
'So, we will check to see if ProductName has a capital B, and
'if so, add to the array.
i = 0
Do While Not objRs.EOF
If InStr(1, objRs("ProductName"), "B") Then
ReDim Preserve vBkmkArray(i)
vBkmkArray(i) = objRs.Bookmark
i = i + 1
Debug.Print objRs("ProductName")
End If
objRs.MoveNext
Loop
'Filter using the array of bookmarks.
objRs.Filter = vBkmkArray
objRs.MoveFirst
Do While Not objRs.EOF
Debug.Print objRs("ProductName")
objRs.MoveNext
Loop
'EndFilterBkmk
레코드 집합의 복제본 만들기
Clone 메서드를 사용하여 여러 개의 중복 Recordset 개체를 만들 수 있습니다. 특히 지정된 Recordset에서 현재 레코드를 두 개 이상 유지하려는 경우 더욱 그렇습니다. Clone 메서드를 사용하는 것이 원본과 동일한 정의를 사용하는 새 Recordset 개체를 만들고 여는 것보다 더 효율적입니다.
새로 만든 복제본의 현재 레코드가 원래 첫 번째 레코드로 설정됩니다. 복제된 레코드 집합의 현재 레코드 포인터는 원본과 동기화되지 않거나 그 반대의 경우도 마찬가지입니다. 각 레코드 집합에서 독립적으로 탐색할 수 있습니다.
한 Recordset 개체에 대한 변경 내용은 커서 유형에 관계없이 모든 복제본에 표시됩니다. 그러나 원래 Recordset에서 Requery를 실행한 후에는 복제본이 더 이상 원본과 동기화되지 않습니다.
원본 Recordset를 닫아도 복사본은 닫히지 않으며 복사본을 닫거나 원본 또는 다른 복사본을 닫지 않습니다.
책갈피를 지원하는 경우에만 Recordset 개체를 복제할 수 있습니다. 책갈피 값은 서로 바꿔 사용할 수 있습니다. 즉, 한 Recordset 개체의 책갈피 참조는 해당 복제본에 있는 동일한 레코드를 참조합니다.