C言語操作MySQLデータベース


1.データベースに接続します.C言語からMySQLデータベースに接続するには、a)接続ハンドル構造を初期化する2つのステップがあります.b)実際に接続を作成する.まずmysql_を使いますInit初期化接続ハンドル:
MYSQL * mysql_init (MYSQL *);
は通常mysqlに空のポインタを渡します.Initという関数は、新しく割り当てられた接続ハンドル構造を指すポインタを返します.既存の構造を渡すと、再初期化されます.エラーが発生した場合はNULLを返します.
初期化に成功したらmysql_を使用real_接続して実際の接続を作成するには、次の手順に従います.
MYSQL * mysql_real_connect(MYSQL * connection,
      const char * server_host,
      const char * sql_user_name,   
      const char * sql_password,
      const char *db_name,
      unsigned int port_number,
      const char * unix_socket_name,
      unsigned int flags);
connectionは、初期化された接続ハンドル構造である必要があります.server_hostはホスト名でもIPアドレスでも構いませんが、ネイティブに接続する場合はlocalhostを使用して接続タイプを最適化できます.port_numberとunix_socket_MYSQLインストールのデフォルト設定を変更しない限り、nameはそれぞれ0とNULLである必要があります.
接続できない場合はNULLを返します.接続が完了したら、プログラムが正常に終了する前にmysql_を使用します.closeはこの接続ハンドルを閉じます.     
void mysql_close(MYSQL * connection);
では、上記の関数を呼び出して、connect 1として上記のデータベースへのアクセスを確立しようとしています.c.内容は次のとおりです.
#include <stdlib.h>
#include <stdio.h>
#include "mysql.h"

int main (int argc, char *argv[])
{
        MYSQL *conn_ptr;
        conn_ptr=mysql_init(NULL); //     
        if(!conn_ptr){
                fprintf(stderr, "mysql_init failed
"); return EXIT_FAILURE; } conn_ptr = mysql_real_connect(conn_ptr, "localhost", "moldao","newpassword","moldao_test", 0, NULL, 0); // // : , ( IP), , , ,0,NULL,0) mysql> if(conn_ptr){ printf("Connection success
"); } else { printf("Connection failed
"); } mysql_close(conn_ptr); // return EXIT_SUCCESS; }

次にコンパイル:
#gcc -I/usr/include/mysql connect1.c -lmysqlclient -o connect1
   connect1.c:4:19:エラー:mysql.h:そのファイルやディレクトリがありません
ヒントはmysqlが見つからないことです.h、このエラーが発生した原因はmysqlがないからです.hファイル、mysql-develパッケージにあります.このパッケージをインストールする必要があります.
 sudo yum install mysql-devel -y
で探してみます.
#locate mysql.h
/usr/include/mysql/mysql.h
これでこのヘッダファイルを見つけることができます(-Iは、指定された場所でヘッダファイルを検索することを意味します.man gccを参照してください).再コンパイルを試みます.
# gcc -I/usr/include/mysql connect1.c -lmysqlclient -o connect1
/usr/bin/ld: cannot find -lmysqlclient
collect 2:ldは1を返します
リンクライブラリに問題があり、mysqlclientリンクライブラリが見つかりません.man gccは、後で-Lで検索場所を指定できることを発見しました.そこで、mysqlclientライブラリの場所を見つけます.
   locate *mysqlclient*
   /usr/lib/mysql/libmysqlclient.a
   /usr/lib/mysql/libmysqlclient.so
   /usr/lib/mysql/libmysqlclient.so.15
   /usr/lib/mysql/libmysqlclient.so.15.0.0
   /usr/lib/mysql/libmysqlclient_r.a
   /usr/lib/mysql/libmysqlclient_r.so
   /usr/lib/mysql/libmysqlclient_r.so.15
   /usr/lib/mysql/libmysqlclient_r.so.15.0.0
これで場所を見つけてコンパイルできます.
gcc -I/usr/include/mysql connect1.c -lmysqlclient -L/usr/lib/mysql -o connect1
コンパイルに成功し、実行できます.その前にmysqldが実行されていることを確認します.
sudo /etc/rc.d/init.d/mysqld restart
で生成された実行可能ファイルが実行されます.
 ./connect1
  Connection success
は、私たちが設計した接続に成功した印刷情報を印刷します.これでC言語でMySQLデータベースに入りました.
2.操作データベース
データベースに入ると、データベースの読み書き操作を開始できます.
データベースの主な操作はselect,insert,update,deleteの4種類です.
   
a)sql文の埋め込み:
SQL文を実行する主なAPI関数は次のとおりです.
int mysql_query(MYSQL *connection, const char * query)
は、確立された接続構造ポインタとテキスト文字列形式の有効なSQL文(文末にセミコロンを使用しない)を受け入れます.0を正常に返します.
もう一つ重要な関数がありますmysql_affected_rows()は、printfを使用する場合は%luフォーマットを使用して符号なしロング整数に変換することを推奨する符号なしタイプを返します.この関数は、以前に実行されたupdate、delete、insertなどのクエリーの影響を受けるローの数を返します.        
my_ulonglong mysql_affected_rows(MYSQL *connection);
MySQLは、更新操作によって変更されたローの数を返しますが、他の多くのデータベースは、where文に一致するレコードのために更新されたものとみなされます.
通常mysql_について関数、戻り値0は行が影響を受けていないことを示し、正数は実際の結果であり、一般的に文の影響を受けた行数を表す.
    
b)select文の使用:
select文はSQL文で最も頻繁に使用される操作です.   
完全なデータ抽出プロセスには、クエリーの実行、データの抽出、データの処理、クリーンアップの4つのステップが含まれます.
mysql_の使用queryはSQL文を送信しmysql_を使用します.store_resultまたはmysql_use_resultでデータを抽出します.そしてmysql_を使いますfetch_row呼び出しでデータを処理し、最後にmysql_を使用します.free_resultは、クエリーに使用されるメモリリソースを解放します.
    mysql_use_resultとmysql_store_resultはいずれも結果セット構造を指す(result set structure)のポインタは、失敗した場合はNULLを返します.storeはクエリしたデータベースの結果をこの結果セットに直接配置し、useは最終データベースのデータ結果をこの結果セットに直接配置しません.storeは、データをローカルメモリに直接読み出すので、データ量の少ないクエリに適しています.useは似ています.1つのストリームの操作では、一度にすべての結果を返すわけではありません.したがって、この結果セットではmysql_を繰り返し呼び出す必要があります.fetch_rowはすべてのデータを抽出するまで.
1)すべてのデータを一度に取得する:
MYSQL_RES *mysql_store_result(MYSQL *connection);
mysqlが正常に呼び出されました.queryの後にこの関数を使用すると、クライアントで返されたすべてのデータが直ちに保存され、この結果セットへのポインタが返されます.失敗した場合はNULLを返します.
成功したらmysql_num_rowsは、戻りレコードの数を得るために、一般的には正数であるべきであり、戻り行が一致しなければ0を返す.    
my_ulonglong mysql_num_rows(MYSQL_RES *result);
今データを得て、mysqlを使うことができますfetch_rowはそれを処理しmysql_を使用することもできますdata_seek,mysql_row_seekとmysql_row_tellはデータセットを往復移動します.    
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
この関数は、上記の結果セットから1行を抽出し、1行構造に配置します.データが切れたりエラーが発生したりしたときにNULLを返します.    
void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);
この関数は、構造セットの現在のポインタのジャンプを許可し、次のmysql_に設定されます.fetch_row操作で返されるロー.offsetは行番号で、0から総行数から1を引く範囲です.0を渡すと、初期位置に戻ります.    
MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result);
この関数は、結果セットの現在の位置を返します.mysqlには使えませんdata_seek.
データに対するすべての操作が完了したらmysql_を呼び出す必要があります.free_resultは、MYSQLデータベースの善後処理を完了させる.    
void mysql_free_result(MYSQL_RES *result);

使用例:
   MYSQL my_connection;
   MYSQL_RES *res_ptr;
   MYSQL_ROW sqlrow;
   
    mysql_init(&my_connection);

    if(mysql_real_connect(&my_connection, "localhost", "moldao","password","moldao_test", 0, NULL, 0)){
                printf("Connection success
"); res = mysql_query(&my_connection, "select * from children where age < 10"); if(res){ printf("select error: %s
", mysql_error(&my_connection)); }else { res_ptr = mysql_store_result(&my_connection); if(res_ptr){ printf("Retrieved %lu rows
", (unsigned long)mysql_num_rows (res_ptr)); while (sqlrow = mysql_fetch_row(res_ptr)){ unsigned int field_count; field_count =0; while(field_count < mysql_field_count(&my_connection)){ printf("%s ", sqlrow[field_count]);field_count++; } } if(mysql_errno(&my_connection)){ printf("Retrive error : %s
", mysql_error(&my_connection)); } } mysql_free_result(res_ptr); } mysql_close(&my_connection);

2)一度に1行のデータを抽出する
このようなデータの抽出方法を推奨します.ネットワーク負荷のバランスを向上させ、ビッグデータ・セットによるストレージの過負荷を低減します.しかし、遅延も増加し、ネットワークリンクが操作途中で失敗した場合、不完全なデータが得られ、混乱をもたらす可能性があります.
このときmysql_に頼るuse_result:
   
 MYSQL_RES *mysql_use_result(MYSQL * connection);

storeと同様に、エラーはNULLを返し、成功すると結果セットオブジェクトへのポインタを返します.
使用例:
   //          
   res_ptr = mysql_store_result(&my_connection);
     if(res_ptr){
        while (sqlrow = mysql_fetch_row(res_ptr)){
            //display_row_or_dealwith_row_here;
            }
        }
    
c)update,insert,delete文の使用
update,insert,deleteの3つの操作は、mysql_を使用してデータを返さない文です.queryで文を実行します.       
使用例:
   int res = mysql_query(&my_connection, "SQL  ");
   if(!res){
        printf("operation success
affected %lu rows
", (unsigned long)mysql_affected_row (&my_connection)); } else{ fprintf(stderr, "failed error: %d: %s", mysql_errno(&my_connection), mysql_error(&my_connection)); }
注意したのはmysql_affected_rowは、where文に一致する行数だけでなく、本当に影響を受けたり、変更されたりする行数を返します.
      
3.データベースのメタデータとデータを完全に表示する例:
#include <stdlib.h>
#include <stdio.h>

#include "mysql.h"

MYSQL my_connection;
MYSQL_RES *res_ptr;
MYSQL_ROW sqlrow;

void display_header();
void display_row();

int main (int argc, char *argv[])
{

        int first_row =1;
        int res;

        mysql_init(&my_connection); //     
/*      if(!conn_ptr){
                fprintf(stderr, "mysql_init failed
"); return EXIT_FAILURE; } */ if(mysql_real_connect(&my_connection, "localhost", "moldao","savage","moldao_test", 0, NULL, 0)){ printf("Connection success
"); res = mysql_query(&my_connection, "select * from children where age > 4"); if(res){ fprintf(stderr, "Select error : %s
", mysql_error(&my_connection)); } else{ res_ptr = mysql_use_result(&my_connection); if(res_ptr){ display_header(); while((sqlrow = mysql_fetch_row(res_ptr))){ if(first_row){ display_header(); first_row = 0; } display_row(); } if(mysql_errno(&my_connection)){ fprintf(stderr, "Retrive error: %s
", mysql_error(&my_connection)); } } mysql_free_result(res_ptr); } mysql_close(&my_connection); } else { fprintf(stderr,"Connection failed
"); if(mysql_errno(&my_connection)){ fprintf(stderr, "Connection error %d: %s
", mysql_errno(&my_connection), mysql_error (&my_connection)); } } return EXIT_SUCCESS; } void display_header(){ MYSQL_FIELD *field_ptr; printf("Column details:
"); while((field_ptr = mysql_fetch_field(res_ptr))!= NULL){ printf("\t Name: %s
", field_ptr->name); printf("\t Type: "); if(IS_NUM(field_ptr->type)){ printf("Numeric field
"); }else{ switch(field_ptr->type){ case FIELD_TYPE_VAR_STRING: printf("VARCHAR
");break; case FIELD_TYPE_LONG: printf("LONG
");break; default: printf("Type is %d, check in mysql_com.h
", field_ptr->type); } } printf("\t Max width %ld
", field_ptr ->length); if(field_ptr->flags & AUTO_INCREMENT_FLAG) printf("\t Auto increment
"); printf("
"); } } void display_row(){ unsigned int field_count; field_count = 0; while(field_count < mysql_field_count(&my_connection)){ if(sqlrow[field_count]) printf("%s ", sqlrow[field_count]); else printf("NULL"); field_count++; } printf("
"); }