• MySQL매뉴얼
    • MySQL 5.6 매뉴얼
    • MySQL 5.1 매뉴얼
    • MySQL 5.0 매뉴얼
    • MySQL HA 매뉴얼
  • 기술문서
    • Xtrabackup 구성
    • 메모리 사용량 모니터링
  • 라이선스
  • 온라인문의
  • 회사소개
  • → 목 록 (MySQL5.6 한글메뉴얼) [close]
  • 1. MySQL 5.6 새로운 기능
  • 2. MySQL 설치 및 업그레이드
  • 3. MySQL Tutorial
  • 4. MySQL 프로그램
  • 5. MySQL 서버관리
  • 6. 보안
  • 7. 백업 및 복구
  • 8. 최적화
  • 9. Language Structure(언어구조)
  • 10. Character Sets(Globalization)
  • 11. 데이터형(Data Types)
  • 12. 함수와 연산자
  • 13. SQL 문법
  • 14. InnoDB 스토리지 엔진
  • 15. 기타 스토리지 엔진
  • 16. 고가용성 및 확장성
  • 17. 리플리케이션
  • 18. MySQL Cluster
  • 19. 파티셔닝
  • 20. Stored Programs and Views
  • 21. INFORMATION_SCHEMA
  • 22. PERFORMANCE SCHEMA
  • 23. 컨넥터 및 API
  • 1. MySQL Connector / ODBC
    2. MySQL Connector/Net
    3. MySQL Connector/J
    4. MySQL Connector/C++
    5. MySQL Connector/C
    6. MySQL Connector/Python
    7. libmysqld, the Embedded MySQL Server Library
    8. MySQL C API
    1. MySQL C API 구현
    2. MySQL Server MySQL Connector/C 동시 설치
    3. C API 클라이언트 프로그램 예제
    4. Building and Running C API Client Programs
    5. C API Data 구조
    6. C API Function 개요
    7. C API Function 설명
    8. C API Prepared Statements
    9. C API Prepared Statement Data 구조
    10. C API Prepared Statement 함수 개요
    11. C API Prepared Statement 함수 설명
    12. C API Threaded 함수 설명
    13. C API 임베디드 서버 함수 설명
    14. C API Client Plugin 함수
    15. C API를 사용하는 경우 일반적인 질문과 문제
    16. 자동 재 연결 동작 제어
    17. 여러 명령문 실행 C API 지원
    18. C API Prepared Statement 문제
    19. C API Prepared Statement date 및 time 값 처리
    20. C API의 Prepared CALL Statements 지원
    9. MySQL PHP API
    10. MySQL Perl API
    11. MySQL Python API
    12. MySQL Ruby APIs
    13. MySQL Tcl API
    14. MySQL Eiffel Wrapper
  • 24. MySQL 확장
  • 25. MySQL Enterprise Edition
  • 26. MySQL Workbench
  • 27. 제약 및 제한
  • 28. MySQL 5.7 새로운 기능

23.8.20 C API의 Prepared CALL Statements 지원

이 섹션에서는 CALL 문을 사용하여 실행되는 저장 프로 시저에 대한 C API의 프리 페 아드 스테이트먼트의 지원에 대해 설명합니다.

MySQL 5.6에서는 Prepared CALL Statements을 사용하여 실행되는 저장 프로 시저를 다음과 같이 사용할 수 있습니다.

  • 저장 프로 시저는 임의의 수의 결과 세트를 생성 할 수 있습니다. 컬럼의 수와 컬럼의 데이터 유형은 모든 결과 세트에 대해 동일 할 필요는 없습니다.

  • OUT 및 INOUT 파라미터의 최종 값은 프로 시저가 돌아온 뒤에 호출 응용 프로그램에서 사용할 수 있습니다. 이러한 매개 변수는 프로 시저 자체에 의해 생성 된 결과 집합에 이어 특별한 단일 행 결과 집합으로 반환됩니다. 행에는 OUT 및 INOUT 매개 변수가 프로 시저 매개 변수 목록에서 선언 된 순서대로 포함됩니다.

다음의 설명에 Prepared Statement에 대해 C API에서 이러한 기능을 사용하는 방법을 보여줍니다. PREPARE 및 EXECUTE 문에서 Prepared CALL 문을 사용하려면 섹션 13.2.1 "CALL 구문" 을 참조하십시오.

응용 프로그램이 5.5.3 이전의 MySQL 버전이 사용 된 문맥으로 컴파일 또는 실행되고있을 가능성이있는 경우 여러 결과 세트의 Prepared CALL 기능 및 OUT 또는 INOUT 매개 변수를 사용하지 못할 수 있습니다.

  • 클라이언트 측 라이브러리가 MySQL 5.5.3 이상하지 않으면, 응용 프로그램은 컴파일되지 않습니다 (버전에서 도입 된 API 함수 및 기호가 존재하지 않습니다).

  • 서버가 완전히 새로운 것을 실행시 확인하려면 클라이언트에서이 테스트를 사용할 수 있습니다.

    if (mysql_get_server_version(mysql) < 50503)
    {
      fprintf(stderr,
              "Server does not support required CALL capabilities\n");
      mysql_close(mysql);
      exit (1);
    }
    

Prepared CALL 문을 실행하는 응용 프로그램은 결과를 가져 와서 다음 mysql_stmt_next_result() 를 호출 해, 그 이상의 결과가 있는지를 판단하는 루프를 사용하십시오. 결과는 저장 프로 시저에 의해 생성 된 결과 세트와 거기에 계속되는 시저가 성공적으로 완료되었는지 여부를 나타내는 최종 상태 값으로 구성됩니다.

프로 시저에 OUT 또는 INOUT 매개 변수가있는 경우 최종 상태 값 이전 결과 세트에 그 값이 저장됩니다. 결과 세트 매개 변수 값이 저장되어 있는지를 판단하려면 MYSQL 연결 처리기의 server_status 멤버에 SERVER_PS_OUT_PARAMS 비트가 설정되어 있는지 여부를 테스트합니다.

mysql->server_status & SERVER_PS_OUT_PARAMS

다음 예제에서는 Prepared CALL 문을 사용하여 여러 결과 집합을 생성하여 OUT 및 INOUT 매개 변수를 사용하여 호출에 매개 변수 값을 반환하는 저장 프로 시저를 실행하고 있습니다. 시저는 세 가지 형태 ( IN , OUT , INOUT )의 매개 변수를 취하여 그 초기 값을 표시하고 새 값을 할당 업데이트 된 값을 표시하고 돌아갑니다. 따라서 프로 시저에서 예상되는 리턴 정보는 여러 결과 세트와 최종 상태에서 구성됩니다.

  • 초기 파라미터 값 ( 10 , NULL , 30 )를 표시하는 SELECT 에서 하나의 결과 집합. ( OUT 매개 변수는 호출자가 값이 할당되지만이 할당 해제 될 것으로 예상됩니다. OUT 매개 변수는 프로 시저에서 값을 할당하기 전까지 프로 시저에서 NULL 로 간주됩니다.)

  • 변경된 매개 변수 값 ( 100 , 200 , 300 )를 표시하는 SELECT 에서 하나의 결과 집합.

  • 최종 OUT 및 INOUT 매개 변수 값 ( 200 , 300 )를 포함하는 1 개의 결과 세트.

  • 최종 상태 패킷.

프로 시저를 실행하는 코드 :

MYSQL_STMT *stmt;
MYSQL_BIND ps_params[3];  /* input parameter buffers */
int        int_data[3];   /* input/output values */
my_bool    is_null[3];    /* output value nullability */
int        status;

/* set up stored procedure */
status = mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
test_error(mysql, status);

status = mysql_query(mysql,
  "CREATE PROCEDURE p1("
  "  IN p_in INT, "
  "  OUT p_out INT, "
  "  INOUT p_inout INT) "
  "BEGIN "
  "  SELECT p_in, p_out, p_inout; "
  "  SET p_in = 100, p_out = 200, p_inout = 300; "
  "  SELECT p_in, p_out, p_inout; "
  "END");
test_error(mysql, status);

/* initialize and prepare CALL statement with parameter placeholders */
stmt = mysql_stmt_init(mysql);
if (!stmt)
{
  printf("Could not initialize statement\n");
  exit(1);
}
status = mysql_stmt_prepare(stmt, "CALL p1(?, ?, ?)", 16);
test_stmt_error(stmt, status);

/* initialize parameters: p_in, p_out, p_inout (all INT) */
memset(ps_params, 0, sizeof (ps_params));

ps_params[0].buffer_type = MYSQL_TYPE_LONG;
ps_params[0].buffer = (char *) &int_data[0];
ps_params[0].length = 0;
ps_params[0].is_null = 0;

ps_params[1].buffer_type = MYSQL_TYPE_LONG;
ps_params[1].buffer = (char *) &int_data[1];
ps_params[1].length = 0;
ps_params[1].is_null = 0;

ps_params[2].buffer_type = MYSQL_TYPE_LONG;
ps_params[2].buffer = (char *) &int_data[2];
ps_params[2].length = 0;
ps_params[2].is_null = 0;

/* bind parameters */
status = mysql_stmt_bind_param(stmt, ps_params);
test_stmt_error(stmt, status);

/* assign values to parameters and execute statement */
int_data[0]= 10;  /* p_in */
int_data[1]= 20;  /* p_out */
int_data[2]= 30;  /* p_inout */

status = mysql_stmt_execute(stmt);
test_stmt_error(stmt, status);

/* process results until there are no more */
do {
  int i;
  int num_fields;       /* number of columns in result */
  MYSQL_FIELD *fields;  /* for result set metadata */
  MYSQL_BIND *rs_bind;  /* for output buffers */

  /* the column count is > 0 if there is a result set */
  /* 0 if the result is only the final status packet */
  num_fields = mysql_stmt_field_count(stmt);

  if (num_fields > 0)
  {
    /* there is a result set to fetch */
    printf("Number of columns in result: %d\n", (int) num_fields);

    /* what kind of result set is this? */
    printf("Data: ");
    if(mysql->server_status & SERVER_PS_OUT_PARAMS)
      printf("this result set contains OUT/INOUT parameters\n");
    else
      printf("this result set is produced by the procedure\n");

    MYSQL_RES *rs_metadata = mysql_stmt_result_metadata(stmt);
    test_stmt_error(stmt, rs_metadata == NULL);

    fields = mysql_fetch_fields(rs_metadata);

    rs_bind = (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
    if (!rs_bind)
    {
      printf("Cannot allocate output buffers\n");
      exit(1);
    }
    memset(rs_bind, 0, sizeof (MYSQL_BIND) * num_fields);

    /* set up and bind result set output buffers */
    for (i = 0; i < num_fields; ++i)
    {
      rs_bind[i].buffer_type = fields[i].type;
      rs_bind[i].is_null = &is_null[i];

      switch (fields[i].type)
      {
        case MYSQL_TYPE_LONG:
          rs_bind[i].buffer = (char *) &(int_data[i]);
          rs_bind[i].buffer_length = sizeof (int_data);
          break;

        default:
          fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
          exit(1);
      }
    }

    status = mysql_stmt_bind_result(stmt, rs_bind);
    test_stmt_error(stmt, status);

    /* fetch and display result set rows */
    while (1)
    {
      status = mysql_stmt_fetch(stmt);

      if (status == 1 || status == MYSQL_NO_DATA)
        break;

      for (i = 0; i < num_fields; ++i)
      {
        switch (rs_bind[i].buffer_type)
        {
          case MYSQL_TYPE_LONG:
            if (*rs_bind[i].is_null)
              printf(" val[%d] = NULL;", i);
            else
              printf(" val[%d] = %ld;",
                     i, (long) *((int *) rs_bind[i].buffer));
            break;

          default:
            printf("  unexpected type (%d)\n",
              rs_bind[i].buffer_type);
        }
      }
      printf("\n");
    }

    mysql_free_result(rs_metadata); /* free metadata */
    free(rs_bind);                  /* free output buffers */
  }
  else
  {
    /* no columns = final status packet */
    printf("End of procedure output\n");
  }

  /* more results? -1 = no, >0 = error, 0 = yes (keep looking) */
  status = mysql_stmt_next_result(stmt);
  if (status > 0)
    test_stmt_error(stmt, status);
} while (status == 0);

mysql_stmt_close(stmt);

프로 시저를 실행하면 다음과 같은 출력이 생성됩니다.

Number of columns in result: 3
Data: this result set is produced by the procedure
 val[0] = 10; val[1] = NULL; val[2] = 30;
Number of columns in result: 3
Data: this result set is produced by the procedure
 val[0] = 100; val[1] = 200; val[2] = 300;
Number of columns in result: 2
Data: this result set contains OUT/INOUT parameters
 val[0] = 200; val[1] = 300;
End of procedure output

이 코드는 두 개의 유틸리티 루틴 test_error() 및 test_stmt_error() 를 사용하여 오류를 확인하고 오류가 발생한 경우 진단 정보를 출력 한 후에 종료합니다.

static void test_error(MYSQL *mysql, int status)
{
  if (status)
  {
    fprintf(stderr, "Error: %s (errno: %d)\n",
            mysql_error(mysql), mysql_errno(mysql));
    exit(1);
  }
}

static void test_stmt_error(MYSQL_STMT *stmt, int status)
{
  if (status)
  {
    fprintf(stderr, "Error: %s (errno: %d)\n",
            mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
    exit(1);
  }
}


서울시 강남구 영동대로 602 6층
TEL: 02-6061-0006  /  E: csr@mysqlkorea.com
주식회사 이노클러스터  등록번호 : 727-86-02261
Copyright © innocluster Co. ltd. all rights reserved