다음을 통해 공유


SQL: 레코드 집합의 SQL 문 사용자 지정(ODBC)

이 항목에서는 다음 내용을 설명합니다.

  • 프레임워크에서 SQL 문을 생성하는 방법

  • SQL 문을 재정의하는 방법

참고 항목

이 정보는 MFC ODBC 클래스에 적용됩니다. MFC DAO 클래스를 사용하여 작업하는 경우 DAO 도움말의 “Microsoft Jet Database Engine SQL과 ANSI SQL 비교” 항목을 참조하세요.

SQL 문 생성

레코드 집합은 주로 SQL SELECT 문을 기준으로 레코드를 선택합니다. 마법사를 사용하여 클래스를 선언하면 다음과 같은 GetDefaultSQL 멤버 함수의 재정의 버전이 작성됩니다(레코드 집합 클래스 CAuthors에 대해).

CString CAuthors::GetDefaultSQL()
{
    return "AUTHORS";
}

기본적으로 이 재정의는 마법사로 지정한 테이블 이름을 반환합니다. 이 예제에서 테이블 이름은 "AUTHORS"입니다. 나중에 레코드 집합의 Open 멤버 함수를 호출하면 Open은 양식의 최종 SELECT 문을 생성합니다.

SELECT rfx-field-list FROM table-name [WHERE m_strFilter]
       [ORDER BY m_strSort]

여기서 table-nameGetDefaultSQL을 호출하여 가져오며, rfx-field-listDoFieldExchange의 RFX 함수 호출에서 가져옵니다. 매개 변수 또는 필터를 사용하여 기본 문을 수정할 수도 있지만 런타임에 재정의 버전으로 대체하지 않는 한, SELECT 문에 대해 이 결과를 얻게 됩니다.

참고 항목

공백을 포함하거나(포함할 수 있는) 열 이름을 지정하는 경우 이름을 대괄호로 묶어야 합니다. 예를 들어 이름 "First Name"은 "[First Name]"이어야 합니다.

기본 SELECT 문을 재정의하려면 Open을 호출할 때 전체 SELECT 문을 포함하는 문자열을 전달합니다. 레코드 집합은 자체 기본 문자열을 생성하는 대신 사용자가 제공하는 문자열을 사용합니다. 대체 문에 WHERE 절이 포함된 경우 필터 문이 2개가 되므로 m_strFilter 필터를 지정하지 마세요. 마찬가지로 대체 문에 ORDER BY 절이 포함된 경우 정렬 문이 2개가 되지 않도록 m_strSort에서 정렬을 지정하지 마세요.

참고 항목

필터(또는 SQL 문의 다른 부분)에서 리터럴 문자열을 사용하는 경우 DBMS별 리터럴 접두사 및 리터럴 접미사 문자를 사용하여 이러한 문자열을 "따옴표로 묶어야"(지정된 구분 기호로 묶음) 할 수 있습니다.

DBMS에 따라 외부 조인과 같은 작업에 대한 특별한 구문 요구 사항이 발생할 수도 있습니다. ODBC 함수를 사용하여 DBMS용 드라이버에서 이 정보를 가져옵니다. 예를 들어 SQL_VARCHAR와 같은 특정 데이터 형식에 대해 ::SQLGetTypeInfo를 호출하여 LITERAL_PREFIX 및 LITERAL_SUFFIX 문자를 요청합니다. 데이터베이스 독립적 코드를 작성하는 경우 자세한 구문 정보는 ODBC 프로그래머 참조에서 부록 C: SQL 문법을 참조하세요.

레코드 집합 개체는 사용자가 사용자 지정 SQL 문을 전달하지 않는 한, 레코드를 선택하는 데 사용하는 SQL 문을 생성합니다. 이 방법은 주로 Open 멤버 함수의 lpszSQL 매개 변수에 전달하는 값에 따라 달라집니다.

SQL SELECT 문의 일반적인 형식은 다음과 같습니다.

SELECT [ALL | DISTINCT] column-list FROM table-list
    [WHERE search-condition][ORDER BY column-list [ASC | DESC]]

DISTINCT 키워드를 레코드 집합의 SQL 문에 추가하는 한 가지 방법은 DoFieldExchange에서 첫 번째 RFX 함수 호출에 키워드를 포함하는 것입니다. 예시:

...
    RFX_Text(pFX, "DISTINCT CourseID", m_strCourseID);
...

참고 항목

읽기 전용으로 열린 레코드 집합에서만 이 기술을 사용합니다.

SQL 문 재정의

다음 표에서는 Open에 대한 lpszSQL 매개 변수의 가능성을 보여 줍니다. 표에 제공된 사례는 표 다음에 설명되어 있습니다.

lpszSQL 매개 변수 및 결과 SQL 문자열

케이스 lpszSQL에 전달하는 내용 결과 SELECT 문
1 NULL SELECT rfx-field-list FROM table-name

CRecordset::Open에서 GetDefaultSQL을 호출하여 테이블 이름을 가져옵니다. 결과 문자열은 GetDefaultSQL에서 반환하는 항목에 따라 2~5 경우 중 하나입니다.
2 테이블 이름 SELECT rfx-field-list FROM table-name

필드 목록은 DoFieldExchange의 RFX 문에서 가져옵니다. m_strFilterm_strSort가 비어 있지 않으면 WHERE 및/또는 ORDER BY 절을 추가합니다.
3* 전체 SELECT 문이지만 WHERE 또는 ORDER BY 절이 없습니다. 전달된 그대로입니다. m_strFilterm_strSort가 비어 있지 않으면 WHERE 및/또는 ORDER BY 절을 추가합니다.
4* WHERE 또는 ORDER BY 절을 포함하는 전체 SELECT 전달된 그대로입니다. m_strFilter 및/또는 m_strSort가 비어 있거나 두 개의 필터 및/또는 정렬 문이 생성됩니다.
5 * 저장 프로시저 호출 전달된 그대로입니다.

* m_nFieldsSELECT 문에 지정된 열 수보다 작거나 같아야 합니다. SELECT 문에 지정된 각 열의 데이터 형식은 해당 RFX 출력 열의 데이터 형식과 동일해야 합니다.

사례 1 lpszSQL = NULL

레코드 집합 선택은 CRecordset::Open이 호출할 때 GetDefaultSQL이 반환하는 항목에 따라 달라집니다. 사례 2~5는 가능한 문자열을 설명합니다.

사례 2 lpszSQL = 테이블 이름

레코드 집합은 RFX(레코드 필드 교환)를 사용하여 레코드 집합 클래스의 DoFieldExchange 재정의에 있는 RFX 함수 호출에 제공된 열 이름에서 열 목록을 빌드합니다. 마법사를 사용하여 레코드 집합 클래스를 선언한 경우 이 사례의 결과는 사례 1과 동일합니다(마법사에서 지정한 것과 동일한 테이블 이름을 전달하는 경우). 마법사를 사용하여 클래스를 작성하지 않는 경우 사례 2는 SQL 문을 생성하는 가장 간단한 방법입니다.

다음 예제에서는 MFC 데이터베이스 애플리케이션에서 레코드를 선택하는 SQL 문을 생성합니다. 프레임워크가 GetDefaultSQL 멤버 함수를 호출하면 함수는 테이블의 이름 SECTION을 반환합니다.

CString CEnrollSet::GetDefaultSQL()
{
    return "SECTION";
}

SQL SELECT 문의 열 이름을 가져오기 위해 프레임워크는 DoFieldExchange 멤버 함수를 호출합니다.

void CEnrollSet::DoFieldExchange(CFieldExchange* pFX)
{
    pFX->SetFieldType(CFieldExchange::outputColumn);
    RFX_Text(pFX, "CourseID", m_strCourseID);
    RFX_Text(pFX, "InstructorID", m_strInstructorID);
    RFX_Text(pFX, "RoomNo", m_strRoomNo);
    RFX_Text(pFX, "Schedule", m_strSchedule);
    RFX_Text(pFX, "SectionNo", m_strSectionNo);
}

완료되면 SQL 문은 다음과 같습니다.

SELECT CourseID, InstructorID, RoomNo, Schedule, SectionNo
    FROM SECTION

사례 3 lpszSQL = SELECT/FROM 문

RFX를 사용하여 열 목록을 자동으로 생성하는 대신, 열 목록을 직접 지정합니다. 다음과 같은 경우 이렇게 작업하려고 할 수 있습니다.

  • SELECT 다음에 DISTINCT 키워드를 지정하려고 합니다.

    열 목록은 DoFieldExchange에 나열된 것과 동일한 순서로 열 이름 및 형식과 일치해야 합니다.

  • RFX를 사용하여 열을 바인딩하고 검색하는 대신 ODBC 함수 ::SQLGetData를 사용하여 열 값을 수동으로 검색해야 할 이유가 있습니다.

    예를 들어 애플리케이션이 배포된 후 애플리케이션 고객이 데이터베이스 테이블에 추가한 새 열을 수용하려고 할 수 있습니다. 마법사를 사용하여 클래스를 선언할 때 알려지지 않은 이러한 추가 필드 데이터 멤버를 추가해야 합니다.

    열 목록은 DoFieldExchange에 나열된 것과 동일한 순서로 열 이름 및 형식과 일치해야 하며 수동으로 바인딩된 열 이름이 뒤에 나옵니다. 자세한 내용은 레코드 집합: 데이터 열 동적 바인딩(ODBC)을 참조하세요.

  • FROM 절에 여러 테이블을 지정하여 테이블을 조인하려고 합니다.

    자세한 내용 및 예제는 레코드 집합: 조인 수행(ODBC)을 참조하세요.

사례 4 lpszSQL = SELECT/FROM과 WHERE 및/또는 ORDER BY

열 목록(DoFieldExchange의 RFX 호출 기준), 테이블 목록 및 WHERE 및/또는 ORDER BY 절의 내용을 모두 지정합니다. 이러한 방식으로 WHERE 및/또는 ORDER BY 절을 지정하는 경우 m_strFilter 및/또는 m_strSort를 사용하지 마세요.

사례 5 lpszSQL = 저장 프로시저 호출

미리 정의된 쿼리(예: Microsoft SQL Server 데이터베이스의 저장 프로시저)를 호출해야 하는 경우 lpszSQL에 전달하는 문자열에 CALL 문을 작성해야 합니다. 마법사는 미리 정의된 쿼리를 호출하기 위한 레코드 집합 클래스 선언을 지원하지 않습니다. 미리 정의된 모든 쿼리가 레코드를 반환하는 것은 아닙니다.

미리 정의된 쿼리가 레코드를 반환하지 않는 경우 CDatabase 멤버 함수 ExecuteSQL을 직접 사용할 수 있습니다. 레코드를 반환하는 미리 정의된 쿼리의 경우 프로시저가 반환하는 열에 대해 DoFieldExchange에서 RFX 호출을 수동으로 작성해야 합니다. RFX 호출은 동일한 순서여야 하며 미리 정의된 쿼리와 동일한 형식을 반환해야 합니다. 자세한 내용은 레코드 집합: 미리 정의된 쿼리에 대한 클래스 선언(ODBC)을 참조하세요.

참고 항목

SQL: SQL 및 C++ 데이터 형식(ODBC)
SQL: SQL 직접 호출(ODBC)