이 문서는 지원되지 않는 PostgreSQL 버전에 대한 것입니다.
당신은 다음과 같은 페이지를 보고 싶을 수도 있습니다.현재버전 또는 위에 나열된 다른 지원 버전 중 하나를 사용하세요.

비동기 사설 토토 처리

PQexec 기능은 간단한 사설 토토를 제출하는 데 적합합니다. 동기식 애플리케이션. 몇 가지 주요 결함이 있습니다. 그러나:

  • PQexec는 사설 토토가 완료될 때까지 기다립니다. 응용 프로그램 다른 작업을 수행해야 할 수도 있습니다(예: 사용자 유지 관리). 인터페이스), 이 경우 대기를 차단하고 싶지 않을 것입니다. 응답.

  • 제어권이 PQexec 내부에 묻혀 있기 때문에 프론트엔드에서 진행 중인 작업을 취소하려고 하는지 결정합니다. 사설 토토. (신호 처리기에서 수행할 수 있지만 그렇지 않으면.)

  • PQexec는 하나의 PGresult 구조만 반환할 수 있습니다. 만약 제출된 사설 토토 문자열에는 여러 SQL 명령이 포함되어 있지만 모두 마지막 PGresult는 PQexec에 의해 삭제됩니다.

이러한 제한이 마음에 들지 않는 응용 프로그램은 대신 다음을 사용할 수 있습니다. PQexec가 구축된 기본 함수: PQsendQuery 및 PQgetResult.

  • PQsendQuery다음에 쿼리를 제출하세요.포스트그레기다리지 않고 결과. 쿼리가 성공적으로 수행되면 TRUE가 반환됩니다. 전달되지 않으면 FALSE입니다(이 경우 PQerrorMessage를 사용하여 실패에 대한 자세한 정보를 얻으세요).

    int PQsendQuery(PGconn *conn,
                    const char *쿼리);
    PQsendQuery를 성공적으로 호출한 후 PQgetResult를 호출하십시오. 또는 쿼리 결과를 얻기 위해 여러 번. PQsendQuery가 아닐 수도 있습니다. PQgetResult가 완료될 때까지 (동일한 연결에서) 다시 호출됩니다. 쿼리가 완료되었음을 나타내는 NULL을 반환했습니다.
  • PQgetResult다음을 기다리세요 이전 PQsendQuery의 결과를 반환합니다. NULL은 쿼리가 완료되고 더 이상 쿼리가 없을 때 반환됩니다. 결과.

    PGresult *PQgetResult(PGconn *conn);
    PQgetResult는 NULL을 반환할 때까지 반복적으로 호출되어야 합니다. 쿼리가 완료되었음을 나타냅니다. (쿼리가 없을 때 호출되는 경우 활성화된 경우 PQgetResult는 한 번에 NULL을 반환합니다.) Null이 아닌 각 PQgetResult의 결과는 동일한 PGresult를 사용하여 처리되어야 합니다. 이전에 설명한 접근자 기능. 각각을 해제하는 것을 잊지 마세요 작업이 완료되면 PQclear를 사용하여 결과 객체를 생성합니다. PQgetResult에 유의하세요. 쿼리가 활성화되어 있고 필요한 응답이 있는 경우에만 차단됩니다. PQconsumeInput이 아직 데이터를 읽지 않았습니다.

PQsendQuery 및 PQgetResult를 사용하면 PQexec의 문제 중 하나를 해결합니다. 문제: 쿼리 문자열에 여러 SQL 명령이 포함된 경우 해당 명령의 결과는 개별적으로 얻을 수 있습니다. (이 그런데 간단한 형태의 중첩 처리가 가능합니다. 프론트엔드는 하나의 쿼리 결과를 처리하는 반면 백엔드는 동일한 쿼리 문자열에서 이후 쿼리를 계속 작업 중입니다.) 그러나 PQgetResult를 호출하면 여전히 프런트엔드가 차단됩니다. 백엔드가 다음 SQL 명령을 완료할 때까지. 이것은 세 가지 추가 기능을 적절하게 사용하면 피할 수 있습니다.

  • PQconsumeInput입력이 다음과 같은 경우 백엔드에서 사용할 수 있으므로 사용하세요.

    int PQconsumeInput(PGconn *conn);
    PQconsumeInput은 일반적으로 "오류 없음"을 나타내는 1을 반환하지만 어떤 종류의 문제가 있는 경우 0을 반환합니다. PQerrorMessage가 설정되었습니다). 결과는 여부를 알려주지 않습니다. 모든 입력 데이터가 실제로 수집되었습니다. 전화 후 PQconsumeInput, 애플리케이션은 PQisBusy 및/또는 확인할 수 있습니다. PQ는 상태가 변경되었는지 확인합니다. PQconsumeInput은 다음과 같습니다. 애플리케이션이 처리할 준비가 되지 않은 경우에도 호출됩니다. 아직 결과나 알림이 없습니다. 루틴을 읽을 수 있습니다. 데이터를 버퍼에 저장하여 select(2)가 발생합니다. 떠날 준비가 되었다는 표시. 따라서 응용 프로그램은 다음을 사용할 수 있습니다. PQconsumeInput을 사용하여 선택 조건을 즉시 삭제한 다음 여유롭게 결과를 검토해 보세요.
  • PQisBusy쿼리인 경우 TRUE를 반환합니다. 바쁜 경우, 즉 PQgetResult는 입력 대기를 차단합니다. 에이 FALSE 반환은 PQgetResult가 다음과 같이 호출될 수 있음을 나타냅니다. 차단하지 않는다는 보장.

    int PQisBusy(PGconn *conn);
    PQisBusy는 자체적으로 데이터 읽기를 시도하지 않습니다. 백엔드; 따라서 PQconsumeInput을 먼저 호출해야 합니다. 바쁜 상태는 끝나지 않을 것입니다.
  • PQsocket파일 획득 백엔드 연결 소켓의 설명자 번호입니다. 유효한 설명자는 = 0입니다. -1의 결과는 없음을 나타냅니다. 백엔드 연결이 현재 열려 있습니다.

    int PQsocket(PGconn *conn);
    PQsocket은 백엔드 소켓을 얻기 위해 사용되어야 합니다 select(2) 실행을 준비하는 디스크립터입니다. 이를 통해 백엔드 응답이나 기타 응답을 기다리는 애플리케이션 조건. select(2)의 결과가 데이터를 백엔드 소켓에서 읽은 다음 PQconsumeInput을 호출해야 합니다. 데이터를 읽으려면; 그 이후에는 PQisBusy, PQgetResult 및/또는 PQnotify를 사용하여 응답을 처리할 수 있습니다.

이러한 기능을 사용하는 일반적인 프런트엔드는 메인 루프를 갖습니다. select(2)를 사용하여 필요한 모든 조건을 기다립니다. 응답하다. 조건 중 하나가 다음에서 입력됩니다. 백엔드(select의 용어로 파일에서 읽을 수 있는 데이터) PQsocket으로 식별되는 설명자입니다. 메인 루프가 입력을 감지하면 준비가 되면 PQconsumeInput을 호출하여 입력을 읽어야 합니다. 그러면 가능하다 PQisBusy를 호출하고, PQisBusy가 FALSE를 반환하면 PQgetResult를 호출합니다. 또한 PQnotify를 호출하여 NOTIFY 메시지를 감지할 수도 있습니다(참조: "비동기 알림"(아래). 예는 샘플 프로그램 섹션.

PQsendQuery/PQgetResult를 사용하는 프런트엔드는 다음을 시도할 수도 있습니다. 백엔드에서 아직 처리 중인 쿼리를 취소합니다.

  • PQ요청취소요청하세요포스트그레스처리 포기 현재 쿼리입니다.

    int PQrequestCancel(PGconn *conn);
    취소 요청이 다음과 같은 경우 반환 값은 TRUE입니다. 성공적으로 발송되었습니다. 그렇지 않은 경우 FALSE입니다. (그렇지 않은 경우 PQerrorMessage 이유를 알려드립니다.) 성공적인 배송이 배송을 보장하지 않습니다. 그러나 요청은 아무런 영향을 미치지 않습니다. 반품 여부와 상관없이 PQrequestCancel 값이 있는 경우 애플리케이션은 다음 작업을 계속해야 합니다. PQgetResult를 사용한 일반적인 결과 읽기 시퀀스. 만약 취소가 유효하면 현재 쿼리가 일찍 종료됩니다. 오류 결과를 반환합니다. 취소에 실패한 경우(예: 백엔드가 이미 쿼리 처리를 완료한 경우) 전혀 눈에 띄는 결과가 없습니다.

현재 쿼리가 트랜잭션의 일부인 경우, 취소하면 전체 거래가 중단됩니다.

PQrequestCancel은 신호 처리기에서 안전하게 호출할 수 있습니다. 그래서, 다음과 같은 경우에는 일반 PQexec와 함께 사용할 수도 있습니다. 취소 결정은 신호 처리기에서 이루어질 수 있습니다. 에 대한 예를 들어, psql은 SIGINT 신호 처리기에서 PQrequestCancel을 호출합니다. 따라서 발행된 쿼리를 대화형으로 취소할 수 있습니다. PQexec를 통해. PQrequestCancel은 다음과 같은 경우에는 아무런 효과가 없습니다. 연결이 현재 열려 있지 않거나 백엔드가 열려 있지 않습니다. 현재 쿼리를 처리 중입니다.