Как пере-вводить текст с Предстеной Statement в MySQL с C?

Вы будете видеть я считаю следующий код написанным в C, который использует API MySQL, чтобы присоединяться в BD. Во время ввождения мне интересно делать это с Предстеной Statement API и во время ввождения текста за мной последует следующее: introducir la descripción de la imagen aquí

Поскольку вы увидите в коде более впереди то, что я пробую сделать, он состоит в том, чтобы вводить слово, "ЗДЕСЬ" выйдя из цикла после commit используя код, который уже у меня есть. Пример глупый, но я изменил текст из-за provar и вдруг: Не работает! и я не могу понять потому что. Код:

void insertar_usuario(MYSQL *conn, MYSQL_STMT *stmt){
char *stmt_str = "INSERT INTO users (id, token, fecha_registro, ultimo_acceso) VALUES(?,?,?,?)";
MYSQL_BIND param[4];
int             *id;                /* SERA NULL PORQUE A.I. */
char            token[26];          /* token aleatorio de 25 caracteres */
unsigned long   token_length;   /*              */
MYSQL_TIME      fecha_creacion;     /*              */
MYSQL_TIME      ultimo_acceso;      /*              */

time_t hora;
struct tm *cur_time;


printf ("Empezamos a insertar datos\n");

if (mysql_stmt_prepare (stmt, stmt_str, strlen (stmt_str)) != 0) {
    print_stmt_error (stmt, "Could not prepare INSERT statement");
    return;
}

memset ((void *) param, 0, sizeof (param)); /* zero the structures */

param[0].buffer_type = MYSQL_TYPE_LONG;
param[0].buffer = (void *) &id;
param[0].is_unsigned = 0;
param[0].is_null = 0;

param[1].buffer_type = MYSQL_TYPE_STRING;
param[1].buffer = (void *) token;
param[1].buffer_length = sizeof (token);
param[1].is_null = 0;


param[2].buffer_type = MYSQL_TYPE_DATETIME;
param[2].buffer = (void *) &fecha_creacion;
param[2].is_null = 0;

param[3].buffer_type = MYSQL_TYPE_DATETIME;
param[3].buffer = (void *) &ultimo_acceso;
param[3].is_null = 0;

if (mysql_stmt_bind_param (stmt, param) != 0) {
    print_stmt_error (stmt, "Could not bind parameters for INSERT");
    return;
}
mysql_autocommit(conn, 0);

for(int i = 0 ; i < 1 ; i++){

    (void) time (&hora); /* get current time */

    /* Damos valores */
    id = NULL;

    strcpy(token, ctime(&hora));
    token[24] = '\0';
    token_length = strlen(token);
    param[1].length = &token_length;

    cur_time = localtime(&hora);
    fecha_creacion.year = cur_time->tm_year + 1900;
    fecha_creacion.month = cur_time->tm_mon + 1;
    fecha_creacion.day = cur_time->tm_mday;
    fecha_creacion.hour = cur_time->tm_hour;
    fecha_creacion.minute = cur_time->tm_min;
    fecha_creacion.second = cur_time->tm_sec;
    fecha_creacion.second_part = 0;
    fecha_creacion.neg = 0;

    ultimo_acceso.year = cur_time->tm_year + 1900;
    ultimo_acceso.month = cur_time->tm_mon + 1;
    ultimo_acceso.day = cur_time->tm_mday;
    ultimo_acceso.hour = cur_time->tm_hour;
    ultimo_acceso.minute = cur_time->tm_min;
    ultimo_acceso.second = cur_time->tm_sec;
    ultimo_acceso.second_part = 0;
    ultimo_acceso.neg = 0;

    if (mysql_stmt_execute (stmt) != 0) {
        print_stmt_error (stmt, "No se ha podido ejecutar la sentencia SQL");
        mysql_rollback(conn);
        return;
    }

    printf("%s\n", "Datos insertados correctamente!!");
    mysql_commit(conn);
    sleep(1);
    /* POSIBLE SOLUCION PEGANDO AQUI */

}

mysql_autocommit(conn, 1);

/* POSIBLE SOLUCION PEGANDO AQUI */
/* Damos valores */
id = NULL;

strcpy(token, "AQUI");
token[4] = '\0';
token_length = strlen(token);
fprintf(stdout, "strlen(\"%s\") = %lu\n", token, strlen(token));
param[1].length = &token_length;

cur_time = localtime(&hora);
fecha_creacion.year = cur_time->tm_year + 1900;
fecha_creacion.month = cur_time->tm_mon + 1;
fecha_creacion.day = cur_time->tm_mday;
fecha_creacion.hour = cur_time->tm_hour;
fecha_creacion.minute = cur_time->tm_min;
fecha_creacion.second = cur_time->tm_sec;
fecha_creacion.second_part = 0;
fecha_creacion.neg = 0;

ultimo_acceso.year = cur_time->tm_year + 1900;
ultimo_acceso.month = cur_time->tm_mon + 1;
ultimo_acceso.day = cur_time->tm_mday;
ultimo_acceso.hour = cur_time->tm_hour;
ultimo_acceso.minute = cur_time->tm_min;
ultimo_acceso.second = cur_time->tm_sec;
ultimo_acceso.second_part = 0;
ultimo_acceso.neg = 0;

if (mysql_stmt_execute (stmt) != 0) {
    print_stmt_error (stmt, "No se ha podido ejecutar la sentencia SQL");
    return;
}

printf("%s\n", "Datos insertados correctamente!!");
}

Благодаря всем заранее!

ОБНОВЛЕННЫЙ

Я понял, что проблема находится в длине текста, который мы посылаем, и возможно, что он должен вновь делать:

mysql_stmt_prepare()
mysql_stmt_bind_param()

Но тогда, это значило бы, что нужно знать длину текста, который мы пошлем перед тем, как выполнять mysql_stmt_bind_param() и что param[1].length = &token_length; он ничем не служит, итак, выйдя из цикла, это у меня есть снова и совсем не (когда fprintf дает ожидаемую стоимость 4)

ВОЗМОЖНОЕ РЕШЕНИЕ: ПОЧЕМУ?

Я обновил код, если я копирую и прикрепляю этот фрагмент кода:

if (mysql_stmt_bind_param (stmt, param) != 0) {
        print_stmt_error (stmt, "Could not bind parameters for INSERT");
        return;
}

В частях кода, который он помещает /*Posible solucion pegando aquí */ (только в 1 из 3, поместите их в любой функционируй) Я получаю:

introducir la descripción de la imagen aquí

Есть ты изменяешь поступающие данные различных доказательств, быть закрепленным в тех, которые он помещает ясно ЗДЕСЬ

0
задан 21.01.2017, 01:34
0 ответов

На основании этого заявления:

char token[26];

Почему ты это делаешь?

strcpy(token, ctime(&hora));
token[24] = '\0';
token_length = strlen(token);

Если ты понимаешь, что буфера - длины 26, логическое было бы, по крайней мере, setear token[25] чтобы избегать терять один байт. С другой стороны, если у тебя есть, что setear эта стоимость в частности в 0 в разе позволять, что это был сам strcpy тот, кто заканчивает цепь, потому что ты пишешь вне буфера... Не было бы более логичным тогда использовать безопасную функцию strcpy_s?

strcpy_s(token,sizeof(token),ctime(&hora));
// token[24] = '\0' <-- SOBRA!!!
token_length = strlen(token);

С другой стороны...

strcpy(token, "AQUI");
token[4] = '\0';

Если, перед этими инструкциями token он содержал что-то из типа (_ он - заместитель '\0' чтобы поддерживать выравнивание):

A B C D E F G H I J _

После strcpy он будет хранить следующее:

A Q U I _ F G H I J _

А именно, для C буфер содержит только AQUI. То, в чем ты нуждаешься, состоит в том, чтобы вводить твой текст, не добавляя '\0' конец, потому что, если ты не теряешь информации. Очень простая форма - с memcpy:

memcpy(token,"AQUI",4);

Конечно, если ты сосредотачиваешься на следующей инструкции:

param[1].length = &token_length;

остается ясным, что param [1] .length - указатель, который обозначается в token_length, а следовательно ты не должен повторять эту инструкцию каждый раз, когда ты меняешь контент token... несмотря на то, что обновляет только token_length он стоит тебе.

Это:

strcpy(token, ctime(&hora));
token[24] = '\0';
token_length = strlen(token);
param[1].length = &token_length;

Это остается так:

memcpy(token,"AQUI",4);
// token[24] = '\0'; <-- SOBRA
// token_length = strlen(token); <-- La longitud de token no ha variado
// param[1].length = &token_length; <-- el puntero y
1
ответ дан 03.12.2019, 17:36