第11章 MySQL API

目次

11.1. MySQL C API
11.1.1. C API データ型
11.1.2. C API 関数の概要
11.1.3. C API 関数の説明
11.1.4. C API のプリペアドステートメント
11.1.5. C API のプリペアドステートメントのデータ型
11.1.6. C API のプリペアドステートメント関数の概要
11.1.7. C API のプリペアドステートメント関数の説明
11.1.8. C API における複数クエリの実行の取り扱い
11.1.9. C API における日付値および時刻値の取り扱い
11.1.10. C API スレッド関数の説明
11.1.11. C API 組み込みサーバ関数の説明
11.1.12. C API の使用に関する一般的な質問および問題
11.1.13. クライアントプログラムのビルド
11.1.14. スレッドクライアントの作成方法
11.1.15. 組み込み MySQL サーバライブラリ libmysqld
11.2. MySQL の ODBC サポート
11.2.1. MyODBC のインストール方法
11.2.2. ODBC アドミニストレータのフィールドの設定方法
11.2.3. MyODBC の接続パラメータ
11.2.4. MyODBC に関する問題を報告する方法
11.2.5. MyODBC と連携して動作することが知られているプログラム
11.2.6. ODBC で AUTO_INCREMENT 属性を持つカラムの値を取得する方法
11.2.7. MyODBC に関する問題の報告
11.3. MySQL の Java 接続(JDBC)
11.4. MySQL PHP API
11.4.1. MySQL および PHP のよくある問題
11.5. MySQL Perl API
11.5.1. DBIDBD::mysql
11.5.2. DBI インタフェース
11.5.3. DBI/DBD に関するその他の情報
11.6. MySQL C++ API
11.6.1. Borland C++
11.7. MySQL Python API
11.8. MySQL Tcl API
11.9. MySQL Eiffel Wrapper

この章では、MySQL で使用できる API の入手場所および使用方法について説明します。最も豊富な種類が用意されているのが C API です。これは MySQL チームが開発しています。他言語向けの API は、この C API をベースにして開発されています。

11.1. MySQL C API

C API コードは、MySQL とともに配布されています。C API コードは mysqlclient ライブラリに格納され、C プログラムはこのコードを使用してデータベースにアクセスできます。

MySQL のソースディストリビューションに含まれるクライアントの多くは C で記述されています。C API の使用方法がわかるようなコード例を探している場合は、これらのクライアントを参考にしてください。クライアントは、MySQL ソースディストリビューションの clients ディレクトリに格納されています。

他のクライアント API(Connector/J を除くすべての API)の多くは、mysqlclient ライブラリを使用して MySQL サーバと通信します。このライブラリを使用すると、たとえば環境変数を参照できるので、他のクライアントプログラムとほとんどの環境変数を共用できることになります。共用できる環境変数の一覧については、項4.9. 「MySQL クライアントサイドのスクリプトとユーティリティ」 を参照してください。

クライアントが使用できる通信バッファサイズには上限があります。内部的に割り当てられているバッファサイズ(16 キロバイト)は、最大 16 メガバイトまで自動的に増加します。バッファサイズが増加するのはバッファの要求量が増加した場合だけであり、デフォルトの最大値を増やしたからといって使用リソースが増加するわけではありません。このサイズチェックでは、誤ったクエリや通信パケットを主にチェックします。

通信バッファサイズは、SQL ステートメント 1 つ(クライアントからサーバへのトラフィック)および結果データ 1 行(サーバからクライアントへのトラフィック)を格納できるだけの大きさが必要です。各スレッドの通信バッファは、クエリやレコードを処理できるように、その最大値まで動的に拡大されます。たとえば、最大 16 メガバイトのデータを格納する BLOB 値を処理する場合、通信バッファサイズの最大値は(サーバとクライアントの両方で)少なくとも 16 メガバイトである必要があります。クライアントのデフォルトの最大値は 16 メガバイトですが、サーバのデフォルトの最大値は 1 メガバイトです。サーバのデフォルトの最大値を増やすには、サーバの起動時に max_allowed_packet の値を変更します。 See 項5.5.2. 「サーバパラメータのチューニング」

MySQL サーバは、クエリが終わるたびに通信バッファサイズを net_buffer_length に減らします。クライアント側では、接続が切断されてメモリが解放されるまで、その接続に割り当てられたバッファサイズが減ることはありません。

スレッドを使用するプログラミングについては、項11.1.14. 「スレッドクライアントの作成方法」 を参照してください。同一プログラム内に "サーバー" と "クライアント" が存在する(および外部の MySQL サーバと通信しない)スタンドアロンアプリケーションの作成については、項11.1.15. 「組み込み MySQL サーバライブラリ libmysqld」 を参照してください。

11.1.1. C API データ型

  • MYSQL

    この構造体は、1 つのデータベース接続へのハンドルを表す。ほとんどの MySQL 関数で使用される。

  • MYSQL_RES

    この構造体は、レコードを返すクエリ(SELECTSHOWEXPLAINDESCRIBE)の結果を表す。このセクションでは、クエリから返された情報を結果セットと呼ぶ。

  • MYSQL_ROW

    1 行のデータのタイプセーフな表現。現在は、バイト文字列の配列として実装されている(フィールドにはバイナリデータが格納される場合があり、そのようなデータでは内部的にヌルバイトが使用される可能性があるので、バイト文字列をヌル終端文字列として扱うことはできない)。レコードを取得するには、mysql_fetch_row() を呼び出す。

  • MYSQL_FIELD

    この構造体には、フィールドの名前、型、サイズなど、フィールドに関する情報が格納される。メンバの詳細については、以下で説明する。 各フィールドに対して mysql_fetch_field() を繰り返し呼び出すことによって、対応する MYSQL_FIELD 構造体を取得できる。フィールド値はこの構造体の一部ではなく、MYSQL_ROW 構造体に含まれる。

  • MYSQL_FIELD_OFFSET

    MySQL フィールド一覧に対するオフセットの安全な型表現(mysql_field_seek() が使用)。オフセットはレコード内部でのフィールド番号であり、0 から始まる。

  • my_ulonglong

    レコードの数を表すための型であり、mysql_affected_rows()mysql_num_rows()、および mysql_insert_id() で使用される。0 から 1.84e19 までの範囲の値を表す。

    一部のシステムでは、my_ulonglong 型の値を出力しようとしても、正常に出力されない。この型の値を出力するには、unsigned long に変換して、%lu フォーマットを使用する。以下に例を示す。

    printf ("Number of rows: %lu\n", (unsigned long) mysql_num_rows(result));
    

MYSQL_FIELD 構造体のメンバを以下に示します。

  • char * name

    フィールドの名前。ヌル終端文字列。

  • char * table

    このフィールドが計算結果データのフィールドでない場合、このフィールドが属するテーブルの名前。計算結果データのフィールドの場合、table の値は空文字列になる。

  • char * def

    このフィールドのデフォルト値。ヌル終端文字列。mysql_list_fields() を使用するときだけ設定される。

  • enum enum_field_types type

    フィールドの型。 type の値は次のいずれかになる。

    型の値型の説明
    FIELD_TYPE_TINYTINYINT フィールド
    FIELD_TYPE_SHORTSMALLINT フィールド
    FIELD_TYPE_LONGINTEGER フィールド
    FIELD_TYPE_INT24MEDIUMINT フィールド
    FIELD_TYPE_LONGLONGBIGINT フィールド
    FIELD_TYPE_DECIMALDECIMAL または NUMERIC フィールド
    FIELD_TYPE_FLOATFLOAT フィールド
    FIELD_TYPE_DOUBLEDOUBLE または REAL フィールド
    FIELD_TYPE_TIMESTAMPTIMESTAMP フィールド
    FIELD_TYPE_DATEDATE フィールド
    FIELD_TYPE_TIMETIME フィールド
    FIELD_TYPE_DATETIMEDATETIME フィールド
    FIELD_TYPE_YEARYEAR フィールド
    FIELD_TYPE_STRINGCHAR フィールド
    FIELD_TYPE_VAR_STRINGVARCHAR フィールド
    FIELD_TYPE_BLOBBLOB または TEXT フィールド(max_length を使用して最大長を決定)
    FIELD_TYPE_SETSET フィールド
    FIELD_TYPE_ENUMENUM フィールド
    FIELD_TYPE_NULLNULL 型フィールド
    FIELD_TYPE_CHAR廃止(代わりに FIELD_TYPE_TINY を使用すること)

    IS_NUM() マクロを使用すると、フィールドが数値型かどうかを調べることができる。type の値を IS_NUM() に渡すと、フィールドが数値型の場合は TRUE と評価される。

    if (IS_NUM(field->type))
        printf("Field is numeric\n");
    

  • unsigned int length

    フィールドの幅。テーブル定義で指定された値に従う。

  • unsigned int max_length

    結果セットのフィールドの最大幅(結果セットに実際に存在するレコードのフィールド値の最大長)。mysql_store_result() または mysql_list_fields() を使用した場合、この値はフィールドの最大長を表す。mysql_use_result() を使用した場合、この値は 0 になる。

  • unsigned int flags

    フィールドのさまざまな状態を表すビットフラグ。flags 値は、0 または以下のビットが 1 つ以上設定された値になる。

    フラグの値フラグの説明
    NOT_NULL_FLAGNULL を設定できないフィールド
    PRI_KEY_FLAG主キーの一部を構成するフィールド
    UNIQUE_KEY_FLAG一意なキーの一部を構成するフィールド
    MULTIPLE_KEY_FLAG一意でないキーの一部を構成するフィールド
    UNSIGNED_FLAGUNSIGNED 属性を持つフィールド
    ZEROFILL_FLAGZEROFILL 属性を持つフィールド
    BINARY_FLAGBINARY 属性を持つフィールド
    AUTO_INCREMENT_FLAGAUTO_INCREMENT 属性を持つフィールド
    ENUM_FLAGENUM 型のフィールド(廃止)
    SET_FLAGSET 型のフィールド(廃止)
    BLOB_FLAGBLOB 型または TEXT 型のフィールド(廃止)
    TIMESTAMP_FLAGTIMESTAMP 型のフィールド(廃止)

    BLOB_FLAGENUM_FLAGSET_FLAG、および TIMESTAMP_FLAG の各フラグは、フィールドの属性ではなく型を示しているので、廃止されている。代わりに、field->typeFIELD_TYPE_BLOBFIELD_TYPE_ENUMFIELD_TYPE_SET、または FIELD_TYPE_TIMESTAMP と比較する方が望ましい。

    次に、flags 値の典型的な使用例を示す。

    if (field->flags & NOT_NULL_FLAG)
        printf("Field can't be null\n");
    

    以下のマクロを使用すると、flags 値を調べてブール値で結果を得ることができる。

    フラグの状態説明
    IS_NOT_NULL(flags)このフィールドが NOT NULL として定義されている場合は True。
    IS_PRI_KEY(flags)このフィールドが主キーの場合は True。
    IS_BLOB(flags)このフィールドが BLOB または TEXT の場合は True (廃止。代わりに field->type による比較を推奨)。
  • unsigned int decimals

    数値フィールドの小数部桁数。

11.1.2. C API 関数の概要

ここでは、C API で提供されている関数について簡単に説明します。詳細については、以降のセクションで説明します。 See 項11.1.3. 「C API 関数の説明」

関数説明
mysql_affected_rows()最後に実行された UPDATEDELETE、または INSERT のいずれかのクエリによって変更、削除、または挿入されたレコードの数を返す。
mysql_change_user()オープンされた接続のユーザおよびデータベースを変更する。
mysql_character_set_name()接続のデフォルトのキャラクタセットの名前を返す。
mysql_close()サーバ接続を切断する。
mysql_connect()MySQL サーバに接続する。この関数は廃止されているので、代わりに mysql_real_connect() を使用すること。
mysql_create_db()データベースを作成する。この関数は廃止されているので、代わりに SQL コマンド CREATE DATABASE を使用すること。
mysql_data_seek()クエリ結果セットの任意のレコード番号にシークする。
mysql_debug()指定された文字列で DBUG_PUSH を実行する。
mysql_drop_db()データベースを破棄する。この関数は廃止されているので、代わりに SQL コマンド DROP DATABASE を使用すること。
mysql_dump_debug_info()デバッグ情報をログに書き込むようにサーバに指示する。
mysql_eof()結果セットの最後のレコードが読み込まれたかどうかを判定する。 この関数は廃止されており、代わりに mysql_errno() または mysql_error() を使用できる。
mysql_errno()最後に呼び出された MySQL 関数のエラー番号を返す。
mysql_error()最後に呼び出された MySQL 関数のエラーを返す。
mysql_escape_string()文字列に含まれる特殊文字をエスケープして、SQL ステートメントで使用できるようにする。
mysql_fetch_field()テーブルの次のフィールドの型を返す。
mysql_fetch_field_direct()フィールド番号で指定されたテーブルフィールドの型を返す。
mysql_fetch_fields()すべてのフィールド構造体の配列を返す。
mysql_fetch_lengths()現在のレコードのすべてのカラムについてその長さを返す。
mysql_fetch_row()結果セットの次のレコードを取得する。
mysql_field_seek()指定されたカラムにカラムカーソルを移動する。
mysql_field_count()最後に実行されたクエリの結果セットのカラム数を返す。
mysql_field_tell()最後に実行された mysql_fetch_field() で使用されたフィールドカーソルの位置を返す。
mysql_free_result()結果セットで使用したメモリを解放する。
mysql_get_client_info()クライアントのバージョン情報を文字列として返す。
mysql_get_client_version()クライアントのバージョン情報を整数として返す。
mysql_get_host_info()接続を記述する文字列を返す。
mysql_get_server_version()サーバのバージョン番号を整数として返す(4.1 の新機能)。
mysql_get_proto_info()接続に使用しているプロトコルのバージョンを返す。
mysql_get_server_info()サーバのバージョン番号を返す。
mysql_info()最後に実行されたクエリに関する情報を返す。
mysql_init()MYSQL 構造体を取得または初期化する。
mysql_insert_id()前回実行されたクエリで生成した AUTO_INCREMENT カラムの ID を返す。
mysql_kill()指定されたスレッドを強制終了する。
mysql_list_dbs()単純な正規表現に一致するデータベース名を返す。
mysql_list_fields()単純な正規表現に一致するフィールド名を返す。
mysql_list_processes()現在のサーバスレッドの一覧を返す。
mysql_list_tables()単純な正規表現に一致するテーブル名を返す。
mysql_num_fields()結果セットのカラム数を返す。
mysql_num_rows()結果セットのレコード数を返す。
mysql_options()mysql_connect() の接続オプションを設定する。
mysql_ping()サーバへの接続が正常かどうかを確認し、必要なら再接続する。
mysql_query()ヌル終端文字列として指定されている SQL クエリを実行する。
mysql_real_connect()MySQL サーバに接続する。
mysql_real_escape_string()接続の現在のキャラクタセットを考慮して、文字列に含まれる特殊文字をエスケープし、SQL ステートメントで使用できるようにする。
mysql_real_query()バイト文字列として指定されている SQL クエリを実行する。
mysql_reload()権限テーブルの再読み込みをサーバに指示する。
mysql_row_seek()mysql_row_tell() から返された値をオフセットとして、結果セット内のレコードにシークする。
mysql_row_tell()レコードカーソルの位置を返す。
mysql_select_db()データベースを選択する。
mysql_set_server_option()接続のオプション(multi-statements など)を設定する。
mysql_sqlstate()最後に発生したエラーの SQLSTATE エラーコードを返す。
mysql_shutdown()データベースサーバをシャットダウンする。
mysql_stat()サーバステータスを文字列として返す。
mysql_store_result()結果セット全体を取得してクライアントに転送する。
mysql_thread_id()現在のスレッド ID を返す。
mysql_thread_safe()クライアントがスレッドセーフとしてコンパイルされている場合は 1 を返す。
mysql_use_result()レコード単位の結果セットの取得を開始する。
mysql_warning_count()前回実行した SQL ステートメントの警告数を返す。
mysql_commit()トランザクションをコミットする(4.1 の新機能)。
mysql_rollback()トランザクションをロールバックする(4.1 の新機能)。
mysql_autocommit()自動コミットモードのオン/オフを切り替える(4.1 の新機能)。
mysql_more_results()まだ取得していない結果セットが存在するかどうかを調べる(4.1 の新機能)。
mysql_next_result()マルチクエリを実行している場合、次の結果セットを取得し、返す(4.1 の新機能)。

サーバに接続するには、mysql_init() を呼び出して接続ハンドラを初期化し、次にそのハンドラ(およびホスト名、ユーザ名、パスワードなどのその他の情報)をパラメータとして mysql_real_connect() を呼び出します。接続が確立したとき、mysql_real_connect() によって reconnect フラグ(MYSQL 構造体の一部)の値が 1 に設定されます。このフラグは、接続が切断されてクエリを実行できない場合に、そこでクエリを終了せずに、サーバへの再接続を試みることを意味します。接続が必要なくなったら、mysql_close() を呼び出して接続を切断します。

接続がアクティブな場合、クライアントは mysql_query() または mysql_real_query() を使用してサーバに SQL クエリを送信できます。この 2 つの違いは、mysql_query() はクエリをヌル終端文字列として、mysql_real_query() はクエリをバイト文字列として、それぞれ受け取ります。文字列にバイナリデータが含まれる(ヌルバイトが含まれる可能性がある)場合は、mysql_real_query() を使用する必要があります。

SELECT クエリ(たとえば、INSERTUPDATEDELETE)を実行した場合、変更された(影響を受けた)レコードの数を知るには、mysql_affected_rows() を呼び出します。

SELECT クエリを実行した場合、選択されたレコードを結果セットとして取得します(注意: SHOWDESCRIBE、および EXPLAIN のように、レコードを返すという点で SELECT に似ているステートメントがあり、これらは SELECT ステートメントと同様に扱う必要があります)。

クライアントが結果セットを処理する方法は 2 つあります。1 つは、mysql_store_result() を呼び出して結果セット全体を一括して取得する方法です。この関数は、クエリから返されたすべてのレコードをサーバから取得し、クライアントに保存します。もう 1 つは、mysql_use_result() を呼び出して、クライアントがレコード単位で結果セットの取得を開始する方法です。この関数は結果セットを取得する処理の初期化は行いますが、実際にはサーバからレコードを受け取っていません。

どちらの場合も、レコードにアクセスするには mysql_fetch_row() を呼び出します。mysql_store_result() を使用した場合、mysql_fetch_row() は、すでにサーバから取得されているレコードにアクセスします。mysql_use_result() を使用した場合、mysql_fetch_row() は実際にサーバからレコードを取得します。各レコードのデータサイズは、mysql_fetch_lengths() を呼び出すことによって知ることができます。

結果セットが必要なくなったら、mysql_free_result() を呼び出して、使用していたメモリを解放します。

2 つの取得メカニズムは、状況に応じて使い分けます。クライアントプログラムは、必要に応じて最も適切な方法を選択する必要があります。実際には、mysql_store_result() を多用する傾向があります。

mysql_store_result() の長所は、すべてのレコードがクライアントに取得済みなので、レコードに順次アクセスできるだけでなく、mysql_data_seek() または mysql_row_seek() を使用して結果セット内でのカレントレコードの位置を変更することによって、結果セット内を前後に移動できることです。結果セットに含まれるレコード数を知るには、mysql_num_rows() を呼び出します。一方で、結果セットが大きい場合の mysql_store_result() のメモリ要件は非常に厳しい場合があり、メモリ不足が発生する可能性は高くなります。

mysql_use_result() の長所は、一度に 1 行のレコードしか保持しないので、クライアントが結果セットで使用するメモリが少なくてすむことです(また、メモリ割り当てのオーバヘッドが少ないので mysql_use_result() の実行速度も向上します)。短所は、サーバを拘束しないように各レコードに対する処理を短時間で終わらせる必要があること、結果セット内のレコードに対するランダムアクセス機能がないこと(順次アクセスのみ)、すべてのレコードを取得するまで結果セットに含まれるレコード数がわからないことです。さらに、探していた情報が順次アクセスの途中で見つかった場合でも、最後まですべてのレコードを取得する必要があります

クライアントは API を使用することで、クエリが SELECT かどうかがわからなくても、クエリに対して適切に応答する(必要に応じてレコードを取得する)ことができます。そのためには、mysql_query()(または mysql_real_query())を呼び出すたびに mysql_store_result() を呼び出します。この呼び出しが正常終了した場合、クエリは SELECT だったことになり、レコードを読み込むことができます。呼び出しが失敗した場合、mysql_field_count() を呼び出して、この結果がクエリの結果として予想されたものだったかどうかを判断します。mysql_field_count() が 0 を返した場合、クエリが返したデータはなく(INSERTUPDATEDELETE などのクエリだったことを意味する)、レコードを返すクエリではなかったと判断されます。mysql_field_count() が 0 以外の値を返した場合、レコードを返すはずのクエリが実行されたけれども、何も返さなかったと判断されます。これは、SELECT クエリが失敗したことを意味します。ここに示した方法のコーディング例については、mysql_field_count() の説明を参照してください。

mysql_store_result() および mysql_use_result() はどちらも、結果セットを構成するフィールドに関する情報(フィールドの数、名前、型など)を取得します。レコードのフィールド情報に順次アクセスするには、mysql_fetch_field() を繰り返し呼び出すか、またはレコードのフィールド番号を指定して mysql_fetch_field_direct() を呼び出します。現在のフィールドカーソルの位置を変更するには、mysql_field_seek() を呼び出します。フィールドカーソルの位置を変更すると、その後に呼び出された mysql_fetch_field() の動作に影響を与えます。mysql_fetch_fields() を呼び出すと、すべてのフィールドの情報を一括して取得できます。

エラーを検出し、報告する場合、mysql_errno() および mysql_error() を使用してエラー情報にアクセスします。この 2 つの関数は、最後に呼び出された、成功または失敗の可能性のある関数のエラーコードまたはエラーメッセージを返します。この結果によって、エラーが発生したタイミングとその内容を判断します。

11.1.3. C API 関数の説明

11.1.3.1. mysql_affected_rows()
11.1.3.2. mysql_change_user()
11.1.3.3. mysql_character_set_name()
11.1.3.4. mysql_close()
11.1.3.5. mysql_connect()
11.1.3.6. mysql_create_db()
11.1.3.7. mysql_data_seek()
11.1.3.8. mysql_debug()
11.1.3.9. mysql_drop_db()
11.1.3.10. mysql_dump_debug_info()
11.1.3.11. mysql_eof()
11.1.3.12. mysql_errno()
11.1.3.13. mysql_error()
11.1.3.14. mysql_escape_string()
11.1.3.15. mysql_fetch_field()
11.1.3.16. mysql_fetch_fields()
11.1.3.17. mysql_fetch_field_direct()
11.1.3.18. mysql_fetch_lengths()
11.1.3.19. mysql_fetch_row()
11.1.3.20. mysql_field_count()
11.1.3.21. mysql_field_seek()
11.1.3.22. mysql_field_tell()
11.1.3.23. mysql_free_result()
11.1.3.24. mysql_get_client_info()
11.1.3.25. mysql_get_client_version()
11.1.3.26. mysql_get_host_info()
11.1.3.27. mysql_get_proto_info()
11.1.3.28. mysql_get_server_info()
11.1.3.29. mysql_get_server_version()
11.1.3.30. mysql_info()
11.1.3.31. mysql_init()
11.1.3.32. mysql_insert_id()
11.1.3.33. mysql_kill()
11.1.3.34. mysql_list_dbs()
11.1.3.35. mysql_list_fields()
11.1.3.36. mysql_list_processes()
11.1.3.37. mysql_list_tables()
11.1.3.38. mysql_num_fields()
11.1.3.39. mysql_num_rows()
11.1.3.40. mysql_options()
11.1.3.41. mysql_ping()
11.1.3.42. mysql_query()
11.1.3.43. mysql_real_connect()
11.1.3.44. mysql_real_escape_string()
11.1.3.45. mysql_real_query()
11.1.3.46. mysql_reload()
11.1.3.47. mysql_row_seek()
11.1.3.48. mysql_row_tell()
11.1.3.49. mysql_select_db()
11.1.3.50. mysql_set_server_option()
11.1.3.51. mysql_shutdown()
11.1.3.52. mysql_sqlstate()
11.1.3.53. mysql_ssl_set()
11.1.3.54. mysql_stat()
11.1.3.55. mysql_store_result()
11.1.3.56. mysql_thread_id()
11.1.3.57. mysql_use_result()
11.1.3.58. mysql_warning_count()
11.1.3.59. mysql_commit()
11.1.3.60. mysql_rollback()
11.1.3.61. mysql_autocommit()
11.1.3.62. mysql_more_results()
11.1.3.63. mysql_next_result()

ここの説明の中で、パラメータまたは戻り値に NULL が使用されている場合、これは C 言語における NULL を表しており、MySQL における NULL 値ではありません。

値を返す関数は、一般にポインタまたは整数を返します。特に指定されていないかぎり、ポインタを返す関数が非 NULL 値を返した場合は正常終了を、NULL 値を返した場合はエラーを示します。同様に、整数を返す関数が 0 を返した場合は正常終了を、0 以外の値を返した場合はエラーを示します。注意: ``0 以外'' ということに、それ以上の意味はありません。関数説明に特に記述がないかぎり、0 以外の値に対して比較テストは必要ありません。

if (result)                   /* correct */
    ... error ...

if (result < 0)               /* incorrect */
    ... error ...

if (result == -1)             /* incorrect */
    ... error ...

関数が返すエラーについては、関数説明の中の「エラー」サブセクションを参照してください。発生したエラーを調べるには、mysql_errno() を呼び出します。mysql_error() を呼び出すと、エラー内容の文字列表現を取得できます。

11.1.3.1. mysql_affected_rows()

my_ulonglong mysql_affected_rows(MYSQL *mysql)

説明

最後に呼び出された UPDATE によって変更されたレコード数、最後に呼び出された DELETE によって削除されたレコード数、または最後に呼び出された INSERT によって挿入されたレコード数を返します。UPDATEDELETE、または INSERT のいずれかのステートメントについて mysql_query() を呼び出した後に、この関数を呼び出します。SELECT ステートメントの場合、mysql_affected_rows() を呼び出すと、mysql_num_rows() と同様に動作します。

戻り値

正の整数は、影響を与えた、または取得した、レコード数を示します。0 は、UPDATE によって更新されたレコードがなかったこと、クエリの WHERE 節に一致するレコードがなかったこと、またはクエリが実行されていないことを示します。-1 は、クエリがエラーを返したこと、または SELECT クエリの場合に mysql_store_result() を呼び出す前に mysql_affected_rows() が呼び出されたことを示します。

エラー

ありません。

mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10");
printf("%ld products updated",(long) mysql_affected_rows(&mysql));

mysqld に接続する際にフラグ CLIENT_FOUND_ROWS が指定されている場合、mysql_affected_rows()UPDATE ステートメントの WHERE 節に一致するレコード数を返します。

注意: REPLACE コマンドで既存のレコードが新しいレコードで置き換えられた場合は mysql_affected_rows() は 2 を返します。これは、レコードが 1 行挿入された後で重複したレコードが削除されたためです。

11.1.3.2. mysql_change_user()

my_bool mysql_change_user(MYSQL *mysql, const char *user, const char *password, const char *db)

説明

ユーザを変更し、db で指定されたデータベースを mysql で指定された接続のデフォルト(カレント)データベースにします。このデータベースは、その後実行されるクエリで明示的なデータベース指定子のないテーブル参照が行われる際のデフォルトになります。

この関数は、MySQL 3.23.3 で導入されました。

mysql_change_user() は、指定したユーザが認証されない場合、またはそのユーザがデータベースを使用する権限を持たない場合に、失敗します。この場合、ユーザおよびデータベースは変更されません。

デフォルトデータベースを使用しない場合、db パラメータを NULL に設定します。

MySQL 4.0.6 以降、このコマンドは、新しい接続が確立した場合は常に、任意のアクティブなトランザクションの ROLLBACK の実行、すべてのテンポラリテーブルのクローズ、ロックされたすべてのテーブルのアンロック、および状態のリセットを行います。この処理は、ユーザが変更されなかった場合も必ず行われます。

戻り値

正常終了した場合は 0。エラーが発生した場合は 0 以外。

エラー

mysql_real_connect() が返すエラーと同じ。

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

  • ER_UNKNOWN_COM_ERROR

    MySQL サーバでこのコマンドが実装されていない(バージョンが古いと考えられる)。

  • ER_ACCESS_DENIED_ERROR

    ユーザまたはパスワードが正しくない。

  • ER_BAD_DB_ERROR

    データベースが存在しない。

  • ER_DBACCESS_DENIED_ERROR

    ユーザがデータベースへのアクセス権を持っていない。

  • ER_WRONG_DB_NAME

    データベース名が長すぎる。

if (mysql_change_user(&mysql, "user", "password", "new_database"))
{
   fprintf(stderr, "Failed to change user.  Error: %s\n",
           mysql_error(&mysql));
}

11.1.3.3. mysql_character_set_name()

const char *mysql_character_set_name(MYSQL *mysql)

説明

現在の接続のデフォルトのキャラクタセットを返します。

戻り値

デフォルトのキャラクタセット。

エラー

ありません。

11.1.3.4. mysql_close()

void mysql_close(MYSQL *mysql)

説明

すでにオープンされている接続をクローズします。mysql で示される接続ハンドルが mysql_init() または mysql_connect() によって自動的に割り当てられたハンドルだった場合は、mysql_close() で割り当てが解除されます。

戻り値

ありません。

エラー

ありません。

11.1.3.5. mysql_connect()

MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)

説明

この関数は廃止されています。代わりに mysql_real_connect() を使用してください。

mysql_connect() は、host 上で実行している MySQL データベースエンジンへの接続を確立しようとします。mysql_connect() が正常終了しなければ、他の API 関数(mysql_get_client_info() を除く)を実行できません。

パラメータの意味は、mysql_real_connect() での対応するパラメータと同じですが、接続パラメータに NULL を渡すことができるという違いがあります。この場合、C API は接続構造体に自動的にメモリを割り当てます。このメモリは mysql_close() を呼び出すことによって解放されます。この方法には、接続に失敗したときにエラーメッセージを取得できないという短所があります(mysql_errno() または mysql_error() からエラー情報を取得するには有効な MYSQL ポインタを渡す必要があります)。

戻り値

mysql_real_connect() と同じです。

エラー

mysql_real_connect() と同じです。

11.1.3.6. mysql_create_db()

int mysql_create_db(MYSQL *mysql, const char *db)

説明

db パラメータで指定された名前でデータベースを作成します。

この関数は廃止されています。代わりに、mysql_query() を使用して CREATE DATABASE ステートメントを発行してください。

戻り値

データベースが正常に作成された場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

if(mysql_create_db(&mysql, "my_database"))
{
   fprintf(stderr, "Failed to create new database.  Error: %s\n",
           mysql_error(&mysql));
}

11.1.3.7. mysql_data_seek()

void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset)

説明

クエリ結果セットの任意のレコードにシークします。offset 値はレコード番号を表し、0 から mysql_num_rows(stmt)-1 の範囲で指定します。

mysql_data_seek() を使用するには、結果セット構造体にクエリの結果全体が格納されている必要があるので、mysql_use_result() ではなく、mysql_store_result() とともに使用する必要があります。

戻り値

ありません。

エラー

ありません。

11.1.3.8. mysql_debug()

void mysql_debug(const char *debug)

説明

指定された文字列で DBUG_PUSH を実行します。mysql_debug() は、Fred Fish デバッグライブラリを使用します。この関数を使用するには、デバッグをサポートするためのクライアントライブラリをコンパイルする必要があります。 See 項E.1. 「MySQL サーバのデバッグ」。 See 項E.2. 「MySQL クライアントのデバッグ」

戻り値

ありません。

エラー

ありません。

次のコードを実行すると、クライアントライブラリによってクライアントマシンの /tmp/client.trace にトレースファイルが生成されます。

mysql_debug("d:t:O,/tmp/client.trace");

11.1.3.9. mysql_drop_db()

int mysql_drop_db(MYSQL *mysql, const char *db)

説明

db パラメータで指定された名前のデータベースを破棄します。

この関数は廃止されています。代わりに、mysql_query() を使用して DROP DATABASE ステートメントを発行してください。

戻り値

データベースが正常に破棄された場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

if(mysql_drop_db(&mysql, "my_database"))
  fprintf(stderr, "Failed to drop the database: Error: %s\n",
          mysql_error(&mysql));

11.1.3.10. mysql_dump_debug_info()

int mysql_dump_debug_info(MYSQL *mysql)

説明

デバッグ情報をログに書き込むようにサーバに指示します。接続ユーザが SUPER 特権を持たない場合は正常に動作しません。

戻り値

正常に動作した場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.11. mysql_eof()

my_bool mysql_eof(MYSQL_RES *result)

説明

この関数は廃止されています。代わりに mysql_errno() または mysql_error() を使用できます。

mysql_eof() は、結果セットの最後のレコードが読み込まれたかどうかを判定します。

mysql_store_result() を呼び出して結果セットを取得する場合、クライアントは 1 回の動作で結果セット全体を受け取ります。この場合、mysql_fetch_row() を呼び出して戻り値が NULL であれば、すでに結果セットの最後に到達していたことがわかるので、mysql_eof() を呼び出す必要はありません。mysql_store_result() と一緒に使用する場合、mysql_eof() は常に true を返します。

一方、mysql_use_result() を使用して結果セットの取得を開始した場合は、mysql_fetch_row() を繰り返し呼び出すことによってそのレコードを 1 行ずつサーバから取得します。この手順を実行している途中で接続に異常が発生する場合があるので、mysql_fetch_row() を呼び出して戻り値が NULL であっても、それが必ずしも結果セットの最後に正常に到達したことを意味するわけではありません。この場合は、mysql_eof() を使用することによって、どういう状況なのかを判断できます。mysql_eof() は、結果セットの最後に到達していた場合は 0 以外、エラーが発生していた場合は 0 を返します。

mysql_eof() は、歴史的には標準の MySQL エラー関数である mysql_errno() および mysql_error() の前身です。これらのエラー関数は同じ情報を返すので、すでに廃止されている mysql_eof() よりも優先して使用してください(実際、mysql_eof() が返すのはブール値だけで、エラー関数はエラー発生理由を示すより多くの情報を返します)。

戻り値

エラーが発生していない場合は 0。結果セットの最後に到達していた場合は 0 以外。

エラー

ありません。

mysql_eof() には次のような使い方が考えられます。

mysql_query(&mysql,"SELECT * FROM some_table");
result = mysql_use_result(&mysql);
while((row = mysql_fetch_row(result)))
{
    // do something with data
}
if(!mysql_eof(result))  // mysql_fetch_row() failed due to an error
{
    fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
}

ただし、標準の MySQL エラー関数を次のように使用すれば、同じ動作を実現できます。

mysql_query(&mysql,"SELECT * FROM some_table");
result = mysql_use_result(&mysql);
while((row = mysql_fetch_row(result)))
{
    // do something with data
}
if(mysql_errno(&mysql))  // mysql_fetch_row() failed due to an error
{
    fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
}

11.1.3.12. mysql_errno()

unsigned int mysql_errno(MYSQL *mysql)

説明

mysql_errno() は、mysql で指定される接続について、最後に呼び出された、成功または失敗する可能性のある API 関数のエラーコードを返します。戻り値が 0 の場合、エラーは発生していません。クライアントのエラーメッセージ番号の一覧は、MySQL errmsg.h ヘッダファイルに記述されています。サーバのエラーメッセージ番号の一覧は、mysqld_error.h に記述されています。MySQL ソースディストリビューションに含まれるファイル Docs/mysqld_error.txt には、すべてのエラーメッセージおよびエラー番号の一覧が記述されています。サーバのエラーコードの一覧は、項12.1. 「返されるエラー」 にも記載されています。

注意: mysql_fetch_row() などの一部の関数は、成功した場合に mysql_errno() を設定しません。

大体の目安として、サーバに情報を要求する関数は、成功した場合に mysql_errno() をリセットすると考えてください。

戻り値

最後に呼び出された mysql_xxx 関数が失敗していた場合はそのエラーコード。0 はエラーが発生しなかったことを示します。

エラー

ありません。

11.1.3.13. mysql_error()

const char *mysql_error(MYSQL *mysql)

説明

mysql_error() は、mysql で指定された接続について、最後に呼び出された API 関数が失敗した際のエラーメッセージをヌル終端文字列として返します。関数が失敗しなかった場合、mysql_error() の戻り値はその前のエラーメッセージか、エラーがまったく発生していない場合は空文字列になります。

大体の目安として、サーバに情報を要求する関数は、成功した場合に mysql_error() をリセットすると考えてください。

mysql_errno をリセットする関数では、次の 2 つの比較は同等です。

if(mysql_errno(&mysql))
{
    // an error occurred
}

if(mysql_error(&mysql)[0] != '\0')
{
    // an error occurred
}

クライアントのエラーメッセージの言語は、MySQL クライアントライブラリを再コンパイルすることによって変更できます。現在は、複数の異なる言語でエラーメッセージを返すことができます。 See 項4.7.2. 「英語以外のエラーメッセージ」

戻り値

エラーの内容を説明するヌル終端文字列。エラーが発生していない場合は空文字列。

エラー

ありません。

11.1.3.14. mysql_escape_string()

この関数の代わりに mysql_real_escape_string() を使用してください。

mysql_real_escape_string() は先頭の引数として接続ハンドラを受け取り、現在のキャラクタセットに従って文字列をエスケープしますが、その 2 点を除けば、この関数と mysql_real_escape_string() は同じです。mysql_escape_string() は接続ハンドラを引数として受け取りません。また、現在のキャラクタセットは参照しません。

11.1.3.15. mysql_fetch_field()

MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)

説明

結果セットに含まれる 1 つのカラムの定義を MYSQL_FIELD 構造体として返します。結果セットに含まれるすべてのカラムの定義を取得するには、この関数を繰り返し呼び出します。定義を取得するカラムが残っていない場合、mysql_fetch_field()NULL を返します。

新しく SELECT クエリを実行するたびに、mysql_fetch_field() は先頭のカラムの定義を返すようにリセットされます。また、mysql_field_seek() を呼び出した場合も、mysql_fetch_field() が返すフィールドが変わります。

mysql_query() を呼び出してテーブルに対して SELECT を実行した後 mysql_store_result() を呼び出さなかった場合、mysql_fetch_field() を呼び出して BLOB フィールドの長さを要求すると、デフォルトの BLOB 長(8 キロバイト)が返されます(MySQL は BLOB の最大長がわからないので 8 キロバイトを返します。この値は将来設定可能な値にする必要があります)。結果セットを取得した後は、そのクエリにおけるこのカラムの最大値の長さが field->max_length に渡されます。

戻り値

現在のカラムの MYSQL_FIELD 構造体。カラムが残っていない場合は NULL

エラー

ありません。

MYSQL_FIELD *field;

while((field = mysql_fetch_field(result)))
{
    printf("field name %s\n", field->name);
}

11.1.3.16. mysql_fetch_fields()

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)

説明

結果セットのすべての MYSQL_FIELD 構造体の配列を返します。各構造体には、結果セットに含まれる 1 つのカラムのフィールド定義が格納されています。

戻り値

結果セットに含まれるすべてのカラムの MYSQL_FIELD 構造体の配列。

エラー

ありません。

unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *fields;

num_fields = mysql_num_fields(result);
fields = mysql_fetch_fields(result);
for(i = 0; i < num_fields; i++)
{
   printf("Field %u is %s\n", i, fields[i].name);
}

11.1.3.17. mysql_fetch_field_direct()

MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)

説明

フィールド番号 fieldnr で指定される結果セットのカラムのフィールド定義を MYSQL_FIELD 構造体として返します。この関数を使用すれば、任意のカラムの定義を取得できます。fieldnr の値は 0 から mysql_num_fields(result)-1 の範囲で指定します。

戻り値

指定したカラムの MYSQL_FIELD 構造体。

エラー

ありません。

unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *field;

num_fields = mysql_num_fields(result);
for(i = 0; i < num_fields; i++)
{
    field = mysql_fetch_field_direct(result, i);
    printf("Field %u is %s\n", i, field->name);
}

11.1.3.18. mysql_fetch_lengths()

unsigned long *mysql_fetch_lengths(MYSQL_RES *result)

説明

結果セット内のカレントレコードのカラムの長さを返します。フィールド値をコピーしようとする場合、この関数を使用すれば strlen() を呼び出さなくても長さを取得できるので便利です。また、結果セットにバイナリデータが含まれている場合、strlen() はヌル文字が含まれるフィールドの長さを正しく返さないので、この関数を使用してデータサイズを調べる必要があります

空のカラムおよび NULL 値を含むカラムの長さは 0 です。この 2 つを区別する方法については、mysql_fetch_row() の説明を参照してください。

戻り値

各カラムのサイズ(ヌル終端文字は数えない)を表す unsigned long 整数の配列。エラーが発生した場合は NULL

エラー

mysql_fetch_lengths() は結果セットのカレントレコードでのみ有効です。mysql_fetch_row() を呼び出す前または結果セットのすべてのレコードを取得した後で呼び出された場合は NULL を返します。

MYSQL_ROW row;
unsigned long *lengths;
unsigned int num_fields;
unsigned int i;

row = mysql_fetch_row(result);
if (row)
{
    num_fields = mysql_num_fields(result);
    lengths = mysql_fetch_lengths(result);
    for(i = 0; i < num_fields; i++)
    {
         printf("Column %u is %lu bytes in length.\n", i, lengths[i]);
    }
}

11.1.3.19. mysql_fetch_row()

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

説明

結果セットの次のレコードを取得します。mysql_store_result() を呼び出した後に mysql_fetch_row() を使用する場合、取得するレコードが残っていなければ NULL を返します。mysql_use_result() を呼び出した後に mysql_fetch_row() を使用する場合、取得するレコードが残っていないか、またはエラーが発生したときに NULL を返します。

レコードに含まれる値の数は mysql_num_fields(result) によって取得します。mysql_fetch_row() を呼び出してその戻り値が row に格納されている場合、値へのポインタは row[0] から row[mysql_num_fields(result)-1] のように表されます。NULL ポインタは、レコードの値が NULL 値であることを示します。

mysql_fetch_lengths() を呼び出すと、レコードのフィールド値の長さを取得できます。空のフィールドおよび NULL を含むフィールドの長さはどちらも 0 ですが、そのフィールドのポインタを調べることによってその 2 つを区別できます。ポインタが NULL の場合、フィールドの値は NULL です。それ以外の場合、フィールドは空です。

戻り値

次のレコードの MYSQL_ROW 構造体。取得するレコードが残っていないか、エラーが発生した場合は NULL

エラー

注意: mysql_fetch_row() を 1 回呼び出してから、次に呼び出すまでの間にエラーがリセットされることはありません。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

MYSQL_ROW row;
unsigned int num_fields;
unsigned int i;

num_fields = mysql_num_fields(result);
while ((row = mysql_fetch_row(result)))
{
   unsigned long *lengths;
   lengths = mysql_fetch_lengths(result);
   for(i = 0; i < num_fields; i++)
   {
       printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL");
   }
   printf("\n");
}

11.1.3.20. mysql_field_count()

unsigned int mysql_field_count(MYSQL *mysql)

MySQL 3.22.24 より古いバージョンを使用している場合、この関数の代わりに unsigned int mysql_num_fields(MYSQL *mysql) を使用してください。

説明

現在の接続で最後に実行されたクエリの結果セットのカラム数を返します。

通常この関数は、mysql_store_result()NULL を返したとき(結果セットポインタが返されなかったとき)に使用します。この場合、mysql_field_count() を呼び出すことによって、mysql_store_result() が正常な処理として空の結果セットを返したのかどうかを判断できます。これによって、クライアントプログラムは、クエリが SELECT(または SELECT ライクな)ステートメントかどうかを知らなくても適切な処理を実行できます。以下の例に、この処理の実現方法を示します。

See 項11.1.12.1. 「mysql_query() が正常に終了した後で mysql_store_result()NULL を返す場合があるのはなぜか」

戻り値

結果セットに含まれるフィールド数を表す unsigned 整数。

エラー

ありません。

MYSQL_RES *result;
unsigned int num_fields;
unsigned int num_rows;

if (mysql_query(&mysql,query_string))
{
    // error
}
else // query succeeded, process any data returned by it
{
    result = mysql_store_result(&mysql);
    if (result)  // there are rows
    {
        num_fields = mysql_num_fields(result);
        // retrieve rows, then call mysql_free_result(result)
    }
    else  // mysql_store_result() returned nothing; should it have?
    {
        if(mysql_field_count(&mysql) == 0)
        {
            // query does not return data
            // (it was not a SELECT)
            num_rows = mysql_affected_rows(&mysql);
        }
        else // mysql_store_result() should have returned data
        {
            fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
        }
    }
}

mysql_field_count(&mysql) の呼び出し部分を mysql_errno(&mysql) に置き換える方法もあります。この場合、ステートメントが SELECT だったかどうかは、mysql_field_count() が返す値から推測するのではなく、mysql_store_result() が返すエラーを直接調べて判断します。

11.1.3.21. mysql_field_seek()

MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)

説明

フィールドカーソルの位置を指定されたオフセットに設定します。次に mysql_fetch_field() を呼び出すと、そのオフセットに関連付けられたカラムのフィールド定義を返します。

レコードの先頭にシークするには、offset 値に 0 を渡します。

戻り値

シークする前のフィールドカーソルの値。

エラー

ありません。

11.1.3.22. mysql_field_tell()

MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)

説明

最後に実行された mysql_fetch_field() で使用されたフィールドカーソルの位置を返します。この戻り値を、mysql_field_seek() に引数として渡すことができます。

戻り値

フィールドカーソルの現在のオフセット。

エラー

ありません。

11.1.3.23. mysql_free_result()

void mysql_free_result(MYSQL_RES *result)

説明

mysql_store_result()mysql_use_result()mysql_list_dbs() などが結果セットに割り当てたメモリを解放します。結果セットが必要なくなったら、mysql_free_result() を呼び出して、使用していたメモリを解放します。

戻り値

ありません。

エラー

ありません。

11.1.3.24. mysql_get_client_info()

char *mysql_get_client_info(void)

説明

クライアントのライブラリバージョンを表す文字列を返します。

戻り値

MySQL クライアントのライブラリバージョンを表す文字列。

エラー

ありません。

11.1.3.25. mysql_get_client_version()

unsigned long mysql_get_client_version(void)

説明

クライアントのライブラリバージョンを表す整数を返します。この値は XYYZZ という形式で表され、X はメジャーバージョン、YY はリリースレベル、ZZ はリリースレベル内のバージョン番号です。たとえば、40102 は、クライアントのライブラリバージョンが 4.1.2 であることを表します。

戻り値

MySQL クライアントのライブラリバージョンを表す整数。

エラー

ありません。

11.1.3.26. mysql_get_host_info()

char *mysql_get_host_info(MYSQL *mysql)

説明

使用している接続のタイプを表す文字列を返します。この文字列にはサーバのホスト名も含まれます。

戻り値

サーバのホスト名および接続タイプを表す文字列。

エラー

ありません。

11.1.3.27. mysql_get_proto_info()

unsigned int mysql_get_proto_info(MYSQL *mysql)

説明

現在の接続に使用しているプロトコルのバージョンを返します。

戻り値

現在の接続に使用しているプロトコルのバージョンを表す unsigned 整数。

エラー

ありません。

11.1.3.28. mysql_get_server_info()

char *mysql_get_server_info(MYSQL *mysql)

説明

サーバのバージョン番号を表す文字列を返します。

戻り値

サーバのバージョン番号を表す文字列。

エラー

ありません。

11.1.3.29. mysql_get_server_version()

unsigned long mysql_get_server_version(MYSQL *mysql)

説明

サーバのバージョン番号を整数として返します(4.1 の新機能)。

戻り値

MySQL サーバのバージョンを次の形式で表す番号。

main_version*10000 + minor_version *100 + sub_version

たとえば、バージョンが 4.1.0 の場合、戻り値は 40100 です。

この値を使用すると、クライアントプログラムはサーバのバージョンから特定の機能が存在するかどうかを簡単に判断できます。

エラー

ありません。

11.1.3.30. mysql_info()

char *mysql_info(MYSQL *mysql)

説明

最後に実行したクエリに関する情報を表す文字列を取得します。ただし、対象となるのは、以下の一覧に含まれるステートメントだけです。最後に実行したのが他のステートメントのクエリだった場合は、mysql_info()NULL を返します。文字列の形式は、以下に説明するように、クエリのタイプによって異なります。数字は例として示したものです。実際の文字列には実行したクエリに即した値が使用されます。

  • INSERT INTO ...SELECT ...

    文字列の形式: Records: 100 Duplicates: 0 Warnings: 0

  • INSERT INTO ...VALUES (...),(...),(...)...

    文字列の形式: Records: 3 Duplicates: 0 Warnings: 0

  • LOAD DATA INFILE ...

    文字列の形式: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0

  • ALTER TABLE

    文字列の形式: Records: 3 Duplicates: 0 Warnings: 0

  • UPDATE

    文字列の形式: Rows matched: 40 Changed: 40 Warnings: 0

注意: mysql_info() は、INSERT ... VALUES ステートメントが複数レコードを挿入する形式の場合に限り(複数の値リストが指定された場合に限り)、NULL 以外の値を返します。

戻り値

最後に実行したクエリに関する情報を表す文字列。クエリの情報がない場合は NULL

エラー

ありません。

11.1.3.31. mysql_init()

MYSQL *mysql_init(MYSQL *mysql)

説明

mysql_real_connect() に適応する MYSQL オブジェクトを割り当て、または初期化します。mysqlNULL ポインタを渡した場合、関数は新しいオブジェクトにメモリを割り当て、初期化し、それを返します。それ以外の値を渡した場合は、オブジェクトを初期化し、そのアドレスを返します。mysql_init() が新しいオブジェクトにメモリを割り当てた場合、そのメモリは mysql_close() を呼び出して接続をクローズする際に解放されます。

戻り値

初期化された MYSQL* ハンドル。新しいオブジェクトに割り当てる十分なメモリがなかった場合は NULL

エラー

メモリが不足していた場合は NULL を返します。

11.1.3.32. mysql_insert_id()

my_ulonglong mysql_insert_id(MYSQL *mysql)

説明

前回実行されたクエリで生成した AUTO_INCREMENT カラムの ID を返します。この関数は、AUTO_INCREMENT フィールドを含むテーブルに対して INSERT クエリを実行した後で使用します。

注意: mysql_insert_id() は、前回実行されたクエリで AUTO_INCREMENT 値が生成されなかった場合は、0 を返します。将来のためにその値を保存する必要がある場合は、それを生成するクエリの直後に mysql_insert_id() を呼び出す必要があります。

前回実行されたクエリがエラーを返した場合については、mysql_insert_id() の値は未定義です。

mysql_insert_id() は、AUTO_INCREMENT 値を生成するか、またはカラム値を LAST_INSERT_ID(expr) に設定する INSERT ステートメントおよび UPDATE ステートメントの実行後に更新されます。 See 項6.3.6.2. 「その他の各種関数」

注意: SQL LAST_INSERT_ID() 関数の値には、必ず最後に生成された AUTO_INCREMENT 値が含まれます。この値はサーバに保持されるので、あるクエリを実行してから次のクエリを実行するまでの間にリセットされることはありません。

戻り値

前回実行されたクエリによって更新された AUTO_INCREMENT フィールドの値。現在の接続でまだ 1 回もクエリが実行されていなかった場合、または前回実行されたクエリで AUTO_INCREMENT 値が更新されなかった場合、0 を返します。

エラー

ありません。

11.1.3.33. mysql_kill()

int mysql_kill(MYSQL *mysql, unsigned long pid)

説明

pid で指定するスレッドを強制終了するように、サーバに要求します。

戻り値

正常終了した場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.34. mysql_list_dbs()

MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)

説明

サーバ上のデータベースから wild パラメータで指定される単純な正規表現に一致するデータベース名を検索し、結果セットとして返します。wild にはワイルドカード文字として ‘%’ または ‘_’ を使用できます。NULL ポインタを指定した場合はすべてのデータベース名が一致します。mysql_list_dbs() を呼び出すと、クエリ SHOW databases [LIKE wild] を実行した場合と同じ結果が得られます。

結果セットに割り当てられたメモリを解放するには、mysql_free_result() を呼び出す必要があります。

戻り値

正常終了した場合は MYSQL_RES 結果セット。エラーが発生した場合は NULL

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.35. mysql_list_fields()

MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)

説明

指定されたテーブルのフィールドから wild パラメータで指定される単純な正規表現に一致するフィールド名を検索し、結果セットとして返します。wild にはワイルドカード文字として ‘%’ または ‘_’ を使用できます。NULL ポインタを指定した場合はすべてのフィールド名が一致します。mysql_list_fields() を呼び出すと、クエリ SHOW COLUMNS FROM tbl_name [LIKE wild] を実行した場合と同じ結果が得られます。

注意: mysql_list_fields() の代わりに SHOW COLUMNS FROM tbl_name を使用することを推奨します。

結果セットに割り当てられたメモリを解放するには、mysql_free_result() を呼び出す必要があります。

戻り値

正常終了した場合は MYSQL_RES 結果セット。エラーが発生した場合は NULL

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.36. mysql_list_processes()

MYSQL_RES *mysql_list_processes(MYSQL *mysql)

説明

現在のサーバスレッドの一覧を表す結果セットを返します。これは、mysqladmin processlist または SHOW PROCESSLIST クエリが返す情報と同じタイプの情報です。

結果セットに割り当てられたメモリを解放するには、mysql_free_result() を呼び出す必要があります。

戻り値

正常終了した場合は MYSQL_RES 結果セット。エラーが発生した場合は NULL

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.37. mysql_list_tables()

MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)

説明

現在のデータベースから wild パラメータで指定される単純な正規表現に一致するテーブル名を検索し、結果セットとして返します。wild にはワイルドカード文字として ‘%’ または ‘_’ を使用できます。NULL ポインタを指定した場合はすべてのテーブル名が一致します。mysql_list_tables() を呼び出すと、クエリ SHOW tables [LIKE wild] を実行した場合と同じ結果が得られます。

結果セットに割り当てられたメモリを解放するには、mysql_free_result() を呼び出す必要があります。

戻り値

正常終了した場合は MYSQL_RES 結果セット。エラーが発生した場合は NULL

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.38. mysql_num_fields()

unsigned int mysql_num_fields(MYSQL_RES *result)

または

unsigned int mysql_num_fields(MYSQL *mysql)

2 番目の形式は、MySQL 3.22.24 以降では動作しません。MYSQL* 引数を渡すには、この関数の代わりに unsigned int mysql_field_count(MYSQL *mysql) を使用する必要があります。

説明

結果セットのカラム数を返します。

注意: 結果セットへのポインタまたは接続ハンドルへのポインタのどちらを使用しても、カラム数を取得できます。mysql_store_result() または mysql_use_result()NULL を返した場合(結果セットポインタが返されなかった場合)は、接続ハンドルを使用します。この場合、mysql_field_count() を呼び出すことによって、mysql_store_result() が正常な処理として空の結果セットを返したのかどうかを判断できます。これによって、クライアントプログラムは、クエリが SELECT(または SELECT ライクな)ステートメントかどうかを知らなくても適切な処理を実行できます。以下の例に、この処理の実現方法を示します。

See 項11.1.12.1. 「mysql_query() が正常に終了した後で mysql_store_result()NULL を返す場合があるのはなぜか」

戻り値

結果セットに含まれるフィールド数を表す unsigned 整数。

エラー

ありません。

MYSQL_RES *result;
unsigned int num_fields;
unsigned int num_rows;

if (mysql_query(&mysql,query_string))
{
    // error
}
else // query succeeded, process any data returned by it
{
    result = mysql_store_result(&mysql);
    if (result)  // there are rows
    {
        num_fields = mysql_num_fields(result);
        // retrieve rows, then call mysql_free_result(result)
    }
    else  // mysql_store_result() returned nothing; should it have?
    {
        if (mysql_errno(&mysql))
        {
           fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
        }
        else if (mysql_field_count(&mysql) == 0)
        {
            // query does not return data
            // (it was not a SELECT)
            num_rows = mysql_affected_rows(&mysql);
        }
    }
}

(クエリが結果セットを返すことがわかっている場合)mysql_errno(&mysql) を呼び出す代わりに mysql_field_count(&mysql) が 0 を返すかどうかを調べる方法もあります。これは、0 を返すのは、何らかの異常が発生した場合だけだからです。

11.1.3.39. mysql_num_rows()

my_ulonglong mysql_num_rows(MYSQL_RES *result)

説明

結果セットのレコード数を返します。

mysql_num_rows() の使い方は、mysql_store_result()mysql_use_result() のどちらを使用して結果セットを取得するかによって決まります。mysql_store_result() を使用する場合、すぐに mysql_num_rows() を呼び出すことができます。mysql_use_result() を使用する場合、結果セットに含まれるすべてのレコードを取得するまでは、mysql_num_rows() は正しい値を返しません。

戻り値

結果セットのレコード数。

エラー

ありません。

11.1.3.40. mysql_options()

int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)

説明

この関数を使用して、接続オプションを追加設定し、接続の動作を変えることができます。この関数を複数回呼び出すことで、複数のオプションを設定できます。

mysql_options() は、mysql_init() を実行してから mysql_connect() または mysql_real_connect() を呼び出すまでの間に呼び出す必要があります。

option 引数は、設定するオプションです。arg 引数はそのオプションに設定する値です。オプションが整数の場合、arg には整数値へのポインタを渡す必要があります。

設定可能なオプションの値を次に示します。

オプション引数の型機能
MYSQL_OPT_CONNECT_TIMEOUTunsigned int *接続のタイムアウト時間(秒単位)。
MYSQL_OPT_READ_TIMEOUTunsigned int *サーバからの読み込みタイムアウト時間(現在は Windows の TCP/IP 接続でのみ有効)。
MYSQL_OPT_WRITE_TIMEOUTunsigned int *サーバへの書き込みタイムアウト時間(現在は Windows の TCP/IP 接続でのみ有効)。
MYSQL_OPT_COMPRESS未使用圧縮されたクライアント/サーバプロトコルを使用。
MYSQL_OPT_LOCAL_INFILEunsigned int への省略可能なポインタポインタが指定されないか、または 0 ではない unsigned int へのポインタが指定された場合、コマンド LOAD LOCAL INFILE は有効。
MYSQL_OPT_NAMED_PIPE未使用名前付きパイプを使用して NT 上で動作する MySQL サーバに接続。
MYSQL_INIT_COMMANDchar *MySQL サーバに接続するときに実行するコマンド。再接続時には自動的に再実行される。
MYSQL_READ_DEFAULT_FILEchar *my.cnf ではなく、指定されたオプション設定ファイルからオプションを読み込む。
MYSQL_READ_DEFAULT_GROUPchar *my.cnf の指定されたグループまたは MYSQL_READ_DEFAULT_FILE で指定されたファイルからオプションを読み込む。
MYSQL_OPT_PROTOCOLunsigned int *使用するプロトコルのタイプ。mysql.h で定義されている mysql_protocol_type の列挙値のいずれか 1 つであること。
MYSQL_SHARED_MEMORY_BASE_NAMEchar*サーバとの通信に使用する名前付き共有メモリオブジェクト。接続相手の mysqld サーバが使用するオプション -shared-memory-base-name と同じ値を指定する必要がある。

注意: MYSQL_READ_DEFAULT_FILE または MYSQL_READ_DEFAULT_GROUP を使用する場合は、グループ client が常に読み込まれます。

オプション設定ファイルの指定されたグループには以下のオプションを指定可能です。

オプション説明
connect-timeout接続のタイムアウト時間(秒単位)。Linux では、サーバから最初の応答を待つ場合にもこのタイムアウト時間を使用する。
compress圧縮されたクライアント/サーバプロトコルを使用。
database接続コマンドでデータベースが指定されなかった場合に接続するデータベース。
debugデバッグオプション。
disable-local-infileLOAD DATA LOCAL の使用を無効にする。
hostデフォルトのホスト名。
init-commandMySQL サーバに接続するときに実行するコマンド。再接続時には自動的に再実行される。
interactive-timeoutmysql_real_connect()CLIENT_INTERACTIVE を指定するのと同じ。 See 項11.1.3.43. 「mysql_real_connect()
local-infile[=(0|1)]引数が指定されないか、または 0 以外の引数が指定された場合に LOAD DATA LOCAL の使用を有効にする。
max_allowed_packetクライアントがサーバから読み込み可能なパケットの最大サイズ。
passwordデフォルトのパスワード。
pipe名前付きパイプを使用して NT 上で動作する MySQL サーバに接続。
protocol=(TCP | SOCKET | PIPE | MEMORY)サーバに接続するときに使用するプロトコルを選択(4.1 の新機能)。
portデフォルトのポート番号。
return-found-rowsUPDATE を使用したときに更新されたレコードではなく、検索結果のレコードを返すように、mysql_info() に指示する。
shared-memory-base-name=nameサーバとの接続に使用する共有メモリの名前(デフォルトは "MySQL")。MySQL 4.1 の新機能。
socketデフォルトのソケット番号。
userデフォルトのユーザ。

注意: timeout の代わりに connect-timeout が提供されていますが、timeout もしばらくは使用できます。

オプション設定ファイルの詳細については、項4.1.2. 「my.cnf オプション設定ファイル」 を参照してください。

戻り値

正常終了した場合は 0。不明なオプションを使用した場合は 0 以外。

MYSQL mysql;

mysql_init(&mysql);
mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");
if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
{
    fprintf(stderr, "Failed to connect to database: Error: %s\n",
          mysql_error(&mysql));
}

この例では、圧縮されたクライアント/サーバプロトコルを使用すること、および my.cnf ファイルの odbc セクションのオプションを追加で読み込むことを、クライアントに要求しています。

11.1.3.41. mysql_ping()

int mysql_ping(MYSQL *mysql)

説明

サーバへの接続が正常かどうかを確認します。切断されていた場合は、自動的に再接続を試みます。

長時間にわたってアイドル状態だったクライアントはこの関数を使用することによって、サーバによって接続が切断されていないかどうかを調べて、必要なら再接続することができます。

戻り値

サーバとの接続が正常な場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.42. mysql_query()

int mysql_query(MYSQL *mysql, const char *query)

説明

ヌル終端文字列 query で指定された SQL クエリを実行します。このクエリは単一 SQL ステートメントで構成されている必要があります。このステートメントには、その終わりを示すセミコロン(‘;’)または \g を追加する必要はありません。

mysql_query() はバイナリデータを含むクエリを扱うことができません。そのようなクエリでは代わりに mysql_real_query() を使用する必要があります(バイナリデータには '\0' が含まれる可能性があり、mysql_query() はそれをクエリ文字列の終わりとして解釈してしまうため)。

クエリが結果セットを返すタイプかどうかを調べるには、mysql_field_count() を使用します。 See 項11.1.3.20. 「mysql_field_count()

戻り値

クエリが正常に動作した場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.43. mysql_real_connect()

MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)

説明

mysql_real_connect() は、host で動作している MySQL データベースエンジンへの接続を確立しようとします。mysql_real_connect() が正常終了しなければ、他の API 関数(mysql_get_client_info() を除く)を実行できません。

パラメータの指定方法を次に示します。

  • 1 つ目のパラメータには、既存の MYSQL 構造体のアドレスを指定する。mysql_real_connect() を呼び出す前に、mysql_init() を呼び出して MYSQL 構造体を初期化する必要がある。mysql_options() を使用すると、さまざまな接続オプションを変更できる。 See 項11.1.3.40. 「mysql_options()

  • host パラメータには、ホスト名または IP アドレスのどちらかを指定する。hostNULL または文字列 "localhost" を指定した場合、ローカルホストに接続するものとみなされる。OS がソケット(Unix)または名前付きパイプ(Windows)をサポートしている場合、TCP/IP の代わりにそれらを使用してサーバに接続する。

  • user パラメータにはユーザの MySQL ログイン ID を指定する。userNULL または空文字列 "" を指定した場合、現在のユーザを使用するものとみなされる。Unix では現在のログイン名が使用される。Windows で ODBC を使用する場合は、現在のユーザ名を明示的に指定する必要がある。 See 項11.2.2. 「ODBC アドミニストレータのフィールドの設定方法」

  • passwd パラメータには user のパスワードを指定する。passwdNULL を指定した場合、user テーブルのエントリのパスワードフィールドに何も指定されていない(空である)ユーザだけがチェック対象となる。データベース管理者は、この機能を使用して、パスワードを指定しているかどうかによってユーザに異なる特権を与えるという MySQL 特権システムをセットアップできる。

    注意:パスワードの暗号化はクライアント API によって自動的に処理されるので、mysql_real_connect() を呼び出す前にパスワードの暗号化は不要である。

  • db パラメータにはデータベース名を指定する。dbNULL ではない場合、この値が接続のデフォルトデータベースとして設定される。

  • port パラメータに 0 以外の値を指定した場合、この値が TCP/IP 接続のポート番号として使用される。注意: 接続のタイプは host パラメータによって決定される。

  • unix_socket パラメータに NULL 以外の値を指定した場合、この文字列がソケットまたは名前付きパイプに使用される。注意: 接続のタイプは host パラメータによって決定される。

  • client_flag パラメータには通常 0 を指定するが、極めて特殊な状況では以下に示すフラグを組み合わせて指定できる。

    フラグ名フラグの説明
    CLIENT_COMPRESS圧縮プロトコルを使用。
    CLIENT_FOUND_ROWS影響を受けたレコードの数ではなく、検索結果の(一致した)レコードの数を返す。
    CLIENT_IGNORE_SPACE関数名の末尾の空白を無視する。すべての関数名を予約語とする。
    CLIENT_INTERACTIVEアイドル状態が(wait_timeout 秒ではなく)interactive_timeout 秒継続したら接続をクローズする。
    CLIENT_LOCAL_FILESLOAD DATA LOCAL の処理を有効にする。
    CLIENT_MULTI_STATEMENTSクライアントが複数行クエリ(‘;’ をステートメントの区切りとする)を送信する可能性があることをサーバに通知する。このフラグが設定されていない場合、複数行クエリは無効。MySQL 4.1 の新機能。
    CLIENT_MULTI_RESULTSクライアントが複数クエリまたはストアドプロシージャによって取得した複数の結果セットを処理できることをサーバに通知する。CLIENT_MULTI_STATEMENTS が設定されている場合、このフラグは自動的に設定される。MySQL 4.1 の新機能。
    CLIENT_NO_SCHEMAdb_name.tbl_name.col_name という構文の使用を禁止する。これは ODCB 向けの構文である。この構文を使用した場合、パーサでエラーが発生する。この構文は一部の ODBC プログラムでバグをトラップするために使用する。
    CLIENT_ODBCクライアントが ODBC 経由であることを通知する。この場合、mysqld は ODBC クライアントに適した処理を行う。
    CLIENT_SSLSSL(暗号化プロトコル)を使用する。アプリケーションプログラムではこのフラグを設定しないこと。これはクライアントライブラリが内部で設定するフラグである。

戻り値

接続が正常に確立した場合は MYSQL* 接続ハンドル。接続が確立しなかった場合は NULL。接続が確立した場合、戻り値は 1 つ目のパラメータの値と同じです。

エラー

  • CR_CONN_HOST_ERROR

    MySQL サーバへの接続が確立しなかった。

  • CR_CONNECTION_ERROR

    ローカルの MySQL サーバへの接続が確立しなかった。

  • CR_IPSOCK_ERROR

    IP ソケットの作成に失敗した。

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_SOCKET_CREATE_ERROR

    Unix ソケットの作成に失敗した。

  • CR_UNKNOWN_HOST

    ホスト名の IP アドレスが見つからなかった。

  • CR_VERSION_ERROR

    サーバに接続する際に、異なるプロトコルバージョンのクライアントライブラリを使用したために、プロトコルの不一致が発生した。このエラーは、--old-protocol オプションを指定しないで起動した新しいバージョンのサーバに、非常に古いバージョンのクライアントライブラリを使用して接続を試みた場合に発生する可能性がある。

  • CR_NAMEDPIPEOPEN_ERROR

    Windows で名前付きパイプの作成に失敗した。

  • CR_NAMEDPIPEWAIT_ERROR

    Windows で名前付きパイプの待機に失敗した。

  • CR_NAMEDPIPESETSTATE_ERROR

    Windows でパイプハンドラの取得に失敗した。

  • CR_SERVER_LOST

    connect_timeout が正の値であり、connect_timeout 秒経過してもサーバに接続できなかった。または init-command の実行中にサーバがダウンした。

MYSQL mysql;

mysql_init(&mysql);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
{
    fprintf(stderr, "Failed to connect to database: Error: %s\n",
          mysql_error(&mysql));
}

この例では mysql_options() を呼び出して MySQL ライブラリが my.cnf ファイルの [client] および [your_prog_name] セクションを読み込むように設定しています。このように設定することで、非標準的な方法でセットアップされた MySQL に対してもこのプログラムが正常に動作することを保証します。

注意: 接続が確立したとき、mysql_real_connect() によって reconnect フラグ(MYSQL 構造体の一部)の値が 1 に設定されます。このフラグは、接続が切断されてクエリを実行できない場合に、そこでクエリを終了せずに、サーバへの再接続を試みることを意味します。

11.1.3.44. mysql_real_escape_string()

unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length)

説明

この関数は、SQL ステートメントで使用できる正当な SQL 文字列を作成するために使用します。 See 項6.1.1.1. 「文字列」

from に指定した文字列が、エスケープされた SQL 文字列にエンコードされます。この際、接続の現在のキャラクタセットが考慮されます。エンコードした結果は to に設定され、末尾には文字列の終わりを示すヌルバイトが付加されます。エンコードされる文字は、NUL(ASCII 0)、'\n'、'\r'、‘\’、‘'’、‘"’、および Ctrl-Z キー(see 項6.1.1. 「リテラル:文字列と数値の記述方法」)です(厳密に言えば、MySQL でエスケープする必要があるのはクエリ内で文字列を引用するためのバックスラッシュおよび引用符だけですが、この関数ではログファイルを読みやすくするために他の文字もエスケープします)。

from で指定する文字列の長さは length バイトである必要があります。to バッファには、少なくとも length*2+1 バイトのメモリを割り当てる必要があります(最悪の場合、1 文字エンコードするのに 2 バイトが必要な可能性があり、さらに文字列の終わりを示すヌルバイトを格納する必要があります)。mysql_real_escape_string() が復帰したとき、to にはヌル終端文字列が格納されています。戻り値はエンコード後の文字列の長さです。ただし、文字列の終わりを示すヌルバイトは含みません。

char query[1000],*end;

end = strmov(query,"INSERT INTO test_table values(");
*end++ = '\'';
end += mysql_real_escape_string(&mysql, end,"What's this",11);
*end++ = '\'';
*end++ = ',';
*end++ = '\'';
end += mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16);
*end++ = '\'';
*end++ = ')';

if (mysql_real_query(&mysql,query,(unsigned int) (end - query)))
{
   fprintf(stderr, "Failed to insert row, Error: %s\n",
           mysql_error(&mysql));
}

この例で使用されている strmov() 関数は、mysqlclient ライブラリに格納されています。strcpy() と同様の処理を行いますが、1 つ目のパラメータで指定された文字列の終わりを示すヌルバイトへのポインタを返します。

戻り値

to に設定された値の長さ。ただし、文字列の終わりを示すヌルバイトは含みません。

エラー

ありません。

11.1.3.45. mysql_real_query()

int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length)

説明

query で指定した文字列で表される SQL クエリを実行します。この文字列の長さは length バイトである必要があります。このクエリは単一 SQL ステートメントで構成されている必要があります。このステートメントには、その終わりを示すセミコロン(‘;’)または \g を追加する必要はありません。

バイナリデータには '\0' 文字が含まれる可能性があるので、そのようなデータを含むクエリの場合は、mysql_query() ではなく、mysql_real_query() を使用する必要があります。また、mysql_real_query() はクエリ文字列に対して strlen() を呼び出さないので、mysql_query() よりも高速に動作します。

クエリが結果セットを返すタイプかどうかを調べるには、mysql_field_count() を使用します。 See 項11.1.3.20. 「mysql_field_count()

戻り値

クエリが正常に動作した場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.46. mysql_reload()

int mysql_reload(MYSQL *mysql)

説明

権限テーブルの再読み込みを MySQL サーバに要求します。接続ユーザには RELOAD 特権が必要です。

この関数は廃止されています。代わりに、mysql_query() を使用して FLUSH PRIVILEGES ステートメントを発行してください。

戻り値

正常終了した場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.47. mysql_row_seek()

MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)

説明

クエリ結果セットの任意のレコードにローカーソルを設定します。offset の値はレコードオフセットであり、mysql_row_tell() または mysql_row_seek() の戻り値になります。この値はレコード番号ではありません。結果セット内のレコードに番号を指定してシークする場合は、この関数ではなく、mysql_data_seek() を使用します。

mysql_row_seek() を使用するには、結果セット構造体にクエリの結果全体が格納されている必要があるので、mysql_use_result() ではなく、mysql_store_result() とともに使用する必要があります。

戻り値

シークする前のレコードカーソルの値。mysql_row_seek() を次に呼び出すときにこの値を渡すことができます。

エラー

ありません。

11.1.3.48. mysql_row_tell()

MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)

説明

最後に実行された mysql_fetch_row() で使用されたレコードカーソルの現在の位置を返します。この戻り値を、mysql_row_seek() に引数として渡すことができます。

mysql_row_tell() は、mysql_use_result() の後ではなく、mysql_store_result() の後でのみ使用できます。

戻り値

レコードカーソルの現在のオフセット。

エラー

ありません。

11.1.3.49. mysql_select_db()

int mysql_select_db(MYSQL *mysql, const char *db)

説明

db で指定されたデータベースを mysql で指定された接続のデフォルト(カレント)データベースにします。このデータベースは、その後実行されるクエリで明示的なデータベース指定子のないテーブル参照が行われる際のデフォルトになります。

接続ユーザがデータベースを使用する権限を持つユーザとして認証されない場合、mysql_select_db() は失敗します。

戻り値

正常終了した場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.50. mysql_set_server_option()

int mysql_set_server_option(MYSQL *mysql, enum enum_mysql_set_option option)

説明

接続のオプションを有効または無効にします。option には以下のどちらかの値を指定できます。

MYSQL_OPTION_MULTI_STATEMENTS_ON複数ステートメントのサポートを有効にする。
MYSQL_OPTION_MULTI_STATEMENTS_OFF複数ステートメントのサポートを無効にする。

戻り値

正常終了した場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • ER_UNKNOWN_COM_ERROR

    サーバが mysql_set_server_option() をサポートしていなかった(サーバが 4.1.1 より古いバージョンの場合)か、またはサーバが設定しようとしたオプションをサポートしていなかった。

11.1.3.51. mysql_shutdown()

int mysql_shutdown(MYSQL *mysql)

説明

データベースサーバにシャットダウンするように要求します。接続ユーザには SHUTDOWN 特権が必要です。

戻り値

正常終了した場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.52. mysql_sqlstate()

const char *mysql_sqlstate(MYSQL *mysql)

説明

最後に発生したエラーの SQLSTATE エラーコードを含むヌル終端文字列を返します。エラーコードは 5 文字で示されます。'00000' は、``エラーがない'' ことを意味します。値は ANSI SQL および ODBC によって規定されています。考えられる値の一覧については、項12.1. 「返されるエラー」 を参照してください。

注意: すべての MySQL エラーが SQLSTATE にマッピングされているわけではありません。マッピングされていないエラーの場合は 'HY000'(一般エラー)が使用されます。

この関数は MySQL 4.1.1 で追加されました。

戻り値

SQLSTATE エラーコードを含むヌル終端文字列。

関連項目

See 項11.1.3.12. 「mysql_errno()。 See 項11.1.3.13. 「mysql_error()。 See 項11.1.7.18. 「mysql_stmt_sqlstate()

11.1.3.53. mysql_ssl_set()

int mysql_ssl_set(MYSQL *mysql, const char *key, const char *cert, const char *ca, const char *capath, const char *cipher)

説明

mysql_ssl_set() は、SSL を使用して、セキュリティで保護された接続を確立するために使用します。mysql_real_connect() の前に呼び出す必要があります。

mysql_ssl_set() は、クライアントライブラリで OpenSSL サポートが有効になっていない場合は何もしません。

mysql は、mysql_init() から返された接続ハンドラです。他のパラメータの指定方法を次に示します。

  • key パラメータには、秘密キーファイルへのパス名を指定する。

  • cert パラメータには、証明書ファイルへのパス名を指定する。

  • ca パラメータには、認証局発行の証明書ファイルへのパス名を指定する。

  • capath パラメータには、PEM 形式の信頼された CA 証明書が格納されたディレクトリへのパス名を指定する。

  • cipher パラメータには、SSL 暗号化に使用できる暗号の一覧を指定する。

使用しない SSL パラメータには NULL を指定できます。

戻り値

この関数は常に 0 を返します。SSL が正しくセットアップされていない場合、接続を試みると mysql_real_connect() がエラーを返します。

11.1.3.54. mysql_stat()

char *mysql_stat(MYSQL *mysql)

説明

mysqladmin status コマンドの出力と同じ情報を含む文字列を返します。この情報には、使用可能時間(秒単位)、実行中のスレッド数、質問の数、再ロード回数、およびオープンされているテーブルの数が含まれます。

戻り値

サーバステータスを表す文字列。エラーが発生した場合は NULL

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.55. mysql_store_result()

MYSQL_RES *mysql_store_result(MYSQL *mysql)

説明

正常にデータを取得したクエリ(SELECTSHOWDESCRIBEEXPLAIN)については、mysql_store_result() または mysql_use_result() を呼び出す必要があります。

他のクエリでは mysql_store_result() または mysql_use_result() を呼び出す必要はありませんが、すべてのケースで mysql_store_result() を呼び出しても、異常が発生したり、目立った動作が行われるようなことはありません。mysql_store_result() が 0 を返すかどうかを調べることで、クエリで結果セットが生成されたかどうかを検出できます。これについては後述します。

クエリが結果セットを返すタイプかどうかを調べるには、mysql_field_count() を使用します。 See 項11.1.3.20. 「mysql_field_count()

mysql_store_result() は、クエリの結果セット全体をクライアントに読み込み、MYSQL_RES 構造体にメモリを割り当て、この構造体に結果セットを格納します。

クエリが結果セットを返さない場合(たとえば、クエリが INSERT ステートメントだった場合)、mysql_store_result() はヌルポインタを返します。

また、結果セットの読み込みに失敗した場合も、mysql_store_result() はヌルポインタを返します。エラーが発生したかどうかを調べるには、mysql_error() がヌルポインタを返さないかどうか、mysql_errno() が 0 以外の値を返すかどうか、または mysql_field_count() が 0 以外の値を返すかどうかを調べます。

返すレコードが存在しない場合は空の結果セットが返されます(空の結果セットは、戻り値としてのヌルポインタとは異なります)。

mysql_store_result() を呼び出して、戻り値がヌルポインタ以外だった場合、mysql_num_rows() を呼び出すと結果セットに含まれるレコード数を取得できます。

mysql_fetch_row() を呼び出すと、結果セットからレコードを取得できます。mysql_row_seek() および mysql_row_tell() を呼び出すと、結果セット内のカレントレコードの位置を設定および取得できます。

結果セットが必要なくなったら、mysql_free_result() を呼び出す必要があります。

See 項11.1.12.1. 「mysql_query() が正常に終了した後で mysql_store_result()NULL を返す場合があるのはなぜか」

戻り値

結果セットが格納された MYSQL_RES 構造体。エラーが発生した場合は NULL

エラー

mysql_store_result() は、正常終了した場合に mysql_error および mysql_errno をリセットします。

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.56. mysql_thread_id()

unsigned long mysql_thread_id(MYSQL *mysql)

説明

現在の接続のスレッド ID を返します。この戻り値を、mysql_kill() に引数として渡してスレッドを強制終了することができます。

現在の接続が切断され、mysql_ping() を使用して再接続した場合、スレッド ID は別の値になります。これは、取得したスレッド ID を保管して後で使用することはできないことを意味します。スレッド ID が必要になったときに、取得する必要があります。

戻り値

現在の接続のスレッド ID。

エラー

ありません。

11.1.3.57. mysql_use_result()

MYSQL_RES *mysql_use_result(MYSQL *mysql)

説明

正常にデータを取得したクエリ(SELECTSHOWDESCRIBEEXPLAIN)については、mysql_store_result() または mysql_use_result() を呼び出す必要があります。

mysql_use_result() は、結果セットの取得を開始しますが、mysql_store_result() のように実際に結果セットをクライアントに読み込むわけではありません。代わりに、mysql_fetch_row() を呼び出して、1 行ずつ個別に取得する必要があります。その場合、クエリの結果は直接サーバから読み込まれ、テンポラリテーブルやローカルバッファには格納されません。これは mysql_store_result() を使用する場合よりも多少高速であり、使用するメモリも少なくてすみます。クライアントは、カレントレコードおよび max_allowed_packet バイトまで増える可能性のある通信バッファにメモリを割り当てるだけです。

一方、それぞれのレコードに対するクライアント側での処理量が多い場合、またはユーザが ^S を入力する(スクロールを停止する)可能性がある画面にデータを出力する場合は、mysql_use_result() の使用は避ける必要があります。そのような処理の場合、サーバの動作が停止して、読み取られているデータが格納されているテーブルを他のスレッドが更新できなくなります。

mysql_use_result() を使用する場合、NULL が返されるまで mysql_fetch_row() を繰り返し呼び出す必要があります。そうしないと、取得されなかったレコードが、次に実行するクエリの結果セットの一部として返されます。取得されなかったレコードが残っている場合、C API はエラー Commands out of sync; you can't run this command now を返します。

mysql_use_result() が返した結果セットに対して mysql_data_seek()mysql_row_seek()mysql_row_tell()mysql_num_rows()、または mysql_affected_rows() を使用することはできません。また、mysql_use_result() が完了するまでは他のクエリを発行できません(ただし、すべてのレコードを取得した後であれば mysql_num_rows() は取得したレコードの数を正確に返します)。

結果セットが必要なくなったら、mysql_free_result() を呼び出す必要があります。

戻り値

MYSQL_RES 構造体。エラーが発生した場合は NULL

エラー

mysql_use_result() は、正常終了した場合に mysql_error および mysql_errno をリセットします。

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.3.58. mysql_warning_count()

unsigned int mysql_warning_count(MYSQL *mysql)

説明

前回実行された SQL ステートメントの実行中に発生した警告数を返します。この関数は、MySQL 4.1 で追加されました。

戻り値

警告数。

エラー

ありません。

11.1.3.59. mysql_commit()

my_bool mysql_commit(MYSQL *mysql)

説明

現在のトランザクションをコミットします。この関数は、MySQL 4.1 で追加されました。

戻り値

正常に動作した場合は 0。エラーが発生した場合は 0 以外。

エラー

ありません。

11.1.3.60. mysql_rollback()

my_bool mysql_rollback(MYSQL *mysql)

説明

現在のトランザクションをロールバックします。この関数は、MySQL 4.1 で追加されました。

戻り値

正常に動作した場合は 0。エラーが発生した場合は 0 以外。

エラー

ありません。

11.1.3.61. mysql_autocommit()

my_bool mysql_autocommit(MYSQL *mysql, my_bool mode)

説明

mode が 1 の場合は自動コミットモードを有効に、mode が 0 の場合は無効にします。この関数は、MySQL 4.1 で追加されました。

戻り値

正常に動作した場合は 0。エラーが発生した場合は 0 以外。

エラー

ありません。

11.1.3.62. mysql_more_results()

my_bool mysql_more_results(MYSQL *mysql)

説明

現在実行しているクエリの他にまだ取得していない結果セットが存在し、アプリケーションが mysql_next_result() を呼び出して取得する必要がある場合は、true を返します。この関数は、MySQL 4.1 で追加されました。

戻り値

取得されていない結果セットが存在する場合は TRUE(1)。取得されていない結果セットが存在しない場合は FALSE(0)。

注意: ほとんどの場合、この関数の代わりに mysql_next_result() を呼び出して取得されていない結果セットがあるかどうかを調べて、存在する場合は次の結果セットを開始します。

See 項11.1.8. 「C API における複数クエリの実行の取り扱い」。 See 項11.1.3.63. 「mysql_next_result()

エラー

ありません。

11.1.3.63. mysql_next_result()

int mysql_next_result(MYSQL *mysql)

説明

取得されていない結果セットが存在する場合、mysql_next_result() は次のクエリの結果セットを読み込み、ステータスをアプリケーションに返します。この関数は、MySQL 4.1 で追加されました。

注意: 前のクエリが結果セットを返していた場合、mysql_free_result() を呼び出す必要があります。

mysql_next_result() を呼び出した後、接続の状態は次のクエリについて mysql_real_query() を呼び出した後と同様になります。これは、この関数を呼び出した後、この接続で mysql_store_result()mysql_warning_count()mysql_affected_rows() などを呼び出すことができることを意味します。

mysql_next_result() がエラーを返した場合、他のステートメントは実行されません。また、取得されていない結果セットも存在しません。

See 項11.1.8. 「C API における複数クエリの実行の取り扱い」

戻り値

呼び出しが正常に動作し、取得する結果セットが存在していた場合は 0、取得する結果セットが存在しなかった場合は -1、エラーが発生した場合は正の値。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。たとえば、前の結果セットで mysql_use_result() が呼び出されなかった場合にこのエラーが発生する。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.4. C API のプリペアドステートメント

MySQL 4.1 では、プリペアドステートメントを使用するためのクライアント/サーバプロトコルが提供されています。この機能は、MYSQL_STMT ステートメントハンドラデータ構造体を使用します。プリペアドステートメントの実行は、ステートメントを繰り返し実行する場合に効率的な方法です。ステートメントは、実行する準備を整えるために、まず解析されます。その後、prepare 関数から返されるステートメントハンドルを使用して、1 回以上実行されます。

プリペアドステートメントの実行は、解析が 1 回しか行われないため、ステートメントを直接複数回実行するよりも高速です。ステートメントを直接実行した場合、そのたびにクエリの解析が行われます。プリペアドステートメントを実行する場合、ネットワークトラフィックも、パラメータとしてデータを送信するときに発生するだけなので、削減できます。

その他にも、プリペアドステートメントの実行ではバイナリプロトコルを使用するので、クライアントおよびサーバ間のデータ転送の効率が向上するという利点があります。プリペアドステートメントは、複数クエリを実行する際の入力および出力のバインディングもサポートします。

11.1.5. C API のプリペアドステートメントのデータ型

注意: プリペアドステートメントの API は、今後改訂される可能性があります。ここで説明する情報は、すぐにこの API を使用する開発者向けに書かれていますが、今後 API が変更になる可能性があることをご承知おきください。

プリペアドステートメントは、主に MYSQL_STMT および MYSQL_BIND の各データ構造体を使用します。その他に、時間的なデータを転送するために MYSQL_TIME を使用します。

  • MYSQL_STMT

    この構造体は、プリペアドステートメントを表す。プリペアドステートメントは、mysql_prepare() を呼び出して作成する。この関数は、MYSQL_STMT へのポインタであるステートメントハンドルを返す。このハンドルは、その後に呼び出されるすべてのステートメント関連の関数で使用される。

    MYSQL_STMT 構造体のメンバをアプリケーションが使用することはない。

    1 つの接続に複数のステートメントハンドルを関連付けることができる。関連付けるハンドル数は、使用できるシステムリソースによって制限される。

  • MYSQL_BIND

    この構造体は、クエリの入力(データ値がサーバに送信される)および出力(結果値がサーバから返される)の両方で使用される。入力の場合、mysql_bind_param() に渡してパラメータデータ値をバッファにバインドし、mysql_execute() が使用できるようにする。出力の場合、mysql_bind_result() に渡して結果セットをバッファにバインドし、mysql_fetch() でレコードを取得する際に使用できるようにする。

    MYSQL_BIND 構造体では、以下に示すメンバをアプリケーションプログラムが使用できる。どのメンバも入力および出力のどちらにも使用するが、データ転送の方向によって異なる目的で使用する場合がある。

    • enum enum_field_types buffer_type

      バッファの型。使用できる buffer_type の値のリストを、このセクションの後半に示す。入力の場合、buffer_type はクエリパラメータにバインドする値の型を表す。出力の場合、結果セットのバッファで受け取る値の型を表す。

    • void *buffer

      入力の場合、クエリパラメータのデータ値が保存されるバッファへのポインタ。出力の場合、結果セットのカラム値を返すバッファへのポインタ。カラム型が数値の場合、buffer は適切な C 言語の型の変数へのポインタとする必要がある(UNSIGNED 属性を持つカラムに変数を関連付けている場合、変数は C 言語の unsigned 型とする必要がある)。カラム型が日付および時刻の場合、bufferMYSQL_TIME 構造体へのポインタとする必要がある。カラム型が文字列およびバイナリ文字列の場合、buffer は文字バッファへのポインタとする必要がある。

    • unsigned long buffer_length

      バイト単位で表した *buffer の実際のサイズ。この値は、バッファに格納できるデータの最大サイズを示す。C の文字データおよびバイナリデータの場合、buffer_length の値は、mysql_bind_param() で使用する場合は *buffer が示すデータの長さ、または mysql_bind_result() で使用する場合はバッファに取得できる最大データバイト数を指定する。

    • unsigned long *length

      unsigned long 変数へのポインタ。*buffer に格納するデータの実際のバイト数を示す。length は、格納するデータが C の文字データまたはバイナリデータの場合に使用する。入力パラメータデータをバインドする場合、length は、*buffer に格納するパラメータ値の長さを示す unsigned long 変数を指す。これは mysql_execute() で使用される。length がヌルポインタの場合、プロトコルはすべての文字データおよびバイナリデータがヌルで終端されていると仮定する。出力値をバインドする場合、mysql_fetch() は、返すデータのカラム値の長さを length がポイントする変数に設定する。

      数値データ型または時間的なデータ型の場合、データ値の長さは buffer_type の値によって決まるので、length は無視される。

    • my_bool *is_null

      my_bool 変数へのポインタ。値が NULL の場合は true、NULL 以外の場合は false。入力の場合、*is_null を true に設定することによって、クエリパラメータとして NULL 値を渡していることを示す。出力の場合、クエリが返す値が NULL のときにレコードを取得すると、この値が true に設定される。

  • MYSQL_TIME

    この構造体は、サーバと直接 DATETIMEDATETIME、および TIMESTAMP データを送受信するために使用する。それには、MYSQL_BIND 構造体の buffer_type メンバをいずれかの時間を表す型に設定し、buffer メンバを MYSQL_TIME 構造体をポイントするように設定する。

    MYSQL_TIME 構造体のメンバを以下に示す。

    • unsigned int year

      年。

    • unsigned int month

      月。

    • unsigned int day

      日。

    • unsigned int hour

      時。

    • unsigned int minute

      分。

    • unsigned int second

      秒。

    • my_bool neg

      時間が負かどうかを示すブール値フラグ。

    • unsigned long second_part

      秒の小数部。現在は未使用。

    MYSQL_TIME 構造体のメンバは、使用する時間的な型に対応する部分だけが使用される。yearmonth、および day の各メンバは、DATEDATETIME、および TIMESTAMP の値に使用する。hourminute、および second の各メンバは、TIMEDATETIME、および TIMESTAMP の値に使用する。 See 項11.1.9. 「C API における日付値および時刻値の取り扱い」

MYSQL_BIND 構造体の buffer_type メンバに指定できる値を以下の表に示します。この表には、それぞれの buffer_type の値に最も近い SQL のデータ型を示し、さらに数値型と時間的な値の型については対応する C のデータ型も示します。

buffer_type SQL のデータ型C のデータ型
MYSQL_TYPE_TINYTINYINTchar
MYSQL_TYPE_SHORTSMALLINTshort int
MYSQL_TYPE_LONGINTlong int
MYSQL_TYPE_LONGLONGBIGINTlong long int
MYSQL_TYPE_FLOATFLOATfloat
MYSQL_TYPE_DOUBLEDOUBLEdouble
MYSQL_TYPE_TIMETIMEMYSQL_TIME
MYSQL_TYPE_DATEDATEMYSQL_TIME
MYSQL_TYPE_DATETIMEDATETIMEMYSQL_TIME
MYSQL_TYPE_TIMESTAMPTIMESTAMPMYSQL_TIME
MYSQL_TYPE_STRINGCHAR?
MYSQL_TYPE_VAR_STRINGVARCHAR?
MYSQL_TYPE_TINY_BLOBTINYBLOB/TINYTEXT?
MYSQL_TYPE_BLOBBLOB/TEXT?
MYSQL_TYPE_MEDIUM_BLOBMEDIUMBLOB/MEDIUMTEXT?
MYSQL_TYPE_LONG_BLOBLONGBLOB/LONGTEXT?

暗黙のデータ型変換はどちらの方向にも行われる可能性があります。

11.1.6. C API のプリペアドステートメント関数の概要

注意: プリペアドステートメントの API は、今後改訂される可能性があります。ここで説明する情報は、すぐにこの API を使用する開発者向けに書かれていますが、今後 API が変更になる可能性があることをご承知おきください。

ここでは、プリペアドステートメントの処理に使用できる関数について簡単に説明します。詳細については、以降のセクションで説明します。 See 項11.1.7. 「C API のプリペアドステートメント関数の説明」

関数説明
mysql_prepare()SQL 文字列を実行するためのプリコンパイルを行う。
mysql_param_count()プリペアドステートメントのパラメータ数を返す。
mysql_get_metadata()プリペアドステートメントメタデータを結果セット形式で返す。
mysql_bind_param()アプリケーションデータバッファを、プリペアドステートメント内のパラメータマーカーに関連付ける。
mysql_execute()プリペアドステートメントを実行する。
mysql_stmt_affected_rows()最後に実行された UPDATEDELETE、または INSERT のいずれかのクエリによって変更、削除、または挿入されたレコードの数を返す。
mysql_bind_result()アプリケーションデータバッファを、結果セットのカラムに関連付ける。
mysql_stmt_store_result()結果セット全体を取得してクライアントに転送する。
mysql_stmt_data_seek()ステートメントの結果セットの任意のレコード番号にシークする。
mysql_stmt_row_seek()mysql_stmt_row_tell() から返された値をオフセットとして、ステートメントの結果セット内のレコードにシークする。
mysql_stmt_row_tell()ステートメントのレコードカーソルの位置を返す。
mysql_stmt_num_rows()バッファに格納されたステートメントの結果セット全体のレコード数を返す。
mysql_fetch()結果セットの次のレコードのデータを取得し、バインドされたすべてのカラムのデータを返す。
mysql_stmt_close()プリペアドステートメントが使用していたメモリを解放する。
mysql_stmt_errno()最後に実行されたステートメントのエラー番号を返す。
mysql_stmt_error()最後に実行されたステートメントのエラーメッセージを返す。
mysql_stmt_sqlstate()最後に実行したステートメントの SQLSTATE エラーコードを返す。
mysql_send_long_data()long 型データを切り分けてサーバに送信する。

mysql_prepare() を呼び出してステートメントハンドルをプリコンパイルし、初期化します。次に mysql_bind_param() を呼び出してパラメータデータを渡し、mysql_execute() を呼び出してクエリを実行します。mysql_bind_param() 経由で渡すバッファに格納したパラメータ値を変更して、mysql_execute() を繰り返し実行することもできます。

クエリが SELECT ステートメントの場合、または結果セットを生成するその他のクエリの場合、mysql_prepare()mysql_get_metadata() を使用して MYSQL_RES 結果セット形式で結果セットのメタデータ情報も返します。

結果を格納するバッファを mysql_bind_result() を使用して渡すことによって、mysql_fetch() は自動的にそのバッファにデータを返します。ここでは 1 行ずつの取得が行われます。

オプションとして is_long_data=1 または length=MYSQL_LONG_DATA または -2 を指定した MYSQL_BIND 構造体を mysql_bind_param() で渡すと、mysql_send_long_data() を使用してテキストデータまたはバイナリデータを切り分けてサーバに送信できます。

ステートメントの実行が完了したら、mysql_stmt_close() を呼び出してステートメントハンドルをクローズし、ハンドルに関連付けられているすべてのリソースを解放する必要があります。

mysql_get_metadata() を呼び出して SELECT ステートメントの結果セットメタデータを取得していた場合も、mysql_free_result() を呼び出して解放する必要があります。

実行ステップ

ステートメントをプリコンパイルして実行するには、アプリケーションで以下のステップに従って処理します。

  1. SQL ステートメントを含む文字列をパラメータとして mysql_prepare() を呼び出す。プリコンパイルが正常に終了した場合、mysql_prepare() は有効なステートメントハンドラをアプリケーションに返す。

  2. 結果セットを生成するクエリを実行する場合、mysql_get_metadata() を呼び出して結果セットメタデータを取得する。このメタデータはそれ自身が結果セット形式である。ただし、クエリが返すレコードを含む結果セットとは別に渡される。結果セットメタデータには、結果セットに含まれるカラム数および各カラムに関する情報が含まれる。

  3. mysql_bind_param() を使用して、パラメータの値を設定する。すべてのパラメータの値を設定する必要がある。値が設定されていないパラメータが残っていると、エラーが返されたり、予想外の結果が発生する。

  4. mysql_execute() を呼び出してステートメントを実行する。

  5. 結果セットを生成するクエリを実行した場合、mysql_bind_result() を呼び出して、レコードの値を取得するためのデータバッファをバインドする。

  6. mysql_fetch() を呼び出して、1 行分のデータをバッファに取得する。すべてのレコードのデータを取得できるまでこれを繰り返す。

  7. 必要に応じてステップ 3 から 6 までを繰り返して、パラメータの値を変更しながらステートメントを再実行する。

mysql_prepare() が呼び出された場合に実行される MySQL クライアント/サーバのプロトコルを以下に示します。

  • サーバはクエリを解析し、ステートメント ID を割り当てて、OK ステータスをクライアントに返信する。結果セットを生成するクエリの場合は、さらに、パラメータの合計数、カラム数、およびそのメタ情報を送信する。この呼び出しで、サーバはクエリのすべての構文および意味を確認する。

  • クライアントはこのステートメント ID を使用してその後の処理を実行する。この ID を使用して、サーバはステートメントプールの中から使用するステートメントを識別する。また、クライアントはステートメントハンドルをこの ID に割り当て、ハンドルをアプリケーションに返す。

mysql_execute() が呼び出された場合に実行される MySQL クライアント/サーバプロトコルを以下に示します。

  • クライアントはステートメントハンドルを使用して、サーバにパラメータデータを送信する。

  • サーバはクライアントから渡された ID を使用してステートメントを識別し、パラメータマーカーを新しく渡されたデータに置き換え、クエリを実行する。結果セットを生成するクエリを実行した場合、サーバはデータをクライアントに返信する。結果セットを生成しないクエリを実行した場合、サーバは OK ステータスおよび変更、削除、または挿入されたレコードの合計数を返す。

mysql_fetch() が呼び出された場合に実行される MySQL クライアント/サーバプロトコルを以下に示します。

  • クライアントは、パケットから 1 行分ずつデータを読み込み、必要に応じてデータ変換しながらアプリケーションデータバッファに格納する。アプリケーションバッファの型がサーバから返されたフィールドの型と同じ場合は、直接的に変換が行われる。

mysql_stmt_errno()mysql_stmt_error()、および mysql_stmt_sqlstate() を使用すると、それぞれステートメントのエラーコード、エラーメッセージ、および SQLSTATE 値を取得できます。

11.1.7. C API のプリペアドステートメント関数の説明

クエリをプリコンパイルして実行するには、以下の関数を使用します。

11.1.7.1. mysql_prepare()

MYSQL_STMT * mysql_prepare(MYSQL *mysql, const char *query, unsigned long length)

説明

ヌル終端文字列 query で指定された SQL クエリをプリコンパイルし、その後の処理に使用するステートメントハンドルを返します。このクエリは単一 SQL ステートメントで構成されている必要があります。このステートメントには、その終わりを示すセミコロン(‘;’)または \g を追加する必要はありません。

アプリケーションは、SQL 文字列の適当な位置に疑問符(‘?’)を埋め込むことで、SQL ステートメントで 1 つ以上のパラメータマーカーを使用できます。

マーカーは、SQL ステートメントの特定の位置に埋め込まれた場合にのみ適正に処理されます。たとえば、マーカーは INSERT ステートメントの VALUES() のリストでレコードに設定するカラムの値を指定する部分、または WHERE 節でカラムの値と比較する値を指定する部分に使用できます。しかし、SELECT ステートメントが返すカラムを指定する選択リストで識別子(テーブルまたはカラムの名前など)として使用したり、等号(=)などのバイナリ演算子の両方のオペランドを指定することはできません。パラメータの型を決定することができないので、後者の制約が必要になります。一般に、パラメータは、データ操作言語(DML)ステートメントでのみ適正に処理され、データ定義言語(DDL)ステートメントでは処理されません。

パラメータマーカーは、ステートメントを実行する前に、mysql_bind_param() を使用してアプリケーション変数にバインドする必要があります。

戻り値

コンパイルが正常に終了した場合は MYSQL_STMT 構造体へのポインタ。エラーが発生した場合は NULL

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

コンパイルが失敗した場合(mysql_prepare()NULL を返した場合)、エラーメッセージは mysql_error() を呼び出すことによって取得できます。

mysql_prepare() の使用方法については、項11.1.7.5. 「mysql_execute() の「例」を参照してください。

11.1.7.2. mysql_param_count()

unsigned long mysql_param_count(MYSQL_STMT *stmt)

説明

プリコンパイルされたステートメントに含まれるパラメータマーカーの数を返します。

戻り値

ステートメントに含まれるパラメータ数を表す unsigned long 整数。

エラー

ありません。

mysql_param_count() の使用方法については、項11.1.7.5. 「mysql_execute() の「例」を参照してください。

11.1.7.3. mysql_get_metadata()

MYSQL_RES *mysql_get_metadata(MYSQL_STMT *stmt)

説明

mysql_prepare() に渡されたステートメントが結果セットを生成するものである場合、mysql_get_metadata()MYSQL_RES 構造体へのポインタという形で結果セットメタデータを返します。この構造体を使用して、フィールドの合計数および個々のフィールド情報などのメタ情報を処理できます。この結果セットへのポインタは、結果セットメタデータを処理する以下のフィールドベースの API 関数に引数として渡すことができます。

  • mysql_num_fields()

  • mysql_fetch_field()

  • mysql_fetch_field_direct()

  • mysql_fetch_fields()

  • mysql_field_count()

  • mysql_field_seek()

  • mysql_field_tell()

  • mysql_free_result()

結果セット構造体は、使用する必要がなくなったら mysql_free_result() に渡して解放する必要があります。これは、mysql_store_result() を呼び出して取得した結果セットを解放する方法と似ています。

mysql_get_metadata() から返される結果セットには、メタデータだけが含まれます。レコードデータは含まれません。レコードを取得するには、ステートメントハンドルをパラメータとして mysql_fetch() を呼び出します。

戻り値

MYSQL_RES 構造体。プリコンパイルしたクエリのメタ情報が存在しない場合は NULL

エラー

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

mysql_get_metadata() の使用方法については、項11.1.7.13. 「mysql_fetch() の「例」を参照してください。

11.1.7.4. mysql_bind_param()

my_bool mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)

説明

mysql_bind_param() は、mysql_prepare() に渡された SQL ステートメントに含まれるパラメータマーカーのデータをバインドするために使用します。データは MYSQL_BIND 構造体を使用して渡します。bind は、MYSQL_BIND 構造体の配列のアドレスです。クライアントライブラリは、この配列に、クエリに含まれる各 ‘?’ パラメータに対応する要素が含まれていると仮定します。

たとえば、以下のステートメントをプリコンパイルするとします。

INSERT INTO mytbl VALUES(?,?,?)

パラメータをバインドする場合、MYSQL_BIND 構造体には 3 つの要素が必要であり、以下のように宣言できます。

MYSQL_BIND bind[3];

設定する必要がある MYSQL_BIND の各要素のメンバについては、項11.1.5. 「C API のプリペアドステートメントのデータ型」 を参照してください。

戻り値

正常にバインドできた場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_NO_PREPARE_STMT

    プリコンパイルされたステートメントが存在しない。

  • CR_NO_PARAMETERS_EXISTS

    バインドするパラメータが存在しない。

  • CR_INVALID_BUFFER_USE

    これがlong データを切り分けて渡すためのバインドか、およびバッファの型が文字列以外またはバイナリ以外かを示す。

  • CR_UNSUPPORTED_PARAM_TYPE

    変換がサポートされていない。buffer_type の値が正しくないか、またはサポートされていない型である可能性がある。

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

mysql_bind_param() の使用方法については、項11.1.7.5. 「mysql_execute() の「例」を参照してください。

11.1.7.5. mysql_execute()

int mysql_execute(MYSQL_STMT *stmt)

説明

mysql_execute() は、ステートメントハンドルに関連付けられているプリコンパイルされたクエリを実行します。この呼び出しの際に、現在バインドされているパラメータマーカーの値がサーバに送信され、サーバはマーカーをここで渡されたデータで置き換えます。

ステートメントが UPDATEDELETE、または INSERT の場合、mysql_stmt_affected_rows() を呼び出すことによって、変更、削除、または挿入されたレコードの合計数を取得できます。これが SELECT などの結果セットを生成するクエリの場合、最初に mysql_fetch() を呼び出してデータを取得してから、他のクエリ処理を必要とする関数を呼び出す必要があります。結果を取得する方法の詳細については、項11.1.7.13. 「mysql_fetch() を参照してください。

戻り値

正常に実行した場合は 0。エラーが発生した場合は 0 以外。エラーコードおよびエラーメッセージは、mysql_stmt_errno() および mysql_stmt_error() を呼び出すことによって取得できます。

エラー

  • CR_NO_PREPARE_QUERY

    実行する前にプリコンパイルされたクエリが存在しない。

  • CR_ALL_PARAMS_NOT_BOUND

    渡されていないパラメータデータがある。

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

以下の例では、mysql_prepare()mysql_param_count()mysql_bind_param()mysql_execute()、および mysql_stmt_affected_rows() を使用して、テーブルを作成し、データを挿入する方法を示します。mysql 変数は有効な接続ハンドルとします。

#define STRING_SIZE 50

#define DROP_SAMPLE_TABLE "DROP TABLE IF EXISTS test_table"
#define CREATE_SAMPLE_TABLE "CREATE TABLE test_table(col1 INT,\
                                                 col2 VARCHAR(40),\
                                                 col3 SMALLINT,\
                                                 col4 TIMESTAMP)"
#define INSERT_SAMPLE "INSERT INTO test_table(col1,col2,col3) VALUES(?,?,?)"

MYSQL_STMT    *stmt;
MYSQL_BIND    bind[3];
my_ulonglong  affected_rows;
int           param_count;
short         small_data;
int           int_data;
char          str_data[STRING_SIZE];
unsigned long str_length;
my_bool       is_null;

if (mysql_query(mysql, DROP_SAMPLE_TABLE))
{
  fprintf(stderr, " DROP TABLE failed\n");
  fprintf(stderr, " %s\n", mysql_error(mysql));
  exit(0);
}

if (mysql_query(mysql, CREATE_SAMPLE_TABLE))
{
  fprintf(stderr, " CREATE TABLE failed\n");
  fprintf(stderr, " %s\n", mysql_error(mysql));
  exit(0);
}

/* Prepare an INSERT query with 3 parameters */
/* (the TIMESTAMP column is not named; it will */
/* be set to the current date and time) */
stmt = mysql_prepare(mysql, INSERT_SAMPLE, strlen(INSERT_SAMPLE));
if (!stmt)
{
  fprintf(stderr, " mysql_prepare(), INSERT failed\n");
  fprintf(stderr, " %s\n", mysql_error(mysql));
  exit(0);
}
fprintf(stdout, " prepare, INSERT successful\n");

/* Get the parameter count from the statement */
param_count= mysql_param_count(stmt);
fprintf(stdout, " total parameters in INSERT: %d\n", param_count);

if (param_count != 3) /* validate parameter count */
{
  fprintf(stderr, " invalid parameter count returned by MySQL\n");
  exit(0);
}

/* Bind the data for all 3 parameters */

/* INTEGER PARAM */
/* This is a number type, so there is no need to specify buffer_length */
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&int_data;
bind[0].is_null= 0;
bind[0].length= 0;

/* STRING PARAM */
bind[1].buffer_type= MYSQL_TYPE_STRING;
bind[1].buffer= (char *)str_data;
bind[1].buffer_length= STRING_SIZE;
bind[1].is_null= 0;
bind[1].length= &str_length;
 
/* SMALLINT PARAM */
bind[2].buffer_type= MYSQL_TYPE_SHORT;
bind[2].buffer= (char *)&small_data;       
bind[2].is_null= &is_null;
bind[2].length= 0;

/* Bind the buffers */
if (mysql_bind_param(stmt, bind))
{
  fprintf(stderr, " mysql_bind_param() failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}

/* Specify the data values for the first row */
int_data= 10;             /* integer */
strncpy(str_data, "MySQL", STRING_SIZE); /* string  */
str_length= strlen(str_data);

/* INSERT SMALLINT data as NULL */
is_null= 1;

/* Execute the INSERT statement - 1*/
if (mysql_execute(stmt))
{
  fprintf(stderr, " mysql_execute(), 1 failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}
  
/* Get the total number of affected rows */   
affected_rows= mysql_stmt_affected_rows(stmt);
fprintf(stdout, " total affected rows(insert 1): %ld\n", affected_rows);

if (affected_rows != 1) /* validate affected rows */
{
  fprintf(stderr, " invalid affected rows by MySQL\n");
  exit(0);
}

/* Specify data values for second row, then re-execute the statement */
int_data= 1000;             
strncpy(str_data, "The most popular open source database", STRING_SIZE); 
str_length= strlen(str_data);
small_data= 1000;         /* smallint */
is_null= 0;               /* reset */

/* Execute the INSERT statement - 2*/
if (mysql_execute(stmt))
{
  fprintf(stderr, " mysql_execute, 2 failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}
  
/* Get the total rows affected */   
affected_rows= mysql_stmt_affected_rows(stmt);
fprintf(stdout, " total affected rows(insert 2): %ld\n", affected_rows);

if (affected_rows != 1) /* validate affected rows */
{
  fprintf(stderr, " invalid affected rows by MySQL\n");
  exit(0);
}

/* Close the statement */
if (mysql_stmt_close(stmt))
{
  fprintf(stderr, " failed while closing the statement\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}

注意: プリペアドステートメント関数を使用した完全な例については、ファイル tests/mysql_client_test.c を参照してください。このファイルは、MySQL ソースディストリビューションまたは BitKeeper ソースリポジトリから取得できます。

11.1.7.6. mysql_stmt_affected_rows()

my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt)

説明

最後に実行されたステートメントによって変更、削除、または挿入されたレコードの合計数を返します。UPDATEDELETE、または INSERT のいずれかのステートメントに対して mysql_execute() を呼び出した直後に呼び出される可能性があります。SELECT ステートメントの場合、mysql_stmt_affected_rows() を呼び出すと、mysql_num_rows() と同様に動作します。

戻り値

正の整数は、影響を与えた、または取得した、レコード数を示します。0 は、UPDATE によって更新されたレコードがなかったこと、クエリの WHERE 節に一致するレコードがなかったこと、またはクエリが実行されていないことを示します。?1 は、クエリがエラーを返したこと、または SELECT クエリの場合に mysql_fetch() を呼び出す前に mysql_stmt_affected_rows() が呼び出されたことを示します。

エラー

ありません。

mysql_stmt_affected_rows() の使用方法については、項11.1.7.5. 「mysql_execute() の「例」を参照してください。

11.1.7.7. mysql_bind_result()

my_bool mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)

説明

mysql_bind_result() は、結果セットのカラムをデータバッファおよび長さバッファに関連付ける(バインドする)ために使用します。mysql_fetch() を呼び出してデータを取得する場合、MySQL クライアント/サーバプロトコルによって、バインドされたカラムのデータが指定されたバッファに書き込まれます。

注意: mysql_fetch() を呼び出す前に、すべてのカラムをバッファにバインドする必要があります。bind は、MYSQL_BIND 構造体の配列のアドレスです。クライアントライブラリは、この配列に、結果セットの各カラムに対応した要素が含まれていると仮定します。要素が含まれていない場合、mysql_fetch() は単にデータを取得しません。また、クライアント/サーバプロトコルはデータの値を切り分けて返すことはしないので、バッファのサイズはデータ値を格納できるだけの十分な大きさである必要があります。

カラムは、任意の時点で、結果セットの一部だけが取得された後でも、バインドまたは再バインドすることができます。新しくバインドした場合、それが有効になるのは、次に mysql_fetch() を呼び出したときです。たとえば、アプリケーションが結果セットのカラムをバインドして mysql_fetch() を呼び出すとします。クライアント/サーバプロトコルは、バインドされたバッファにデータを返します。次にアプリケーションがカラムを別のバッファにバインドするとします。プロトコルは、次に mysql_fetch() が呼び出されるまで、新しくバインドされたバッファにデータを書き込みません。

カラムをバインドするには、アプリケーションは mysql_bind_result() を呼び出して、型、アドレス、および長さバッファのアドレスを渡します。設定する必要がある MYSQL_BIND の各要素のメンバについては、項11.1.5. 「C API のプリペアドステートメントのデータ型」 を参照してください。

戻り値

正常にバインドできた場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_NO_PREPARE_STMT

    プリコンパイルされたステートメントが存在しない。

  • CR_UNSUPPORTED_PARAM_TYPE

    変換がサポートされていない。buffer_type の値が正しくないか、またはサポートされていない型である可能性がある。

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

mysql_bind_result() の使用方法については、項11.1.7.13. 「mysql_fetch() の「例」を参照してください。

11.1.7.8. mysql_stmt_store_result()

int mysql_stmt_store_result(MYSQL_STMT *stmt)

説明

クエリが結果セットを正常に生成し(SELECTSHOWDESCRIBEEXPLAIN)、さらにクライアントのバッファに結果セット全体を格納して、その後の mysql_fetch() の呼び出しでバッファされたデータが返されるようにする場合に限り、mysql_stmt_store_result() を呼び出す必要があります。

そのようなクエリ以外では mysql_stmt_store_result() を呼び出す必要はありませんが、呼び出したとしても異常が発生したり、目立った動作が行われるようなことは一切ありません。mysql_get_metadata()NULL を返すかどうかを調べることで、クエリが結果セットを生成したかどうかを検出できます。詳細については、項11.1.7.3. 「mysql_get_metadata() を参照してください。

戻り値

結果セットが正常にバッファに格納された場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

11.1.7.9. mysql_stmt_data_seek()

void mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset)

説明

ステートメントの結果セットの任意のレコードにシークします。offset 値はレコード番号を表し、0 から mysql_stmt_num_rows(stmt)-1 の範囲で指定します。

mysql_stmt_data_seek() を使用するには、ステートメントの結果セット構造体に最後に実行されたクエリの結果全体が格納されている必要があるので、mysql_stmt_store_result() とともに使用する必要があります。

戻り値

ありません。

エラー

ありません。

11.1.7.10. mysql_stmt_row_seek()

MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET offset)

説明

ステートメントの結果セットの任意のレコードにレコードカーソルを設定します。offset の値はレコードオフセットであり、mysql_stmt_row_tell() または mysql_stmt_row_seek() の戻り値になります。この値はレコード番号ではありません。結果セット内のレコードに番号を指定してシークする場合は、この関数ではなく、mysql_stmt_data_seek() を使用します。

mysql_stmt_row_seek() を使用するには、結果セット構造体にクエリの結果全体が格納されている必要があるので、mysql_stmt_store_result() とともに使用する必要があります。

戻り値

シークする前のレコードカーソルの値。mysql_stmt_row_seek() を次に呼び出すときにこの値を渡すことができます。

エラー

ありません。

11.1.7.11. mysql_stmt_row_tell()

MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT *stmt)

説明

最後に実行された mysql_fetch() で使用されたレコードカーソルの現在の位置を返します。この戻り値を、mysql_stmt_row_seek() に引数として渡すことができます。

mysql_stmt_row_tell() は、mysql_stmt_store_result() の後でのみ使用できます。

戻り値

レコードカーソルの現在のオフセット。

エラー

ありません。

11.1.7.12. mysql_stmt_num_rows()

my_ulonglong mysql_stmt_num_rows(MYSQL_STMT *stmt)

説明

結果セットのレコード数を返します。

mysql_stmt_num_rows() を使用するかどうかは、mysql_stmt_store_result() を使用して結果セット全体をステートメントハンドルに格納したかどうかによって決まります。

mysql_stmt_store_result() を使用する場合、すぐに mysql_stmt_num_rows() を呼び出すことができます。

戻り値

結果セットのレコード数。

エラー

ありません。

11.1.7.13. mysql_fetch()

int mysql_fetch(MYSQL_STMT *stmt)

説明

mysql_fetch() は、結果セットの次のレコードを取得します。この関数は結果セットが存在する間のみ、すなわち、mysql_execute() を呼び出して結果セットを作成した後、または mysql_execute() を呼び出して結果セット全体をバッファに格納してから mysql_stmt_store_result() を呼び出した後にのみ、呼び出すことができます。

mysql_fetch() は、mysql_bind_result() を呼び出してバインドしたバッファを使用してレコードデータを返します。バッファには、現在のレコードセットのすべてのカラムのデータが格納されます。データの長さは length ポインタに返されます。

注意: アプリケーションは、mysql_fetch() を呼び出す前に、すべてのカラムをバッファにバインドする必要があります。

取得したデータが NULL 値だった場合、対応する MYSQL_BIND 構造体の *is_null の値には TRUE(1)が格納されます。それ以外の値だった場合、アプリケーションが指定したバッファの型に基づいて、データおよびその長さがそれぞれ *buffer 要素および *length 要素に返されます。数値型および時間的な値の型は、以下の表に示すように、それぞれ固定長です。文字列型の長さは、実際のデータの長さによって決まり、data_length によって表されます。

長さ
MYSQL_TYPE_TINY1
MYSQL_TYPE_SHORT2
MYSQL_TYPE_LONG4
MYSQL_TYPE_LONGLONG8
MYSQL_TYPE_FLOAT4
MYSQL_TYPE_DOUBLE8
MYSQL_TYPE_TIMEsizeof(MYSQL_TIME)
MYSQL_TYPE_DATEsizeof(MYSQL_TIME)
MYSQL_TYPE_DATETIMEsizeof(MYSQL_TIME)
MYSQL_TYPE_STRINGdata length
MYSQL_TYPE_BLOBdata_length

戻り値

戻り値説明
0正常。データはアプリケーションデータバッファに取得されている。
1エラーが発生した。エラーコードおよびエラーメッセージは、mysql_stmt_errno() および mysql_stmt_error() を呼び出すことによって取得できる。
MYSQL_NO_DATA取得されていないレコード/データは残っていない。

エラー

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_SERVER_LOST

    クエリの実行中にサーバへの接続が切断された。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

  • CR_UNSUPPORTED_PARAM_TYPE

    バッファの型は MYSQL_TYPE_DATEMYSQL_TYPE_TIMEMYSQL_TYPE_DATETIME、または MYSQL_TYPE_TIMESTAMP なのに、データの型は DATETIMEDATETIME、または TIMESTAMP のいずれでもない。

  • その他のサポートされていない変換に関するエラーはすべて mysql_bind_result() から返される。

以下の例では、mysql_get_metadata()mysql_bind_result()、および mysql_fetch() を使用して、テーブルからデータを取得する方法を示します(この例では 項11.1.7.5. 「mysql_execute() の例で挿入された 2 行のレコードを取得するものと想定しています)。mysql 変数は有効な接続ハンドルとします。

#define STRING_SIZE 50

#define SELECT_SAMPLE "SELECT col1, col2, col3, col4 FROM test_table"

MYSQL_STMT    *stmt;
MYSQL_BIND    bind[4];
MYSQL_RES     *prepare_meta_result;
MYSQL_TIME    ts;
unsigned long length[4];
int           param_count, column_count, row_count;
short         small_data;
int           int_data;
char          str_data[STRING_SIZE];
my_bool       is_null[4];

/* Prepare a SELECT query to fetch data from test_table */
stmt = mysql_prepare(mysql, SELECT_SAMPLE, strlen(SELECT_SAMPLE));
if (!stmt)
{
  fprintf(stderr, " mysql_prepare(), SELECT failed\n");
  fprintf(stderr, " %s\n", mysql_error(mysql));
  exit(0);
}
fprintf(stdout, " prepare, SELECT successful\n");

/* Get the parameter count from the statement */
param_count= mysql_param_count(stmt);
fprintf(stdout, " total parameters in SELECT: %d\n", param_count);

if (param_count != 0) /* validate parameter count */
{
  fprintf(stderr, " invalid parameter count returned by MySQL\n");
  exit(0);
}

/* Fetch result set meta information */
prepare_meta_result = mysql_get_metadata(stmt);
if (!prepare_meta_result)
{
  fprintf(stderr, " mysql_get_metadata(), returned no meta information\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}

/* Get total columns in the query */
column_count= mysql_num_fields(prepare_meta_result);
fprintf(stdout, " total columns in SELECT statement: %d\n", column_count);

if (column_count != 4) /* validate column count */
{
  fprintf(stderr, " invalid column count returned by MySQL\n");
  exit(0);
}

/* Execute the SELECT query */
if (mysql_execute(stmt))
{
  fprintf(stderr, " mysql_execute(), failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}

/* Bind the result buffers for all 4 columns before fetching them */

/* INTEGER COLUMN */
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&int_data;
bind[0].is_null= &is_null[0];
bind[0].length= &length[0];

/* STRING COLUMN */
bind[1].buffer_type= MYSQL_TYPE_STRING;
bind[1].buffer= (char *)str_data;
bind[1].buffer_length= STRING_SIZE;
bind[1].is_null= &is_null[1];
bind[1].length= &length[1];
 
/* SMALLINT COLUMN */
bind[2].buffer_type= MYSQL_TYPE_SHORT;
bind[2].buffer= (char *)&small_data;       
bind[2].is_null= &is_null[2];
bind[2].length= &length[2];
 
/* TIMESTAMP COLUMN */
bind[3].buffer_type= MYSQL_TYPE_TIMESTAMP;
bind[3].buffer= (char *)&ts;       
bind[3].is_null= &is_null[3];
bind[3].length= &length[3];

/* Bind the result buffers */
if (mysql_bind_result(stmt, bind))
{
  fprintf(stderr, " mysql_bind_result() failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}

/* Now buffer all results to client */
if (mysql_stmt_store_result(stmt))
{
  fprintf(stderr, " mysql_stmt_store_result() failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}

/* Fetch all rows */
row_count= 0;
fprintf(stdout, "Fetching results ...\n");
while (!mysql_fetch(stmt))
{
  row_count++;
  fprintf(stdout, "  row %d\n", row_count);

  /* column 1 */
  fprintf(stdout, "   column1 (integer)  : ");
  if (is_null[0])
    fprintf(stdout, " NULL\n");
  else
    fprintf(stdout, " %d(%ld)\n", int_data, length[0]);

  /* column 2 */
  fprintf(stdout, "   column2 (string)   : ");
  if (is_null[1])
    fprintf(stdout, " NULL\n");
  else
    fprintf(stdout, " %s(%ld)\n", str_data, length[1]);

  /* column 3 */
  fprintf(stdout, "   column3 (smallint) : ");
  if (is_null[2])
    fprintf(stdout, " NULL\n");
  else
    fprintf(stdout, " %d(%ld)\n", small_data, length[2]);

  /* column 4 */
  fprintf(stdout, "   column4 (timestamp): ");
  if (is_null[3])
    fprintf(stdout, " NULL\n");
  else
    fprintf(stdout, " %04d-%02d-%02d %02d:%02d:%02d (%ld)\n",
                                               ts.year, ts.month, ts.day,
                                               ts.hour, ts.minute, ts.second,
                                               length[3]);
  fprintf(stdout, "\n");
}

/* Validate rows fetched */
fprintf(stdout, " total rows fetched: %d\n", row_count);
if (row_count != 2)
{
  fprintf(stderr, " MySQL failed to return all rows\n");
  exit(0);
} 

/* Free the prepared result metadata */
mysql_free_result(prepare_meta_result);


/* Close the statement */
if (mysql_stmt_close(stmt))
{
  fprintf(stderr, " failed while closing the statement\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}

11.1.7.14. mysql_send_long_data()

my_bool mysql_send_long_data(MYSQL_STMT *stmt, unsigned int parameter_number, const char *data, unsigned long length)

説明

アプリケーションはこの関数を使用して、パラメータデータを個別に(または ``切り分けて'')サーバに送信できます。この関数を複数回呼び出すことによって、TEXT または BLOB のどちらかのデータ型のカラムの文字データ値またはバイナリデータ値を複数回に分けて送信することができます。

parameter_number は、データを関連付けるパラメータを示す番号です。パラメータの番号は 0 から始まります。data は送信データを含むバッファへのポインタを、length はバッファ内のデータのバイト数を示します。

戻り値

データをサーバに正常に送信できた場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_INVALID_PARAMETER_NO

    無効なパラメータ番号が指定された。

  • CR_COMMANDS_OUT_OF_SYNC

    コマンドが正しい順序で実行されなかった。

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_OUT_OF_MEMORY

    メモリが不足していた。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

以下の例では、TEXT 型カラムのデータを切り分けて送信する方法を示します。ここでは、データ値 'MySQL - The most popular open source database'text_column カラムに挿入します。mysql 変数は有効な接続ハンドルとします。

#define INSERT_QUERY "INSERT INTO test_long_data(text_column) VALUES(?)"
  
MYSQL_BIND bind[1];
long       length;

if (!mysql_prepare(mysql, INSERT_QUERY, strlen(INSERT_QUERY))
{
  fprintf(stderr, "\n prepare failed");
  fprintf(stderr, "\n %s", mysql_error(mysql));
  exit(0);
}
 memset(bind, 0, sizeof(bind));
 bind[0].buffer_type= MYSQL_TYPE_STRING;
 bind[0].length= &length;
 bind[0].is_null= 0;

/* Bind the buffers */
if (mysql_bind_param(stmt, bind))
{
  fprintf(stderr, "\n param bind failed");
  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
  exit(0);
}

 /* Supply data in chunks to server */
 if (!mysql_send_long_data(stmt,0,"MySQL",5))
{
  fprintf(stderr, "\n send_long_data failed");
  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
  exit(0);
}

 /* Supply the next piece of data */
 if (mysql_send_long_data(stmt,0," - The most popular open source database",40))
{
  fprintf(stderr, "\n send_long_data failed");
  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
  exit(0);
}

 /* Now, execute the query */
 if (mysql_execute(stmt))
{
  fprintf(stderr, "\n mysql_execute failed");
  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
  exit(0);
}

11.1.7.15. mysql_stmt_close()

my_bool mysql_stmt_close(MYSQL_STMT *)

説明

プリペアドステートメントをクローズします。mysql_stmt_close() では、stmt が示すステートメントハンドルに割り当てられたメモリも解放されます。

現在のステートメントの結果セットの処理が途中か、または取得されていないレコードが残っている場合、この関数を呼び出すと、その状態をキャンセルして、次のクエリを実行できるようにします。

戻り値

ステートメントが正常に解放された場合は 0。エラーが発生した場合は 0 以外。

エラー

  • CR_SERVER_GONE_ERROR

    MySQL サーバがいなくなった。

  • CR_UNKNOWN_ERROR

    不明なエラーが発生した。

mysql_stmt_close() の使用方法については、項11.1.7.5. 「mysql_execute() の「例」を参照してください。

11.1.7.16. mysql_stmt_errno()

unsigned int mysql_stmt_errno(MYSQL_STMT *stmt)

説明

mysql_stmt_errno() は、stmt で指定されるステートメントについて、最後に呼び出された、成功または失敗する可能性のあるステートメント API 関数のエラーコードを返します。戻り値が 0 の場合、エラーは発生していません。クライアントのエラーメッセージ番号の一覧は、MySQL errmsg.h ヘッダファイルに記述されています。サーバのエラーメッセージ番号の一覧は、mysqld_error.h に記述されています。MySQL ソースディストリビューションに含まれるファイル Docs/mysqld_error.txt には、すべてのエラーメッセージおよびエラー番号の一覧が記述されています。サーバのエラーコードの一覧は、項12.1. 「返されるエラー」 にも記載されています。

戻り値

エラーコードの値。エラーが発生していない場合は 0。

エラー

ありません。

11.1.7.17. mysql_stmt_error()

const char *mysql_stmt_error(MYSQL_STMT *stmt)

説明

mysql_stmt_error() は、stmt で指定されるステートメントについて、最後に呼び出された、成功または失敗する可能性のあるステートメント API 関数のエラーメッセージを含むヌル終端文字列を返します。エラーが発生していない場合は空文字列("")を返します。これは、次の 2 つの比較は等価であることを意味します。

if (mysql_stmt_errno(stmt))
{
  // an error occurred
}

if (mysql_stmt_error(stmt)[0])
{
  // an error occurred
}

クライアントのエラーメッセージの言語は、MySQL クライアントライブラリを再コンパイルすることによって変更できます。現在は、複数の異なる言語でエラーメッセージを返すことができます。

戻り値

エラーの内容を説明する文字列。エラーが発生していない場合は空文字列。

エラー

ありません。

11.1.7.18. mysql_stmt_sqlstate()

const char *mysql_stmt_sqlstate(MYSQL_STMT *stmt)

説明

mysql_stmt_sqlstate() は、stmt で指定されるステートメントについて、最後に呼び出された、成功または失敗する可能性のあるプリペアドステートメント API 関数の SQLSTATE エラーコードを含むヌル終端文字列を返します。エラーコードは 5 文字で示されます。"00000" は、``エラーがない'' ことを意味します。値は ANSI SQL および ODBC によって規定されています。考えられる値の一覧については、項12.1. 「返されるエラー」 を参照してください。

注意: すべての MySQL エラーが SQLSTATE にマッピングされているわけではありません。マッピングされていないエラーの場合は "HY000"(一般エラー)が使用されます。

この関数は MySQL 4.1.1 で追加されました。

戻り値

SQLSTATE エラーコードを含むヌル終端文字列。

11.1.8. C API における複数クエリの実行の取り扱い

MySQL は、バージョン 4.1 から 1 つのクエリ文字列で指定された複数ステートメントの実行をサポートします。接続でこの機能を使用するには、接続をオープンするときに mysql_real_connect() のフラグパラメータで CLIENT_MULTI_STATEMENTS オプションを指定する必要があります。このオプションは、mysql_set_server_option(MYSQL_OPTION_MULTI_STATEMENTS_ON) を呼び出すことで、接続に対して設定することもできます。

デフォルトでは、mysql_query() および mysql_real_query() は最初のクエリのステータスだけを返します。その後のクエリのステータスは mysql_more_results() および mysql_next_result() を使用して処理できます。

/* Connect to server with option CLIENT_MULTI_STATEMENTS */
mysql_real_connect(..., CLIENT_MULTI_STATEMENTS);

/* Now execute multiple queries */
mysql_query(mysql,"DROP TABLE IF EXISTS test_table;\
                   CREATE TABLE test_table(id INT);\
                   INSERT INTO test_table VALUES(10);\
                   UPDATE test_table SET id=20 WHERE id=10;\
                   SELECT * FROM test_table;\
                   DROP TABLE test_table";
do
{
  /* Process all results */
  ...
  printf("total affected rows: %lld", mysql_affected_rows(mysql));
  ...
  if (!(result= mysql_store_result(mysql)))
  {
     printf(stderr, "Got fatal error processing query\n");
     exit(1);
  }
  process_result_set(result);	/* client function */
  mysql_free_result(result);
} while (!mysql_next_result(mysql));

11.1.9. C API における日付値および時刻値の取り扱い

MySQL 4.1 で導入された新しいバイナリプロトコルを使用すると、MYSQL_TIME 構造体を使用して日付および時刻に関する値(DATETIMEDATETIME、および TIMESTAMP)を送受信できます。この構造体のメンバについては、項11.1.5. 「C API のプリペアドステートメントのデータ型」 を参照してください。

時間的なデータを送信するには、mysql_prepare() を使用してプリペアドステートメントを作成します。次に mysql_execute() を呼び出してステートメントを実行する前に、以下の手順を実行して時間的なパラメータを設定します。

  1. データ値に関連付けられた MYSQL_BIND 構造体のメンバ buffer_type に、送信する時間的な値の型を示す値を設定する。DATETIMEDATETIME、または TIMESTAMP の値の場合、buffer_typeMYSQL_TYPE_DATEMYSQL_TYPE_TIMEMYSQL_TYPE_DATETIME、または MYSQL_TYPE_TIMESTAMP をそれぞれ設定する。

  2. MYSQL_BIND 構造体のメンバ buffer に、時間的な値が格納されている MYSQL_TIME 構造体のアドレスを設定する。

  3. 時間的な値の型に合わせて MYSQL_TIME 構造体の必要なメンバの値を設定する。

mysql_bind_param() を使用してパラメータデータをステートメントにバインドします。これで mysql_execute() を呼び出す準備が完了します。

時間的な値を取得する手順はほとんど同じですが、buffer_type メンバには取得しようとする値の型を設定する点、および buffer メンバには返される値を格納する MYSQL_TIME 構造体のアドレスを設定する点が異なります。mysql_execute() を呼び出した後、結果を取得するまでの間に、mysql_bind_results() を呼び出して、バッファをステートメントにバインドします。

以下の例では、DATETIME、および TIMESTAMP の型のデータを挿入する方法を示します。mysql 変数は有効な接続ハンドルとします。

MYSQL_TIME  ts;
MYSQL_BIND  bind[3];
MYSQL_STMT  *stmt;
  
  strmov(query, "INSERT INTO test_table(date_field, time_field,
                                        timestamp_field) VALUES(?,?,?");

  stmt= mysql_prepare(mysql, query, strlen(query))); 

  /* setup input buffers for all 3 parameters */
  bind[0].buffer_type= MYSQL_TYPE_DATE;
  bind[0].buffer= (char *)&ts;  
  bind[0].is_null= 0;
  bind[0].length= 0;
  ..
  bind[1]= bind[2]= bind[0];
  ..

  mysql_bind_param(stmt, bind);

  /* supply the data to be sent is the ts structure */
  ts.year= 2002;
  ts.month= 02;
  ts.day= 03;

  ts.hour= 10;
  ts.minute= 45;
  ts.second= 20;

  mysql_execute(stmt);
  .. 

11.1.10. C API スレッド関数の説明

スレッドクライアントを作成するには、以下の関数を使用する必要があります。 See 項11.1.14. 「スレッドクライアントの作成方法」

11.1.10.1. my_init()

void my_init(void)

説明

この関数は、他の MySQL 関数を呼び出す前に、プログラム内で 1 回だけ呼び出す必要があります。MySQL が必要とするいくつかのグローバル変数を初期化します。スレッドセーフなクライアントライブラリを使用している場合、この関数は現在のスレッドに対して mysql_thread_init() の呼び出しも行います。

mysql_init()mysql_server_init()、および mysql_connect() は、自動的にこの関数を呼び出します。

戻り値

ありません。

11.1.10.2. mysql_thread_init()

my_bool mysql_thread_init(void)

説明

スレッドを作成したら、スレッド固有の変数を初期化するためにこの関数を呼び出す必要があります。

my_init() および mysql_connect() は、自動的にこの関数を呼び出します。

戻り値

正常に動作した場合は 0。エラーが発生した場合は 0 以外。

11.1.10.3. mysql_thread_end()

void mysql_thread_end(void)

説明

mysql_thread_init() を呼び出す前にこの関数を呼び出して、pthread_exit() によって割り当てられたメモリを解放する必要があります。

注意: この関数は、クライアントライブラリからは自動的に呼び出されません。メモリリークを避けるために、明示的に呼び出す必要があります。

戻り値

ありません。

11.1.10.4. mysql_thread_safe()

unsigned int mysql_thread_safe(void)

説明

この関数は、クライアントがスレッドセーフとしてコンパイルされたかどうかを示します。

戻り値

クライアントがスレッドセーフの場合は 1、それ以外の場合は 0。

11.1.11. C API 組み込みサーバ関数の説明

アプリケーションを組み込み MySQL サーバライブラリとリンクする場合、以下で説明する関数を使用する必要があります。 See 項11.1.15. 「組み込み MySQL サーバライブラリ libmysqld」

プログラムを、-lmysqld ではなく、-lmysqlclient を指定してリンクした場合、これらの関数は何も実行しません。そのため、コードを変更しなくても、組み込み MySQL サーバおよびスタンドアロンサーバのどちらを使用するかを選択できます。

11.1.11.1. mysql_server_init()

int mysql_server_init(int argc, char **argv, char **groups)

説明

この関数は、組み込みサーバを使用するプログラムで、他の MySQL 関数を呼び出す前に、1 回だけ呼び出す必要があります。まず組み込みサーバを起動し、このサーバが使用するサブシステム(mysysInnoDB など)をすべて初期化します。この関数を呼び出さなかった場合、プログラムはクラッシュします。MySQL に付属の DBUG パッケージを使用している場合は、MY_INIT() を呼び出した後にこの関数を呼び出す必要があります。

引数の argc および argv は、main() の引数と似ています。argv の最初の要素は、通常はプログラム名であり、無視されます。使いやすくするために、サーバに対してコマンドライン引数がない場合、argc0(ゼロ)になります。mysql_server_init() は引数のコピーを作成するので、それを呼び出した後は argv または groups を壊しても問題ありません。

groupsNULL で終端された文字列のリストは、オプション設定ファイルのどのグループをアクティブにするかを選択します。See 項4.1.2. 「my.cnf オプション設定ファイル」。 使いやすくするために、groupsNULL の場合は、[server] および [embedded] グループが読み込まれます。

#include <mysql.h>
#include <stdlib.h>

static char *server_args[] = {
  "this_program",       /* this string is not used */
  "--datadir=.",
  "--key_buffer_size=32M"
};
static char *server_groups[] = {
  "embedded",
  "server",
  "this_program_SERVER",
  (char *)NULL
};

int main(void) {
  mysql_server_init(sizeof(server_args) / sizeof(char *),
                    server_args, server_groups);

  /* Use any MySQL API functions here */

  mysql_server_end();

  return EXIT_SUCCESS;
}

戻り値

正常に終了した場合は 0。エラーが発生した場合は 1。

11.1.11.2. mysql_server_end()

void mysql_server_end(void)

説明

この関数は、他の MySQL 関数をすべて呼び出した後に 1 回呼び出す必要があります。組み込みサーバをシャットダウンします。

戻り値

ありません。

11.1.12. C API の使用に関する一般的な質問および問題

11.1.12.1. mysql_query() が正常に終了した後で mysql_store_result()NULL を返す場合があるのはなぜか

mysql_query() の呼び出しが正常に終了した後で mysql_store_result()NULL を返す可能性はあります。このような状況が発生した場合、以下のいずれかの条件が成立したことを意味します。

  • malloc() が異常終了した(結果セットが大きすぎた場合など)

  • データを読み込めなかった(接続にエラーが発生した)

  • データを返さないクエリだった(INSERTUPDATE、または DELETE だった場合など)

mysql_field_count() を呼び出すことによって、ステートメントが空でない結果セットを生成したかどうかをいつでも調べることができます。mysql_field_count() が 0 を返す場合、結果セットは空であり、最後に実行したクエリは結果を返していません(INSERT または DELETE など)。mysql_field_count() が 0 以外の値を返す場合、ステートメントは空ではない結果セットを返しています。例については、mysql_field_count() 関数の説明を参照してください。

mysql_error() または mysql_errno() を呼び出すことによって、エラーが発生したかどうかを判定できます。

11.1.12.2. クエリから取得できる結果にはどのようなものがあるか

クエリは、結果セットを返す以外に、以下の情報を提供します。

  • mysql_affected_rows() は、INSERTUPDATE、または DELETE を実行する場合、最後に実行したクエリで挿入、更新、または削除されたレコードの数を返す。例外は、WHERE 節を使わずに DELETE を実行した場合で、このときは時間を大幅に短縮するためにテーブルを空の状態で再作成する。この場合、mysql_affected_rows() は削除されたレコードの数として 0 を返す。

  • mysql_num_rows() は結果セットのレコード数を返す。mysql_store_result() を使用する場合、mysql_store_result() が復帰した直後に mysql_num_rows() を呼び出すことができる。mysql_use_result() を使用する場合、mysql_fetch_row() を使用してすべてのレコードを取得した後でのみ mysql_num_rows() を呼び出すことができる。

  • mysql_insert_id() は、AUTO_INCREMENT インデックスを使用してテーブルにレコードを挿入した最後のクエリが生成した ID を返す。 See 項11.1.3.32. 「mysql_insert_id()

  • 一部のクエリ(LOAD DATA INFILE ...INSERT INTO ... SELECT ...UPDATE)は、上記以外にも補足情報を提供する。この補足情報は mysql_info() を呼び出すことによって取得する。この関数が返す文字列のフォーマットについては、mysql_info() の説明を参照すること。mysql_info() は、取得する補足情報がない場合は、NULL ポインタを返す。

11.1.12.3. 最後に挿入したレコードの一意な ID はどのように取得するのか

AUTO_INCREMENT 属性を持つカラムが定義されているテーブルにレコードを挿入する場合、mysql_insert_id() を呼び出すことによって、最後に生成された ID を取得できます。

また、mysql_query() に渡すクエリ文字列で LAST_INSERT_ID() 関数を使用することによって、最後に生成された ID を取得することもできます。

以下のコードを実行すると、AUTO_INCREMENT インデックスが使用されたかどうかを調べることができます。このコードは同時に、クエリが AUTO_INCREMENT インデックスを使用する INSERT だったかどうかも調べます。

if (mysql_error(&mysql)[0] == 0 &&
    mysql_num_fields(result) == 0 &&
    mysql_insert_id(&mysql) != 0)
{
    used_id = mysql_insert_id(&mysql);
}

最後に生成された ID は、接続ごとにサーバに保持されます。他の接続を使用するクライアントによって変更されることはありません。AUTO_INCREMENT 属性を持つ他のカラムを非マジック値(NULL でも 0 でもない値)で更新した場合も、この ID は変更されません。

あるテーブル用に生成された ID を別のテーブルに挿入するには、以下の SQL ステートメントを記述します。

INSERT INTO foo (auto,text)
    VALUES(NULL,'text');              # generate ID by inserting NULL
INSERT INTO foo2 (id,text)
    VALUES(LAST_INSERT_ID(),'text');  # use ID in second table

11.1.12.4. C API とリンクする場合の問題

C API とリンクする場合、一部のシステムでは以下のエラーが発生する可能性があります。

gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl

Undefined        first referenced
 symbol          in file
floor            /usr/local/lib/mysql/libmysqlclient.a(password.o)
ld: fatal: Symbol referencing errors. No output written to client

システムでこのエラーが発生した場合、コンパイル/リンク行の最後に -lm を追加して、数学ライブラリをリンクする必要があります。

11.1.13. クライアントプログラムのビルド

自分で作成した MySQL クライアントまたはサードパーティから入手した MySQL クライアントをコンパイルする場合、リンクコマンドで -lmysqlclient -lz オプションを使用してリンクする必要があります。また、場合によっては、ライブラリの所在をリンカに通知するために -L オプションを指定する必要があります。たとえば、ライブラリが /usr/local/mysql/lib にインストールされている場合、リンクコマンドで -L/usr/local/mysql/lib -lmysqlclient -lz を記述します。

MySQL ヘッダファイルを使用するクライアントをコンパイルするとき、場合によっては -I オプションを指定して(たとえば -I/usr/local/mysql/include)、ヘッダファイルの所在をコンパイラに通知する必要があります。

上記の処理を Unix で簡単に実行するために mysql_config スクリプトが用意されています。 See 項4.9.11. 「mysql_config(クライアントをコンパイルするためのコンパイルオプションの取得)」

このスクリプトを使用して以下のように指定することで、MySQL クライアントをコンパイルできます。

CFG=/usr/local/mysql/bin/mysql_config
sh -c "gcc -o progname `$CFG --cflags` progname.c `$CFG --libs`"

sh -c は、mysql_config からの出力をシェルが 1 語として処理しないようにするために必要です。

11.1.14. スレッドクライアントの作成方法

クライアントライブラリはほぼスレッドセーフです。最大の問題は、net.c で記述されているソケットからデータを読み込むためのサブルーチンが、割り込みが発生したときにスレッドセーフではないことです。これは、サーバに対する読み込みに長時間かかる場合、それを中断できるアラームをユーザが独自に作成する可能性があるという考えに基づく仕様です。割り込み SIGPIPE に対する割り込みハンドラをインストールする場合は、ソケットの処理をスレッドセーフにする必要があります。

バージョン 4.0.16 の新機能: 接続が切断されたときにプログラムが強制終了しないようにするために、MySQL は最初に mysql_server_init()、mysql_init()、または mysql_connect() を呼び出すときに SIGPIPE をブロックします。独自に SIGPIPE に対する割り込みハンドラを作成する場合、まず mysql_server_init() を呼び出してから、そのハンドラをインストールする必要があります。MySQL の古いバージョンでは、スレッドセーフなクライアントライブラリでのみ、mysql_init() を呼び出すたびに、SIGPIPE がブロックされていました。

当社の Web サイト(http://www.mysql.com/)で配布した古いバイナリファイルの場合、クライアントライブラリのコンパイルではスレッドセーフなオプションを使用しないのが普通でした(Windows のバイナリはデフォルトでスレッドセーフでコンパイルされます)。新しく配布するバイナリでは、スレッドセーフなクライアントライブラリとそうでないクライアントライブラリの両方が必要です。

別のスレッドから割り込んだり、MySQL サーバとの通信にタイムアウトを設定できるようなスレッドクライアントを作成するには、-lmysys-lmystrings、および -ldbug の各ライブラリ、およびサーバが使用する net_serv.o コードを使用する必要があります。

割り込みやタイムアウトを使用しない場合は、スレッドセーフなクライアントライブラリ (mysqlclient_r) をコンパイルして使用するだけで済みます。See 項11.1. 「MySQL C API」。 この場合、net_serv.o オブジェクトファイルや他の MySQL ライブラリを使用する必要はありません。

スレッドクライアントを使用しながら、タイムアウトや割り込みも使用する場合、thr_alarm.c ファイルで定義されているルーチンを活用できます。mysys ライブラリのルーチンを使用している場合、まず my_init() を呼び出す必要があります。 See 項11.1.10. 「C API スレッド関数の説明」

mysql_real_connect() 以外のすべての関数は、デフォルトでスレッドセーフです。以下に、スレッドセーフなクライアントライブラリをコンパイルし、スレッドセーフに使用する方法を示します(mysql_real_connect() を使用した以下の記述は mysql_connect() にも同様に適用できますが、mysql_connect() は廃止されたので、いずれにしろ mysql_real_connect() を使用する必要があります)。

mysql_real_connect() をスレッドセーフにするには、以下のコマンドを使用してクライアントライブラリを再コンパイルする必要があります。

shell> ./configure --enable-thread-safe-client

このコマンドによって、スレッドセーフなクライアントライブラリ libmysqlclient_r が作成されます(使用する OS にスレッドセーフな gethostbyname_r() 関数が提供されていると仮定)。このライブラリは接続ごとにスレッドセーフになります。以下の項目に注意すれば、2 つのスレッドで同じ接続を共有できます。

  • 2 つのスレッドが同じ接続で同時に MySQL サーバにクエリを送信することはできない。特に、mysql_query() を呼び出してから mysql_store_result() を呼び出すまでの間は、他のスレッドが同じ接続を決して使用しないようにする必要がある。

  • 複数のスレッドが mysql_store_result() で取得した複数の結果セットにアクセスすることができる。

  • mysql_use_result を使用する場合、結果セットをクローズするまで、同じ接続を他のスレッドが使用しないようにする必要がある。ただし、最も望ましいのは、同じ接続を共有するスレッドクライアントが mysql_store_result() を使用することである。

  • 同じ接続で複数のスレッドを使用する場合、mysql_query() を呼び出す前から mysql_store_result() を呼び出した後までの部分を mutex ロックで囲む必要がある。mysql_store_result() が復帰した後はロックを解放することができ、同じ接続で他のスレッドがクエリを実行できるようになる。

  • POSIX スレッドを使用してプログラムする場合、pthread_mutex_lock() および pthread_mutex_unlock() を使用して、mutex ロックを設定および解放できる。

MySQL データベースに接続しない MySQL 関数を呼び出すスレッドを使用する場合、以下の事項を認識しておく必要があります。

mysql_init() または mysql_connect() を呼び出すと、MySQL はスレッドごとにスレッド固有の変数を作成します。この変数は特にデバッグライブラリで使用されます。

スレッドが mysql_init() または mysql_connect() を呼び出す前に MySQL 関数を呼び出すと、スレッドは必要なスレッド固有の変数を設定せず、そのうちコアダンプが発生します。

処理を円滑に進めるには、以下に示す項目を実行する必要があります。

  1. mysql_real_connect() を呼び出す前に他の MySQL 関数を呼び出す場合、プログラムの先頭で my_init() を呼び出す。

  2. MySQL 関数を呼び出す前にスレッドハンドラで mysql_thread_init() を呼び出す。

  3. スレッドでは、pthread_exit() を呼び出す前に mysql_thread_end() を呼び出す。これにより MySQL が作成したスレッド固有の変数が使用していたメモリが解放される。

クライアントを libmysqlclient_r とリンクするときに、未定義シンボルがあるというエラーが発生する可能性があります。ほとんどの場合、これはリンク/コンパイル行にスレッドライブラリを追加しなかったことが原因です。

11.1.15. 組み込み MySQL サーバライブラリ libmysqld

11.1.15.1. 組み込み MySQL サーバライブラリの概要

組み込み MySQL サーバライブラリを使用することで、クライアントアプリケーション内部で完全な機能を備えた MySQL サーバを実行できます。最大の長所は、処理速度が高速になることと、組み込みアプリケーションの管理性が向上することです。

組み込み MySQL サーバライブラリは、C/C++ で記述された MySQL のクライアント/サーババージョンをベースとしています。そのため、組み込みサーバも C/C++ で記述されています。他の言語での組み込みサーバは提供されていません。

組み込みサーババージョンとクライアント/サーババージョンはどちらも同じ API が用意されています。既存のスレッドアプリケーションも、通常は以下の関数への呼び出しを追加するだけで、組み込みサーバライブラリを使用するように変更できます。

関数呼び出すタイミング
mysql_server_init()他の MySQL 関数が呼び出される前に呼び出す必要がある。main() 関数のできるだけ先頭に近い場所が望ましい。
mysql_server_end()プログラムが終了する前に呼び出す必要がある。
mysql_thread_init()MySQL にアクセスするスレッドごとに呼び出す必要がある。
mysql_thread_end()pthread_exit() を呼び出す前に呼び出す必要がある。

次に、libmysqlclient.a ではなく、libmysqld.a を作成したコードにリンクする必要があります。

上記の mysql_server_xxx 関数は libmysqlclient.a にも含まれており、作成したアプリケーションを適切なライブラリとリンクするだけで、組み込みサーババージョンおよびクライアント/サーババージョンのどちらを使用するかを切り替えることができるようになっています。 See 項11.1.11.1. 「mysql_server_init()

11.1.15.2. libmysqld を使用したプログラムのコンパイル

libmysqld ライブラリを取得するには、--with-embedded-server オプションを使用して MySQL を設定する必要があります。

プログラムを libmysqld とリンクするときは、システム固有の pthread ライブラリおよび MySQL サーバが使用するライブラリもリンクする必要があります。mysql_config --libmysqld-libs を実行すると、ライブラリの詳細なリストを取得できます。

スレッドプログラムをコンパイルおよびリンクするときは、適切なフラグを指定する必要があります。これは、自作コードから直接スレッド関数を呼び出していない場合でも必要です。

11.1.15.3. 組み込み MySQL サーバを使用する際の制約

組み込み MySQL サーバには以下の制約があります。

  • ISAM テーブルはサポートしない(ライブラリのサイズを小さくするための方針)。

  • ユーザ定義関数(UDF)は使用できない。

  • コアダンプでスタックトレースはできない。

  • 内部 RAID をサポートしない(現在ほとんどの OS でサイズの大きいファイルをサポートしているので通常は必要ない)。

  • サーバまたはマスタとして設定できない(レプリケーションできない)。

  • 外部プロセスからソケットまたは TCP/IP を使用して組み込み MySQL サーバに接続することはできない。

上記の制約の中には、mysql_embed.h インクルードファイルを編集して MySQL を再コンパイルすることで変更できるものもあります。

11.1.15.4. 組み込み MySQL サーバでのオプション設定ファイルの使用

オプション設定ファイルを使用して、クライアント/サーバアプリケーションと組み込み MySQL サーバを使用したアプリケーションを簡単に切り替える推奨方法を以下に示します。 See 項4.1.2. 「my.cnf オプション設定ファイル」

  • 共通するオプションを [server] セクションに記述する。このオプションは両方のバージョンの MySQL に読み込まれる。

  • クライアント/サーバ固有のオプションを [mysqld] セクションに記述する。

  • 組み込み MySQL サーバ固有のオプションを [embedded] セクションに記述する。

  • アプリケーション固有のオプションを [ApplicationName_SERVER] セクションに記述する。

11.1.15.5. 組み込み MySQL サーバの今後の開発課題

  • ライブラリを小さくするために MySQL の機能の一部を組み込まないオプションを提供する。

  • 実行速度を向上させる。

  • エラーの出力先を stderr にする。その場合にファイル名を指定するオプションを追加する。

  • InnoDB を組み込み MySQL サーババージョンで使用する際の冗長度を削減する。

11.1.15.6. 組み込み MySQL サーバを使用した簡単な例

以下に示すプログラムおよび makefile は、Linux や FreeBSD システムでも何も変更することなく動作するはずです。他のオペレーティングシステムで使用する場合は、一部変更が必要です。この例は、実際のアプリケーションを作成する場合には避けられない混乱を回避して、問題点を理解できるだけの詳細な実例を示すことを目的としています。

この例を実際に動作させるには、mysql-4.0 ソースディレクトリと同じレベルに test_libmysqld ディレクトリを作成します。そのディレクトリに test_libmysqld.c ソースファイルと GNUmakefile を保存し、test_libmysqld ディレクトリ内から GNU make を実行します。

test_libmysqld.c

/*
 * A simple example client, using the embedded MySQL server library
 */

#include <mysql.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

MYSQL *db_connect(const char *dbname);
void db_disconnect(MYSQL *db);
void db_do_query(MYSQL *db, const char *query);

const char *server_groups[] = {
  "test_libmysqld_SERVER", "embedded", "server", NULL
};

int
main(int argc, char **argv)
{
  MYSQL *one, *two;

  /* mysql_server_init() must be called before any other mysql
   * functions.
   *
   * You can use mysql_server_init(0, NULL, NULL), and it will
   * initialize the server using groups = {
   *   "server", "embedded", NULL
   *  }.
   *
   * In your $HOME/.my.cnf file, you probably want to put:

[test_libmysqld_SERVER]
language = /path/to/source/of/mysql/sql/share/english

   * You could, of course, modify argc and argv before passing
   * them to this function.  Or you could create new ones in any
   * way you like.  But all of the arguments in argv (except for
   * argv[0], which is the program name) should be valid options
   * for the MySQL server.
   *
   * If you link this client against the normal mysqlclient
   * library, this function is just a stub that does nothing.
   */
  mysql_server_init(argc, argv, (char **)server_groups);

  one = db_connect("test");
  two = db_connect(NULL);

  db_do_query(one, "SHOW TABLE STATUS");
  db_do_query(two, "SHOW DATABASES");

  mysql_close(two);
  mysql_close(one);

  /* This must be called after all other mysql functions */
  mysql_server_end();

  exit(EXIT_SUCCESS);
}

static void
die(MYSQL *db, char *fmt, ...)
{
  va_list ap;
  va_start(ap, fmt);
  vfprintf(stderr, fmt, ap);
  va_end(ap);
  (void)putc('\n', stderr);
  if (db)
    db_disconnect(db);
  exit(EXIT_FAILURE);
}

MYSQL *
db_connect(const char *dbname)
{
  MYSQL *db = mysql_init(NULL);
  if (!db)
    die(db, "mysql_init failed: no memory");
  /*
   * Notice that the client and server use separate group names.
   * This is critical, because the server will not accept the
   * client's options, and vice versa.
   */
  mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "test_libmysqld_CLIENT");
  if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0))
    die(db, "mysql_real_connect failed: %s", mysql_error(db));

  return db;
}

void
db_disconnect(MYSQL *db)
{
  mysql_close(db);
}

void
db_do_query(MYSQL *db, const char *query)
{
  if (mysql_query(db, query) != 0)
    goto err;

  if (mysql_field_count(db) > 0)
  {
    MYSQL_RES   *res;
    MYSQL_ROW    row, end_row;
    int num_fields;

    if (!(res = mysql_store_result(db)))
      goto err;
    num_fields = mysql_num_fields(res);
    while ((row = mysql_fetch_row(res)))
    {
      (void)fputs(">> ", stdout);
      for (end_row = row + num_fields; row < end_row; ++row)
        (void)printf("%s\t", row ? (char*)*row : "NULL");
      (void)fputc('\n', stdout);
    }
    (void)fputc('\n', stdout);
    mysql_free_result(res);
  }
  else
    (void)printf("Affected rows: %lld\n", mysql_affected_rows(db));

  return;

err:
  die(db, "db_do_query failed: %s [%s]", mysql_error(db), query);
}

GNUmakefile

# This assumes the MySQL software is installed in /usr/local/mysql
inc      := /usr/local/mysql/include/mysql
lib      := /usr/local/mysql/lib

# If you have not installed the MySQL software yet, try this instead
#inc      := $(HOME)/mysql-4.0/include
#lib      := $(HOME)/mysql-4.0/libmysqld

CC       := gcc
CPPFLAGS := -I$(inc) -D_THREAD_SAFE -D_REENTRANT
CFLAGS   := -g -W -Wall
LDFLAGS  := -static
# You can change -lmysqld to -lmysqlclient to use the
# client/server library
LDLIBS    = -L$(lib) -lmysqld -lz -lm -lcrypt

ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))
# FreeBSD
LDFLAGS += -pthread
else
# Assume Linux
LDLIBS += -lpthread
endif

# This works for simple one-file test programs
sources := $(wildcard *.c)
objects := $(patsubst %c,%o,$(sources))
targets := $(basename $(sources))

all: $(targets)

clean:
        rm -f $(targets) $(objects) *.core

11.1.15.7. 組み込み MySQL サーバのライセンス

MySQL のソースコードは GNU GPL ライセンス(see 付録?H. GNU General Public License)の対象です。その結果、libmysqld をリンクすることによって MySQL ソースコードをインクルードするプログラムは、(GPL と互換性のあるライセンスの下で)フリーソフトウェアとしてリリースする必要があります。

フリーソフトウェアを作成したら、GPL またはそれと互換性のあるライセンスの下でコードをリリースすることによってフリーソフトウェアを宣伝するようにしてください。それができない場合は、MySQL AB から MySQL コードの商業的ライセンスを購入するという選択肢があります。詳細については、項1.4.3. 「MySQL ライセンス」 を参照してください。

11.2. MySQL の ODBC サポート

MySQL は、MyODBC プログラムという形で ODBC をサポートします。この章では、MyODBC のインストール方法およびその使用方法について説明します。また、MyODBC と連携して動作することが知られている共通プログラムのリストも提供します。

11.2.1. MyODBC のインストール方法

MyODBC 2.50 は、ODBC 対応アプリケーションが MySQL に接続するための 32 ビット ODBC 2.50 仕様レベル 0(レベル 1 およびレベル 2 の機能を含む)のドライバです。MyODBC は、Windows 9x/Me/NT/2000/XP およびほとんどの Unix プラットフォームで動作します。MyODBC 3.51 は、ODBC 3.5x 仕様レベル 1(完全なコア API およびレベル 2 の機能を含む)の拡張バージョンです。

MyODBCOpen Source であり、http://www.mysql.com/downloads/api-myodbc.html で最新バージョンが公開されています。注意: 2.50.x バージョンには LGPL ライセンスが適用され、3.51.x バージョンには GPL ライセンスが適用されます。

MyODBC を使用して問題が発生する場合、それが OLEDB と連携して動作するプログラムであれば、OLEDB ドライバを試す必要があります。

通常は、Windows マシンに MyODBC をインストールする必要があるだけです。Unix で MyODBC が必要になるのは、ColdFusion のように、Unix マシン上で動作しながら ODBC を使用してデータベースに接続するプログラムを実行する場合だけです。

Unix マシンに MyODBC をインストールする場合は、ODBC マネージャも必要です。MyODBC は、ほとんどの Unix ODBC マネージャで動作することが知られています。

Windows マシンに MyODBC をインストールするには、適切な MyODBC .zip ファイルをダウンロードし、WinZip などのプログラムで解凍して、SETUP.EXE ファイルを実行します。

Windows/NT/XP マシンでは、MyODBC をインストールする際に以下のエラーが発生する可能性があります。

An error occurred while copying C:\WINDOWS\SYSTEM\MFC30.DLL. Restart
Windows and try installing again (before running any applications which
use ODBC)

この場合の問題は、他の何らかのプログラムが ODBC を使用中であり、Windows の設計方針として、Microsoft の ODBC セットアッププログラムで新しい ODBC ドライバをインストールできない可能性があることです。ほとんどの場合、Ignore をクリックするだけで残りの MyODBC ファイルのコピーを続行することができ、インストールされたプログラムも正常に動作します。正常に動作しなかった場合の解決策としては、コンピュータを ``セーフモード'' でリブートし(リブート中に Windows が立ち上がる前に F8 キーを押す)、MyODBC をインストールしてから、通常モードでリブートします。

  • Unix マシンから Windows マシンに ODBC アプリケーション(MySQL を本来サポートしないアプリケーション)を使用して接続するには、まず Windows マシンに MyODBC をインストールする必要がある。

  • ユーザおよび Windows マシンには、Unix マシン上の MySQL サーバへのアクセス権が必要である。このアクセス権を与えるには、GRANT コマンドを使用する。 See 項4.4.1. 「GRANT および REVOKE の構文」

  • 以下の手順に従って、ODBC DSN エントリを作成する必要がある。

    • Windows マシンで [コントロールパネル] を開く。

    • [ODBC Data Sources 32-bit] アイコンをダブルクリックする。

    • [User DSN] タブをクリックする。

    • [Add] をクリックする。

    • [Create New Data Source] ダイアログボックスで [MySQL] を選択し、[Finish] をクリックする。

    • [MySQL Driver default configuration] ダイアログボックスが表示される。 See 項11.2.2. 「ODBC アドミニストレータのフィールドの設定方法」

  • アプリケーションを起動して、ODBC アドミニストレータで指定した DSN と ODBC ドライバを選択する。

注意: MySQL の画面には上記以外にも設定オプション(トレース、接続時にプロンプトを表示しないなど)があり、問題が発生した場合に使用することができます。

11.2.2. ODBC アドミニストレータのフィールドの設定方法

Windows 95 ではサーバ名を指定する方法が 3 つ考えられます。

  • サーバの IP アドレスを使用する。

  • 以下の情報を \windows\lmhosts ファイルに追加する。

    ip hostname
    

    たとえば、以下のように指定する。

    194.216.84.21 my_hostname
    
  • DNS を使用するように PC を設定する。

ODBC setup の入力例を示します。

Windows DSN name:   test
Description:        This is my test database
MySQL Database:     test
Server:             194.216.84.21
User:               monty
Password:           my_password
Port:

Windows DSN name フィールドの値には、Windows の ODBC 設定で一意な名前を指定します。

ODBC setup ダイアログボックスの ServerUserPassword、または Port の各フィールドは、入力必須フィールドではありません。ただし、これらのフィールドに値を入力した場合、その値は後で接続する際にデフォルトとして使用されます。その時点で、そのデフォルト値を変更することができます。

ポート番号が指定されなかった場合、デフォルトポート(3306)が使用されます。

Read options from C:\my.cnf を有効にした場合、C:\my.cnf ファイルから client グループおよび odbc グループのデータが読み込まれます。mysql_options() が使用可能なすべてのオプションを使用できます。 See 項11.1.3.40. 「mysql_options()

11.2.3. MyODBC の接続パラメータ

ODBC.INI ファイルの [Servername] セクションで以下に示す MyODBC のパラメータを指定できます。これらのパラメータは、SQLDriverConnect() を呼び出すときに渡す引数 InConnectionString でも指定できます。

パラメータデフォルト値コメント
userODBC(Windows 上)MySQL に接続する際に使用するユーザ名
serverlocalhostMySQL サーバのホスト名
database?デフォルトのデータベース
option0MyODBC の動作を指定する整数(下記参照)
port3306serverlocalhost 以外の値の場合に使用する TCP/IP ポート
stmt?MySQL に接続する際に実行するステートメント
password?serveruser の組み合わせに対するパスワード
socket?接続するソケットまたは Windows パイプ

option 引数は、クライアントが 100% ODBC 準拠ではないことを MyODBC に通知するために使用します。Windows では、通常、接続画面で複数の選択肢を切り替えることによってオプションフラグを設定しますが、option 引数で設定することもできます。以下に、MyODBC 接続画面に表示されるのと同じ順序でオプションのリストを示します。

ビット説明
1クライアントは MyODBC がカラムの実際の幅を返すことに対応していない。
2クライアントは MySQL が実際に影響を受けたレコードの数を返すことに対応していない。このフラグが設定されている場合、MySQL は影響を受けたレコードではなく、見つかったレコードを返す。MySQL が実際に影響を受けたレコードの数を返すことに対応するには、MySQL 3.21.14 以降を使用する必要がある。
4デバッグログを c:\myodbc.log に書き込む。これは、AUTOEXEC.BATMYSQL_DEBUG=d:t:O,c::\myodbc.log を追加することと同じである。
8結果およびパラメータにパケット制限を設定しない。
16ドライバが入力を要求する画面の表示を必要としても、それを表示しない。
32状況に応じて ODBC 1.0 ドライバをシミュレートする。
64'database.table.column' でデータベース名の使用を無視する。
128ODBC マネージャカーソルの使用を強制する(実験的)。
256拡張取得の使用を無効にする(実験的)。
512CHAR 型フィールドではカラム幅全体に文字をパッドする
1024SQLDescribeCol() は完全修飾カラム名を返す。
2048圧縮されたサーバ/クライアントプロトコルを使用する。
4096サーバに、関数名の後および '(' の前の空白を無視するように通知する (PowerBuilder で必要)。これによりすべての関数名をキーワードにする。
8192NT 上で動作する mysqld サーバに名前付きパイプを使用して接続する。
16384LONGLONG 型のカラムを INT 型のカラムに変更する(一部のアプリケーションでは LONGLONG 型に対応していない)。
32768SQLTables から Table_qualifier および Table_owner として 'user' を返す(実験的)。
65536my.cnfclient グループおよび odbc グループからパラメータを読み込む。
131072安全性チェックを追加する(その必要はないかもしれないが念のため)。

複数のオプションを選択する場合は上記のフラグを加算します。たとえば、オプションを 12 (4+8) に設定すると、パッケージの制約を受けずにデバッグできます。

最適なパフォーマンスを得るために、デフォルトで MYODBC.DLL がコンパイルされます。MyODBC をデバッグする場合(たとえばトレース機能を有効にする)、代わりに MYODBCD.DLL を使用する必要があります。このファイルをインストールするには、インストールされている MYODBC.DLL ファイルに MYODBCD.DLL を上書きコピーします。

11.2.4. MyODBC に関する問題を報告する方法

MyODBC は、Access、Admndemo.exe、C++-Builder、Borland Builder 4、Centura Team Developer(旧 Gupta SQL/Windows)、ColdFusion(Solaris および NT 上でサービスパック 5 を使用)、Crystal Reports、DataJunction、Delphi、ERwin、Excel、iHTML、FileMaker Pro、FoxPro、Notes 4.5/4.6、SBSS、Perl DBD-ODBC、Paradox、Powerbuilder、Powerdesigner 32 ビット、VC++、および Visual Basic との動作を試験しています。

MyODBC と連携して動作するアプリケーションを他にご存知の方は、myodbc メーリングリストにその旨を投稿してください。 See 項1.7.1.1. 「MySQL メーリングリスト」

一部のプログラムでは Another user has modifies the record that you have modified のようなエラーが発生する可能性があります。. ほとんどの場合、これは以下のいずれかを実行することで解決できます。

  • 主キーが存在しない場合、それをテーブルに追加する。

  • タイムスタンプ型のカラムが存在しない場合、それを追加する。

  • 倍精度浮動小数点型のフィールドだけを使用する。一部のプログラムでは単精度浮動小数点の比較でエラーが発生する可能性がある。

上記のどれを実行しても問題が解決しなかった場合、MyODBC トレースファイルを有効にして、問題が発生する原因を調べる必要があります。

11.2.5. MyODBC と連携して動作することが知られているプログラム

ほとんどのプログラムは MyODBC と連携して動作しますが、ここに示したプログラムについては、当社が社内で試験したか、またはユーザから動作確認したという連絡を受けています。

  • プログラム

    コメント

  • Access

    Access を動作させるには、以下の処理を実行する。

    • Access 2000 を使用している場合、http://www.microsoft.com/data/ から最新(バージョン 2.6 以降)の Microsoft MDAC(Microsoft Data Access Components)をダウンロードし、インストールする必要がある。これによって、MySQL にデータをエクスポートする際にテーブル名およびカラム名が指定されないという Access のバグが修正される。このバグは、MyODBC バージョン 2.50.33 および MySQL バージョン 3.23.x にアップグレードすることによって回避することもできる。

      その他に、http://support.microsoft.com/support/kb/articles/Q 239/1/14.ASP で公開されている Microsoft Jet 4.0 サービスパック 5 をダウンロードし、適用する必要もある。これは、Access でカラムが #deleted# とマークされる場合があるバグを修正する。

      注意: MySQL バージョン 3.22 を使用している場合、この問題を回避するには、MDAC パッチを適用し、MyODBC 2.50.32 または 2.50.34 以降を使用する必要がある。

    • Access のすべてのバージョンで、MyODBC のオプションフラグ Return matching rows を有効にする必要がある。Access 2.0 では、さらに Simulate ODBC 1.0 を有効にする必要がある。

    • 更新可能にするすべてのテーブルでタイムスタンプ型のカラムを定義する必要がある。移植性を最大にするために、TIMESTAMP(14) または単純な TIMESTAMP を、TIMESTAMP(X) の代わりに使用することが推奨される。

    • テーブルに主キーを定義する必要がある。これを定義しない場合、新しく追加したレコードまたは更新したレコードが #DELETED# として表示される可能性がある。

    • DOUBLE 浮動小数点型のフィールドだけを使用する。Access では、単精度浮動小数点型の値を比較できない。その結果、表面上は、新しく追加したレコードまたは更新されたレコードが #DELETED# として表示されたり、レコードを検索または更新できないという現象が発生する。

    • BIGINT 型のカラムを持つテーブルを MyODBC 経由でリンクしている場合、結果が #DELETED として表示される。以下に回避策を示す。

      • データ型が TIMESTAMP、できれば TIMESTAMP(14) のダミーカラムを 1 つ追加する。

      • ODBC DSN アドミニストレータの接続オプションを指定するダイアログボックスで、'Change BIGINT columns to INT' をオンにする。

      • Access からテーブルリンクを削除し、再作成する。

      上記の回避策を実行した後も、既存のレコードは #DELETED# として表示されたままだが、新しく追加または更新されたレコードは正しく表示されるようになる。

    • TIMESTAMP 型カラムを追加した後でもエラー Another user has changed your data が発生する場合、次の対策で解決する可能性がある。

      テーブルデータシートビューを使用しない。代わりに必要なフィールドを定義したフォームを作成し、フォームデータシートビューを使用する。TIMESTAMP 型カラムの DefaultValue プロパティを NOW() に設定する必要がある。このテーブルを使用するユーザが混乱しないように、TIMESTAMP 型カラムを非表示にすることも 1 つの方法である。

    • 場合によっては、Access が、MySQL が解釈できない不正な SQL クエリを生成する可能性がある。これは、Access のメニューから "Query|SQLSpecific|Pass-Through" を選択することによって修正できる。

    • NT 上で動作する Access が BLOB 型カラムを OLE OBJECTS 型として報告する。代わりに MEMO 型カラムを使用する場合は、ALTER TABLE を使用してカラムを TEXT 型に変更する必要がある。

    • Access が DATE 型カラムを正しく処理できない場合がある。この問題が発生する場合、カラムを DATETIME 型に変更する。

    • Access で BYTE 型として定義されているカラムを使用している場合、Access はこのカラムを、TINYINT UNSIGNED 型ではなく、TINYINT 型としてエクスポートしようとする。この場合、カラムに 127 より大きい値が格納されていると問題が発生する。

  • ADO

    ADO API および MyODBC を使用してコーディングする場合、MySQL サーバでサポートされない一部のデフォルトプロパティに注意する必要がある。たとえば、CursorLocation プロパティadUseServer が設定されている場合、RecordCount プロパティは -1 を返す。正しい値が返されるようにするには、以下の VB コードで示すように、このプロパティを adUseClient に設定する必要がある。

    Dim myconn As New ADODB.Connection
    Dim myrs As New Recordset
    Dim mySQL As String
    Dim myrows As Long
    
    myconn.Open "DSN=MyODBCsample"
    mySQL = "SELECT * from user"
    myrs.Source = mySQL
    Set myrs.ActiveConnection = myconn
    myrs.CursorLocation = adUseClient
    myrs.Open
    myrows = myrs.RecordCount
    
    myrs.Close
    myconn.Close
    

    他の回避策としては、同じようなクエリで SELECT COUNT(*) ステートメントを使用して適切なレコード数を取得する方法がある。

  • Active server pages(ASP)

    オプションフラグ Return matching rows を使用する必要がある。

  • BDE アプリケーション

    オプションフラグ Don't optimize column widths および Return matching rows を設定する必要がある。

  • Borland Builder 4

    クエリを開始するとき、Active プロパティまたは Open メソッドを使用できる。注意: Active は、自動的に SELECT * FROM ... クエリを発行してクエリを開始するが、テーブルが大きい場合は問題になる場合がある。

  • ColdFusion(Unix 上)

    以下の情報は ColdFusion のマニュアルからの抜粋である。

    以下の情報を使用して、MySQL データソースに対して MyODBC とともに unixODBC ドライバを使用するように ColdFusion Server for Linux を設定する。Allaire は、MyODBC バージョン 2.50.26 が MySQL バージョン 3.22.27 および ColdFusion for Linux と連携して動作することを確認済みである(それ以降のバージョンも当然動作する)。MyODBC は、http://www.mysql.com/downloads/api-myodbc.html からダウンロードできる。

    ColdFusion バージョン 4.5.1 を使用すると、ColdFusion Administrator を使用して MySQL データソースを追加できる。ただし、ColdFusion バージョン 4.5.1 にはドライバは付属していない。MySQL ドライバが ODBC データソースのドロップダウンリストに表示されるようにするには、MyODBC ドライバをビルドして、/opt/coldfusion/lib/libmyodbc.so にコピーする必要がある。

    Contrib ディレクトリには mydsn-xxx.zip があり、これを使用して ColuFusion アプリケーションで MyODBC ドライバの DSN レジストリファイルをビルドおよび削除できる。

  • DataJunction

    DataJunction では、エクスポートで ENUM が出力されて、MySQL でトラブルの原因となるので、代わりに VARCHAR を出力するように設定を変更する必要がある。

  • Excel

    正常に動作する。以下にヒントを示す。

    • 日付データで問題が発生する場合、CONCAT() 関数を使用して日付データを文字列として選択する。たとえば、以下のように指定する。

      SELECT CONCAT(rise_time), CONCAT(set_time)
          FROM sunrise_sunset;
      

      この方法で文字列として取得した値は、Excel97 で正しく時刻として認識される。

      この例で CONCAT() を使用したのは、ODBC にカラムが ``文字列型'' であると思わせるためである。CONCAT() を使用しないと、ODBC はカラムが時刻型であることを認識するが、Excel はそれを認識しない。

      注意: Excel は自動的に文字列を時刻データに変換するので、上記の件は Excel のバグである。ソースがテキストファイルであれば、この自動変換は非常に便利だが、ソースがカラムごとのデータ型を正しく報告する ODBC 接続である場合はまったく意味をなさない。

  • Word

    MySQL から Word または Excel ドキュメントにデータを取得するには、MyODBC ドライバおよび Microsoft Query アドインを使用する必要がある。

    たとえば、データベースに、2 つのテキスト型カラムを持つテーブルがあるとする。

    • mysql クライアントコマンドラインツールを使用してレコードを挿入する。

    • ODBC マネージャを使用して、上記のデータベースに対して、たとえば my という DSN ファイルを作成する。

    • Word を開く。

    • 新規ドキュメントを作成する。

    • [Database] ツールバーの [Insert Database] をクリックする。

    • [Get Data] をクリックする。

    • [Get Data] ダイアログボックスの右側にある [MS Query] をクリックする。

    • [MS Query] で DSN ファイル my を使用して新しいデータソースを作成する。

    • 新しいクエリを選択する。

    • 取得するカラムを選択する。

    • 必要ならフィルタを作成する。

    • 必要なら並べ替えを指定する。

    • [Return Data to Microsoft Word] を選択する。

    • [Finish] をクリックする。

    • [Insert data] をクリックしてレコードを選択する。

    • [OK] をクリックする。Word ドキュメントに選択したレコードが表示される。

  • odbcadmin

    ODBC のテストプログラム。

  • Delphi

    BDE バージョン 3.2 以降を使用する必要がある。MySQL に接続する場合、オプションフィールド Don't optimize column width を有効にする。

    また、MyODBC の ODBC エントリおよび BDE エントリ(BDE エントリは Delphi Super Page で無料公開されている BDE Alias Editor を必要とする)をセットアップする便利な Delphi コードを以下に示す(これについては Bryan Brunton に感謝する)。

    fReg:= TRegistry.Create;
      fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True);
      fReg.WriteString('Database', 'Documents');
      fReg.WriteString('Description', ' ');
      fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll');
      fReg.WriteString('Flag', '1');
      fReg.WriteString('Password', '');
      fReg.WriteString('Port', ' ');
      fReg.WriteString('Server', 'xmark');
      fReg.WriteString('User', 'winuser');
      fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True);
      fReg.WriteString('DocumentsFab', 'MySQL');
      fReg.CloseKey;
      fReg.Free;
    
      Memo1.Lines.Add('DATABASE NAME=');
      Memo1.Lines.Add('USER NAME=');
      Memo1.Lines.Add('ODBC DSN=DocumentsFab');
      Memo1.Lines.Add('OPEN MODE=READ/WRITE');
      Memo1.Lines.Add('BATCH COUNT=200');
      Memo1.Lines.Add('LANGDRIVER=');
      Memo1.Lines.Add('MAX ROWS=-1');
      Memo1.Lines.Add('SCHEMA CACHE DIR=');
      Memo1.Lines.Add('SCHEMA CACHE SIZE=8');
      Memo1.Lines.Add('SCHEMA CACHE TIME=-1');
      Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT');
      Memo1.Lines.Add('SQLQRYMODE=');
      Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE');
      Memo1.Lines.Add('ENABLE BCD=FALSE');
      Memo1.Lines.Add('ROWSET SIZE=20');
      Memo1.Lines.Add('BLOBS TO CACHE=64');
      Memo1.Lines.Add('BLOB SIZE=32');
    
      AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines);
    

  • C++ Builder

    BDE バージョン 3.0 を使用して試験済み。唯一の既知の問題は、テーブルスキーマが変更されたときにクエリのフィールドが更新されないことである。ただし、BDE はインデックスの PRIMARY 以外の主キーを認識しないと思われるが、これはこれまで問題にはなっていない。

  • Vision

    オプションフラグ Return matching rows を使用する必要がある。

  • Visual Basic

    テーブルを更新できるようにするには、テーブルに主キーを定義する必要がある。

    Visual Basic を ADO とともに使用した場合、大きなサイズの整数を処理できない。これは、SHOW PROCESSLIST のようなクエリは正しく動作しないことを意味する。これを解決するには、ODBC 接続文字列にオプション OPTION=16384 を設定するか、または MyODBC 接続画面で Change BIGINT columns to INT を選択する。場合によっては、Return matching rows も選択する必要がある。

  • VisualInterDev

    [Microsoft][ODBC Driver Manager] Driver does not support this parameter というエラーが発生する場合、結果セットに BIGINT が含まれていることが原因である可能性がある。MyODBC 接続画面で Change BIGINT columns to INT を選択すると解決する可能性がある。

  • Visual Objects

    オプションフラグ Don't optimize column widths を使用する必要がある。

11.2.6. ODBC で AUTO_INCREMENT 属性を持つカラムの値を取得する方法

よくある問題として、INSERT を実行したときに自動生成される ID の値をどのように取得するかという問題があります。ODBC を使用する場合、以下のようなステートメントによって、自動生成される ID を取得できます(autoAUTO_INCREMENT 属性を持つフィールドとする)。

INSERT INTO foo (auto,text) VALUES(NULL,'text');
SELECT LAST_INSERT_ID();

自動生成された ID を他のテーブルに挿入するだけであれば、以下のようなステートメントを実行します。

INSERT INTO foo (auto,text) VALUES(NULL,'text');
INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text');

See 項11.1.12.3. 「最後に挿入したレコードの一意な ID はどのように取得するのか」

一部の ODBC アプリケーション(少なくとも Delphi および Access)では、以下のクエリを使用して、新しく挿入されたレコードを検索できます。

SELECT * FROM tbl_name WHERE auto IS NULL;

11.2.7. MyODBC に関する問題の報告

MyODBC を使用して問題が発生した場合、まず MyODBC ログを作成すること、および ODBC マネージャからログファイル(ODBCADMIN で要求すると作成されるログ)を作成することから始めます。

MyODBC ログを取得するには、以下の手順に従います。

  1. myodbc.dll ではなく、myodbcd.dll を使用していることを確認する。確認する最も簡単な方法は、MyODBC ディストリビューションから myodbcd.dll を取得して、C:\windows\system32 または C:\winnt\system32 にあると思われる myodbc.dll に上書きでコピーすることである。

    注意: 元の myodbc.dll は myodbcd.dll よりもはるかに高速なので、試験が終わったら元の myodbc.dll に戻すことが望ましい。

  2. MyODBC 接続画面または設定画面でオプションフラグ `Trace MyODBC' を有効にする。ログが C:\myodbc.log ファイルに書き込まれる。

    上記の画面を再表示するとトレースオプションが無効になってしまう場合は、myodbcd.dll ドライバが使用されていないことを意味する(上記の項目参照)。

  3. アプリケーションを起動して、異常終了させる。

MyODBC trace file を調べて、おかしいと思われる部分を探します。myodbc.log ファイルで文字列 >mysql_real_query を検索すると、クエリを発行した部分が見つかります。

また、mysql モニタまたは admndemo でクエリを重複して実行し、エラーが MyODBC で発生しているのか、MySQL で発生しているのかを調べる必要があります。

おかしいと思われる部分が見つかった場合、関連する行だけ(最大 40 行)を myodbc メーリングリストに投稿してください。See 項1.7.1.1. 「MySQL メーリングリスト」。 決して MyODBC ログファイルや ODBC ログファイルを丸ごと投稿しないでください。

おかしいと思われる部分が見つからなかった場合、最後の手段として、MyODBC トレースファイル、ODBC ログファイル、および問題点を説明する README ファイルを含むアーカイブ(tar または zip)を作成します。このアーカイブを ftp://support.mysql.com/pub/mysql/secret/ にアップロードします。このファイルには MySQL AB の担当者だけがアクセスできます。また、担当者とこれらのデータは完全に分離されています。

この問題が発生するプログラムを他にも作成できる場合は、それもアップロードしてください。

同じプログラムを他の SQL サーバに対して実行すると正常に動作する場合は、そのときの ODBC ログファイルを作成してください。

提供していただける情報が多いほど、その問題を解決できる可能性も高まりますので、できるだけ多くの情報を提供してください。

11.3. MySQL の Java 接続(JDBC)

MySQL では 2 つの JDBC ドライバをサポートしています。

マニュアルについては、JDBC のマニュアルおよび MySQL 固有の機能に関する各ドライバのマニュアルを参照してください。

11.4. MySQL PHP API

PHP は、HTML 埋め込み型のサーバサイドスクリプト言語で、動的な Web ページの作成に使用できます。PHP は、MySQL をはじめとする複数のデータベースへのアクセス機能をサポートしています。独立したプログラムとして動作させることもできるし、Apache Web サーバで使用するモジュールとしてコンパイルすることもできます。

PHP Web サイト(http://www.php.net/)でディストリビューションおよびマニュアルが公開されています。

11.4.1. MySQL および PHP のよくある問題

  • エラー: "Maximum Execution Time Exceeded" これは PHP の制約です。php3.ini ファイルを開いて、必要に応じて最大実行時間を 30 秒からもっと長い時間に設定してください。1 スクリプトあたりで使用できる RAM を 8MB から 16MB に倍増させる方法も考えられます。

  • エラー: "Fatal error: Call to unsupported or undefined function mysql_connect() in .." これは、使用している PHP をコンパイルしたときに MySQL のサポートが組み込まれなかったことを意味します。MySQL のダイナミックモジュールをコンパイルして PHP にロードするか、または組み込み MySQL サポートとともに PHP を再コンパイルすることで解決できます。この詳細については、PHP マニュアルを参照してください。

  • エラー: "undefined reference to `uncompress'" これは、クライアントライブラリをコンパイルしたときに、クライアント/サーバプロトコルの zlib サポートが組み込まれていたことを意味します。-lmysqlclient を指定してリンクするときに、最後に -lz を追加することで解決できます。

11.5. MySQL Perl API

ここでは、Perl DBI インタフェースについて説明します。以前のインタフェースは、mysqlperl と呼ばれていました。DBI/現在は DBD が Perl インタフェースとして推奨されています。mysqlperl は廃止され、ここでは説明しません。

11.5.1. DBIDBD::mysql

DBI は、さまざまなデータベース向けの汎用インタフェースです。これは、何も変更しなくても、複数の異なるデータベースで動作するスクリプトを作成できることを意味します。データベースの種類ごとにデータベースドライバ(DBD)を定義する必要があります。MySQL の場合、このドライバは DBD::mysql と呼ばれます。

Perl5 DBI の詳細については、DBI の Web ページにあるマニュアルを参照してください。

http://dbi.perl.org/

注意: Perl でトランザクションを使用する場合、DBD-mysql バージョン 1.2216 以降が必要です。バージョン 2.1022 以降が推奨されます。

MySQL Perl サポートのインストール手順については、項2.7. 「Perl インストールについてのコメント」 を参照してください。

MySQL モジュールをインストールしている場合、以下のどちらかのコマンドを使用して、特定の MySQL 機能に関する情報を入手できます。

shell> perldoc DBD/mysql
shell> perldoc mysql

11.5.2. DBI インタフェース

移植可能な DBI メソッドおよび属性

メソッド/属性説明
connectデータベースサーバへの接続を確立する。
disconnectデータベースサーバへの接続を切断する。
prepareSQL ステートメントを実行するためのプリコンパイルを行う。
executeプリペアドステートメントを実行する。
doSQL ステートメントをプリコンパイルし、実行する。
quote挿入する文字列または BLOB 値を引用符で囲む。
fetchrow_arrayフィールドの配列として次のレコードを取得する。
fetchrow_arrayrefフィールドの参照配列として次のレコードを取得する。
fetchrow_hashrefハッシュテーブルへの参照として次のレコードを取得する。
fetchall_arrayref配列の配列としてすべてのデータを取得する。
finishステートメントの使用を完了して、リソースを解放する。
rows影響を受けたレコードの数を返す。
data_sourceslocalhost で使用できるデータベースの配列を返す。
ChopBlanksfetchrow_* メソッドで余白を切り取るかどうかを制御する。
NUM_OF_PARAMSプリペアドステートメントのプレースホルダの数。
NULLABLEどのカラムに NULL を格納できるかを示す。
traceデバッグのためにトレースを実行する。

MySQL 固有のメソッドおよび属性

メソッド/属性説明
mysql_insertid最新の AUTO_INCREMENT 値を返す。
is_blobどのカラムが BLOB 値かを示す。
is_keyどのカラムがキーかを示す。
is_numどのカラムが数値かを示す。
is_pri_keyどのカラムが主キーかを示す。
is_not_nullどのカラムに NULL を格納できないかを示す。NULLABLE を参照。
length拡大可能な最大カラムサイズを示す。
max_length結果セットに実際に存在する最大のカラムサイズを示す。
NAMEカラム名を示す。
NUM_OF_FIELDS結果セットのフィールドの数。
table結果セットのテーブル名を示す。
typeすべてのカラムの型を示す。

Perl のメソッドについては、以下のセクションで詳細に説明します。メソッドの戻り値に使用される変数には以下の意味があります。

  • $dbh

    データベースハンドル

  • $sth

    ステートメントハンドル

  • $rc

    リターンコード(通常はステータス)

  • $rv

    戻り値(通常はレコード数)

移植可能な DBI メソッドおよび属性

  • connect($data_source, $username, $password)

    connect メソッドを使用して、データソースへのデータベース接続を確立する。$data_source 値は DBI:driver_name: で始まる必要がある。DBD::mysql ドライバを使用する connect の使用例を以下に示す。

    $dbh = DBI->connect("DBI:mysql:$database", $user, $password);
    $dbh = DBI->connect("DBI:mysql:$database:$hostname",
                        $user, $password);
    $dbh = DBI->connect("DBI:mysql:$database:$hostname:$port",
                        $user, $password);
    

    ユーザ名またはパスワード、あるいはその両方が未定義の場合、DBI はそれぞれ DBI_USER および DBI_PASS の各環境変数の値を使用する。ホスト名を指定しない場合、'localhost' が使用される。ポート番号を指定しない場合、デフォルトの MySQL ポート(3306)が使用される。

    Msql-Mysql-modules バージョン 1.2009 の時点では、$data_source 値に特定の修飾子を使用できる。

    • mysql_read_default_file=file_name

      file_name をオプション設定ファイルとして読み込む。オプション設定ファイルについては、項4.1.2. 「my.cnf オプション設定ファイル」 を参照すること。

    • mysql_read_default_group=group_name

      オプション設定ファイルを読み込むときのデフォルトグループは、通常は [client] グループである。mysql_read_default_group オプションを指定することによって、デフォルトグループは [group_name] グループになる。

    • mysql_compression=1

      クライアントとサーバ間で圧縮された通信を使用する(MySQL バージョン 3.22.3 以降)。

    • mysql_socket=/path/to/socket

      サーバへの接続に使用する Unix ソケットのパス名を指定する(MySQL バージョン 3.21.15 以降)。

    複数の修飾子をセミコロンで区切って指定できる。

    たとえば、ユーザ名およびパスワードを DBI スクリプトにハードコードすることを避けるには、以下のように connect の呼び出しを記述して、ユーザの ~/.my.cnf オプション設定ファイルからユーザ名およびパスワードを読み込む。

    $dbh = DBI->connect("DBI:mysql:$database"
                    . ";mysql_read_default_file=$ENV{HOME}/.my.cnf",
                    $user, $password);
    

    この呼び出しによって、オプション設定ファイルの [client] グループに定義されたオプションが読み込まれる。上記と同じ処理を、[perl] グループに指定したオプションを使用して実行するには、以下のようなコードを記述する。

    $dbh = DBI->connect("DBI:mysql:$database"
                    . ";mysql_read_default_file=$ENV{HOME}/.my.cnf"
                    . ";mysql_read_default_group=perl",
                    $user, $password);
    

  • disconnect

    disconnect メソッドは、データベースからデータベースハンドルを切断する。通常、このメソッドはプログラムを終了する直前に呼び出される。以下に例を示す。

    $rc = $dbh->disconnect;
    

  • prepare($statement)

    SQL ステートメントを、データベースで実行できるようにプリコンパイルし、ステートメントハンドル ($sth) を返す。ステートメントハンドルを使用して execute メソッドを呼び出すことができる。

    通常、prepare および execute を使用して SELECT ステートメント(および SHOWDESCRIBEEXPLAIN などの SELECT ライクなステートメント)を処理する。以下に例を示す。

    $sth = $dbh->prepare($statement)
        or die "Can't prepare $statement: $dbh->errstr\n";
    

    サイズの大きい結果セットをクライアントに読み込む場合、Perl に mysql_use_result() を使用するように指示できる。

    my $sth = $dbh->prepare($statement { "mysql_use_result" => 1});
    

  • execute

    execute メソッドは、プリペアドステートメントを実行する。非 SELECT ステートメントの場合、execute は影響を受けたレコードの数を返す。影響を受けたレコードがない場合、execute"0E0" を返す。Perl はこの戻り値を 0 として処理するが、true とみなす。エラーが発生した場合、executeundef を返す。SELECT ステートメントの場合、execute はデータベースで SQL クエリを起動するだけであり、データを取得するには、後述する fetch_* メソッドの中の 1 つを使用する必要がある。以下に例を示す。

    $rv = $sth->execute
              or die "can't execute the query: " . $sth->errstr;
    

  • do($statement)

    do メソッドは、SQL ステートメントをプリコンパイルおよび実行し、影響を受けたレコード数を返す。影響を受けたレコードがない場合、do"0E0" を返す。Perl はこの戻り値を 0 として処理するが、true とみなす。このメソッドは通常、あらかじめプリコンパイルできない(ドライバの制約により)、または複数回実行する必要がない(挿入、削除など)非 SELECT ステートメントで使用する。以下に例を示す。

    $rv = $dbh->do($statement)
            or die "Can't execute $statement: $dbh- >errstr\n";
    

    一般に、'do' ステートメントは、パラメータを使用しないステートメントをプリコンパイルして実行するよりも、非常に高速である(使用することが推奨される)。

  • quote($string)

    quote メソッドは、文字列に含まれる特殊文字を "エスケープ" して、引用符で囲むために使用する。以下に例を示す。

    $sql = $dbh->quote($string)
    

  • fetchrow_array

    このメソッドは、次のレコードのデータを取得し、フィールド値の配列として返す。以下に例を示す。

    while(@row = $sth->fetchrow_array) {
            print qw($row[0]\t$row[1]\t$row[2]\n);
    }
    

  • fetchrow_arrayref

    このメソッドは、次のレコードのデータを取得し、フィールド値の配列として返す。以下に例を示す。

    while($row_ref = $sth->fetchrow_arrayref) {
            print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n);
    }
    

  • fetchrow_hashref

    このメソッドは、レコードデータを取得し、フィールド名と値の組み合わせを含むハッシュテーブルへの参照を返す。これは前述の配列参照を使用する場合ほど効率的ではない。以下に例を示す。

    while($hash_ref = $sth->fetchrow_hashref) {
            print qw($hash_ref->{firstname}\t$hash_ref->{lastname}\t\
                    $hash_ref->{title}\n);
    }
    

  • fetchall_arrayref

    このメソッドは、SQL ステートメントが返すすべてのデータ(レコード)を取得するために使用する。このメソッドは、"各レコードに対応する配列への参照" の配列への参照を返す。データにアクセスしたり、出力するには、ネストされたループを使用する。以下に例を示す。

    my $table = $sth->fetchall_arrayref
                    or die "$sth->errstr\n";
    my($i, $j);
    for $i ( 0 .. $#{$table} ) {
            for $j ( 0 .. $#{$table->[$i]} ) {
                    print "$table->[$i][$j]\t";
            }
            print "\n";
    }
    

  • finish

    このステートメントハンドルを使用してこれ以上データを取得しないことを示す。このメソッドを呼び出すことによって、ステートメントハンドルおよびそれに関連付けられたシステムリソースがすべて解放される。以下に例を示す。

    $rc = $sth->finish;
    

  • rows

    最後に実行されたコマンドによって影響を受けた(更新された、削除された、など)レコードの数を返す。通常、非 SELECT execute ステートメントの後に使用される。以下に例を示す。

    $rv = $sth->rows;
    

  • NULLABLE

    カラムに NULL 値を格納できるかどうかを示す値の配列への参照を返す。各配列要素に格納できる値は、カラムに NULL 値を格納できない場合は 0 または空文字列、格納できる場合は 1、カラムの NULL ステータスが不明な場合は 2 である。以下に例を示す。

    $null_possible = $sth->{NULLABLE};
    

  • NUM_OF_FIELDS

    この属性は、SELECT ステートメントまたは SHOW FIELDS ステートメントが返したフィールドの数を示す。これを使用して、結果セットを返すステートメントが実行されたかどうかを調べることができる。値が 0 の場合は、INSERTDELETE、または UPDATE などの非 SELECT ステートメントが実行されたことを示す。以下に例を示す。

    $nr_of_fields = $sth->{NUM_OF_FIELDS};
    

  • data_sources($driver_name)

    このメソッドは、ホスト 'localhost' 上で動作する MySQL サーバに対して使用できるデータベース名を含む配列を返す。以下に例を示す。

    @dbs = DBI->data_sources("mysql");
    

  • ChopBlanks

    この属性は、fetchrow_* メソッドが、返された値の先頭および末尾の空白を切り取るかどうかを決定する。以下に例を示す。

    $sth->{'ChopBlanks'} =1;
    

  • trace($trace_level) , trace($trace_level, $trace_filename)

    trace メソッドはトレースを有効または無効にする。DBI クラスメソッドとして呼び出された場合は、すべてのハンドルのトレースを有効または無効にする。データベースまたはステートメントハンドルのメソッドとして呼び出された場合は、指定されたハンドル(およびそのハンドルから今後派生する子)のトレースを有効または無効にする。$trace_level を 2 に設定すると、詳細なトレース情報が出力される。$trace_level を 0 に設定すると、トレースが無効になる。トレース情報は、デフォルトでは標準エラー出力に出力される。$trace_filename が指定された場合、そのファイルが追加モードで開かれ、トレースが有効なすべてのハンドルのトレース情報がそのファイルに出力される。以下に例を示す。

    DBI->trace(2);                # trace everything
    DBI->trace(2,"/tmp/dbi.out"); # trace everything to
                                  # /tmp/dbi.out
    $dth->trace(2);               # trace this database handle
    $sth->trace(2);               # trace this statement handle
    

    また、DBI_TRACE 環境変数を設定することによって DBI トレースを有効にできる。この変数に数値を設定することは、DBI->(value) を呼び出すことと同等である。この変数にパス名を設定することは、DBI->(2,value) を呼び出すことと同等である。

MySQL 固有のメソッドおよび属性

ここに示すメソッドは MySQL 固有であり、DBI の標準には含まれません。is_blobis_keyis_numis_pri_keyis_not_nulllengthmax_lengthtable など、その多くは廃止されています。DBI 標準に代替できるメソッドや属性が存在する場合は、ここに明記します。

  • mysql_insertid

    MySQL の AUTO_INCREMENT 機能を使用する場合、最新の値がここに格納される。以下に例を示す。

    $new_id = $sth->{mysql_insertid};
    

    古いバージョンの DBI インタフェースでは、$sth->{'insertid'} を使用できる。

  • is_blob

    ブール値の配列への参照を返す。配列の要素が TRUE の場合、対応するカラムが BLOB 型であることを示す。以下に例を示す。

    $keys = $sth->{is_blob};
    

  • is_key

    ブール値の配列への参照を返す。配列の要素が TRUE の場合、対応するカラムがキーであることを示す。以下に例を示す。

    $keys = $sth->{is_key};
    

  • is_num

    ブール値の配列への参照を返す。配列の要素が TRUE の場合、対応するカラムに数値が格納されることを示す。以下に例を示す。

    $nums = $sth->{is_num};
    

  • is_pri_key

    ブール値の配列への参照を返す。配列の要素が TRUE の場合、対応するカラムが主キーであることを示す。以下に例を示す。

    $pri_keys = $sth->{is_pri_key};
    

  • is_not_null

    ブール値の配列への参照を返す。配列の要素が FALSE の場合、対応するカラムに NULL 値を格納できることを示す。以下に例を示す。

    $not_nulls = $sth->{is_not_null};
    

    is_not_null は廃止されている。DBI 標準の NULLABLE 属性(前述)を使用することが推奨される。

  • length , max_length

    各メソッドは、カラムサイズの配列への参照を返す。length の配列は、各カラムの(テーブル定義での宣言に従った)拡大可能な最大サイズを示す。max_length の配列は、結果テーブルに実際に存在するデータの最大サイズを示す。以下に例を示す。

    $lengths = $sth->{length};
    $max_lengths = $sth->{max_length};
    

  • NAME

    カラム名の配列への参照を返す。以下に例を示す。

    $names = $sth->{NAME};
    

  • table

    テーブル名の配列への参照を返す。以下に例を示す。

    $tables = $sth->{table};
    

  • type

    カラムのデータ型の配列への参照を返す。以下に例を示す。

    $types = $sth->{type};
    

11.5.3. DBI/DBD に関するその他の情報

perldoc コマンドを使用すると DBI の詳細情報を取得できます。

perldoc DBI
perldoc DBI::FAQ
perldoc DBD::mysql

また、pod2manpod2html などのツールを使用して、他のフォーマットのデータに変換できます。

DBI に関する最新情報については、DBI の Web ページ http://dbi.perl.org/ を参照してください。.

11.6. MySQL C++ API

MySQL Connector/C++(または MySQL++)は、C++ のオフィシャル MySQL API です。詳細については、http://www.mysql.com/products/mysql++/ を参照してください。

11.6.1. Borland C++

Borland C++ 5.02 を使用して MySQL Windows ソースをコンパイルできます(Windows ソースには、Microsoft VC++ および Borland C++ 用のプロジェクトファイルしか用意されていないので、プロジェクトファイルを自作する必要があります)。

Borland C++ を使用する場合の唯一の既知の問題は、VC++ とは異なる構造体のアラインメントを使用していることです。これは、デフォルトの libmysql.dll ライブラリ(VC++ でコンパイルされている)を Borland C++ で使用すると、問題が発生することを意味します。以下のいずれかを実行すると、この問題を回避できます。

  • http://www.mysql.com/downloads/os-win32.html からダウンロードできる Borland C++ のスタティック MySQL ライブラリを使用する。

  • 事前に割り当てられた MYSQL 構造体ではなく、NULL を引数として mysql_init() を呼び出す。

11.7. MySQL Python API

MySQLdb は、Python 向けの MySQL サポートを提供しており、Python DB API バージョン 2.0 に準拠しています。詳細については、http://sourceforge.net/projects/mysql-python/ を参照してください。

11.8. MySQL Tcl API

MySQLtcl は、Tcl プログラム言語から MySQL データベースサーバにアクセスするための簡単な API です。詳細については、http://www.xdobry.de/mysqltcl/ を参照してください。

11.9. MySQL Eiffel Wrapper

Eiffel MysQL は、Mychael Ravits が作成した Eiffel プログラム言語を使用した MySQL データベースサーバへのインタフェースです。詳細については、http://efsa.sourceforge.net/archive/ravits/mysql.htm を参照してください。


This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.

アダルトレンタルサーバー