Mysql记录

利用stmt操作mysql

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "lxy.h"

#define MYSQL_HOST "192.168.5.167"
#define USER_NAME "root"
#define PASSWORD "2002"
#define PORT 3306
#define DB_NAME "****"
#define QBMMJ_QUERY_USER "SELECT name FROM user LIMIT 10"

MYSQL conn;
MYSQL_STMT *stmt;
MYSQL_RES *res;
un_int res_length;
MYSQL_FIELD *field;

char name[255] = "\0";
un_long id;

char *resp;

int main(int num, char *args[])
{
    char *resp;
    MYSQL_BIND *in;
    lxy_mysql_init_stmt_mysql_conn(&conn, &stmt);
    if (mysql_stmt_prepare(stmt, QBMMJ_QUERY_USER, strlen(QBMMJ_QUERY_USER)))
    {
        fprintf(stderr, "prepare stmt error errno:%d errmessage:%s\n", mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
        exit(-1);
    }
    if ((res = mysql_stmt_result_metadata(stmt)) == NULL)
    {
        fprintf(stderr, "gain stmt matadata error errno:%d errmessage:%s\n", mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
        exit(-1);
    }
    mysql_stmt_bind_param(stmt, in);
    res_length = res->field_count;
    MYSQL_BIND out[res_length];
    memset(out, 0, sizeof(out));
    lxy_param_out_result(res, out);
    mysql_stmt_execute(stmt);
    mysql_stmt_bind_result(stmt, out);
    while (!mysql_stmt_fetch(stmt))
    {
        fprintf(stdout, "%s\n", name);
    }
    mysql_stmt_free_result(stmt);
    mysql_stmt_close(stmt);
    mysql_close(&conn);
    return 0;
}

int lxy_mysql_init_stmt_mysql_conn(MYSQL *conn, MYSQL_STMT **stmt)
{
    mysql_init(conn);
    if (mysql_real_connect(conn, MYSQL_HOST, USER_NAME, PASSWORD, DB_NAME, PORT, NULL, 0) == NULL)
    {
        fprintf(stderr, "create connection error errno:%d errmessage:%s\n", mysql_errno(conn), mysql_error(conn));
        exit(-1);
    }
    if ((*stmt = mysql_stmt_init(conn)) == NULL)
    {
        fprintf(stderr, "create stmt error errno:%d errmessage:%s\n", mysql_stmt_errno(*stmt), mysql_stmt_error(*stmt));
        exit(-1);
    }
    return 0;
}

MYSQL_BIND *lxy_param_out_result(const MYSQL_STMT *const res, MYSQL_BIND (*out)[])
{
    int i = 0;
    while ((field = mysql_fetch_field(res)) != NULL)
    {
        switch (field->type)
        {
        case MYSQL_TYPE_VAR_STRING:
            (*out + i)->buffer_type = MYSQL_TYPE_VAR_STRING;
            (*out + i)->buffer_length = field->length;
            (*out + i)->buffer = name;
            break;
        case MYSQL_TYPE_LONGLONG:
            (*out + i)->buffer_type = MYSQL_TYPE_LONGLONG;
            (*out + i)->buffer_length = field->length;
            (*out + i)->buffer = &id;
            break;
        }
        i++;
    }
    return *out;
}
#pragma once

#include <mysql/mysql.h>
#include <mysql/binary_log_types.h>

#ifndef _LXY_
#define _LXY_

typedef unsigned long un_long;
typedef unsigned int un_int;
MYSQL_BIND *lxy_param_out_result(const MYSQL_STMT *res, MYSQL_BIND (*out)[]);
int lxy_mysql_init_stmt_mysql_conn(MYSQL *const conn, MYSQL_STMT **stmt);

#endif

类型对照表:

typedef enum enum_field_types {  
  MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
  MYSQL_TYPE_SHORT,  MYSQL_TYPE_LONG,
  MYSQL_TYPE_FLOAT,  MYSQL_TYPE_DOUBLE,
  MYSQL_TYPE_NULL,   MYSQL_TYPE_TIMESTAMP,
  MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
  MYSQL_TYPE_DATE,   MYSQL_TYPE_TIME,
  MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
  MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
  MYSQL_TYPE_BIT,
  MYSQL_TYPE_TIMESTAMP2,
  MYSQL_TYPE_DATETIME2,
  MYSQL_TYPE_TIME2,
  MYSQL_TYPE_JSON=245,
  MYSQL_TYPE_NEWDECIMAL=246,
  MYSQL_TYPE_ENUM=247,
  MYSQL_TYPE_SET=248,
  MYSQL_TYPE_TINY_BLOB=249,
  MYSQL_TYPE_MEDIUM_BLOB=250,
  MYSQL_TYPE_LONG_BLOB=251,
  MYSQL_TYPE_BLOB=252,
  MYSQL_TYPE_VAR_STRING=253,
  MYSQL_TYPE_STRING=254,
  MYSQL_TYPE_GEOMETRY=255
} enum_field_types;

gcc compile参考https://dev.mysql.com/doc/refman/5.7/en/c-api-building-clients.html

gcc lxy.c -o lxy.out -L/usr/local/mysql/lib -lmysqlclient

对时间的处理参考
https://dev.mysql.com/doc/refman/5.7/en/c-api-prepared-statement-date-handling.html

stmt使用参考
https://dev.mysql.com/doc/refman/5.7/en/c-api-prepared-statement-function-overview.html

Execution Steps
To prepare and execute a statement, an application follows these steps:

Create a prepared statement handler with mysql_stmt_init(). To prepare the statement on the server, call mysql_stmt_prepare() and pass it a string containing the SQL statement.

If the statement will produce a result set, call mysql_stmt_result_metadata() to obtain the result set metadata. This metadata is itself in the form of result set, albeit a separate one from the one that contains the rows returned by the query. The metadata result set indicates how many columns are in the result and contains information about each column.

Set the values of any parameters using mysql_stmt_bind_param(). All parameters must be set. Otherwise, statement execution returns an error or produces unexpected results.

Call mysql_stmt_execute() to execute the statement.

If the statement produces a result set, bind the data buffers to use for retrieving the row values by calling mysql_stmt_bind_result().

Fetch the data into the buffers row by row by calling mysql_stmt_fetch() repeatedly until no more rows are found.

Repeat steps 3 through 6 as necessary, by changing the parameter values and re-executing the statement.

When mysql_stmt_prepare() is called, the MySQL client/server protocol performs these actions:

The server parses the statement and sends the okay status back to the client by assigning a statement ID. It also sends total number of parameters, a column count, and its metadata if it is a result set oriented statement. All syntax and semantics of the statement are checked by the server during this call.

The client uses this statement ID for the further operations, so that the server can identify the statement from among its pool of statements.

When mysql_stmt_execute() is called, the MySQL client/server protocol performs these actions:

The client uses the statement handler and sends the parameter data to the server.

The server identifies the statement using the ID provided by the client, replaces the parameter markers with the newly supplied data, and executes the statement. If the statement produces a result set, the server sends the data back to the client. Otherwise, it sends an okay status and the number of rows changed, deleted, or inserted.

When mysql_stmt_fetch() is called, the MySQL client/server protocol performs these actions:

The client reads the data from the current row of the result set and places it into the application data buffers by doing the necessary conversions. If the application buffer type is same as that of the field type returned from the server, the conversions are straightforward.

If an error occurs, you can get the statement error number, error message, and SQLSTATE code using mysql_stmt_errno(), mysql_stmt_error(), and mysql_stmt_sqlstate(), respectively.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值