INSERT INTO ... SELECT ...语句不起作用

时间:2018-08-06 03:34:55

标签: mysql c mariadb

我对我不太了解的INSERT INTO ... SELECT ...语句遇到了麻烦。我不确定这是MariaDB的问题还是我做错了。

我有一个表(我们称为table_a),该表由列idcb组成。 cb不是唯一的,但是我在c上设置了索引。

我有另一个表(我们称为table_b),该表由列table_a_id_1table_a_id_1组成。我使用此表来跟踪table_a中彼此具有相同值c的行-即,如果第1-4行都具有相同的值c,则存在将是table_b-1, 21, 31, 42, 32, 43, 4中的6个条目。 / p>

所以,这就是想法-我在table_a中添加了一堆行。每次插入之后,我将获取插入ID,将其存储在insert_id中,然后使用以下查询准备语句:

INSERT INTO table_b (table_a_id_1, table_a_id_2) SELECT ?, id FROM table_a WHERE c = ? AND id != ?

然后我将insert_id(我刚刚插入到c的{​​{1}}的值,和table_a(再次)绑定到该语句并执行它。

这是我的问题:insert_id查询不执行任何操作。它不会引起任何错误-它只是不会插入任何内容。但是,如果我获取INSERT INTO ... SELECT ...insert_id的值并通过PHPMyAdmin运行查询,它就可以正常工作。我没有在该程序中使用交易记录...因此,我实在感到困惑,为什么在我手动进行编程而不是以编程方式进行操作时会起作用。

任何人都知道为什么要这样做吗?

编辑:我更改了程序,以便分别进行cSELECT查询。在我的程序中,INSERT查询不会出现任何行,即使我在类似PHPMyAdmin的程序中运行完全相同的查询也能看到它们。我真的很困惑。

编辑2:这是我的代码(为简便起见删除了一些错误处理代码):

SELECT

稍后在程序中,我有:

int save_to_database(char *b, char *c, my_ulonglong &insert_id) {
  const char *insert_str = "INSERT INTO table_a (c, b) VALUES (?, ?)";
  MYSQL_STMT *stmt;
  MYSQL_BIND bind[2];
  int retval;
  unsigned long buffer_length[2];
  my_bool is_null[2];

  stmt = mysql_stmt_init(boinc_db.mysql);
  if(!stmt) {
    // Print an error, return -1
  }

  retval = mysql_stmt_prepare(stmt, insert_str, strlen(insert_str));
  if(retval) {
    // Print an error, close stmt, return -1
  }

  memset(bind, 0, sizeof(bind));

  buffer_length[0] = strlen(c);
  buffer_length[1] = strlen(b);

  is_null[0] = 0;
  is_null[1] = 0;

  bind[0].buffer_type = MYSQL_TYPE_STRING;
  bind[0].buffer = c;
  bind[0].buffer_length = buffer_length[0];
  bind[0].length = &buffer_length[0];
  bind[0].is_null = &is_null[0];
  bind[0].is_unsigned = 0;

  bind[1].buffer_type = MYSQL_TYPE_STRING;
  bind[1].buffer = b;
  bind[1].buffer_length = buffer_length[1];
  bind[1].length = &buffer_length[1];
  bind[1].is_null = &is_null[1];
  bind[1].is_unsigned = 0;

  if(mysql_stmt_bind_param(stmt, bind)) {
    // Print an error, close stmt, return -1
  }

  if(mysql_stmt_execute(stmt)) {
    // Print an error, close stmt, return -1
  }

  insert_id = mysql_stmt_insert_id(stmt);

  mysql_stmt_close(stmt);
  return 0;
}

int generate_matches(my_ulonglong pair_id, char *c) {
  const char *insert_str = "INSERT INTO table_b (a_pair, b_pair) SELECT ?, id FROM table_a WHERE c = ? AND id != ?";

  MYSQL_STMT *stmt;
  MYSQL_BIND in_bind[3];
  int retval;
  unsigned long in_buffer_len[3];
  my_bool in_is_null[3];

  stmt = mysql_stmt_init(boinc_db.mysql);
  if(!stmt) {
    // Print an error, return -1
  }

  retval = mysql_stmt_prepare(stmt, insert_str, strlen(insert_str));
  if(retval) {
    // Print an error, close stmt, return -1
  }

  memset(in_bind, 0, sizeof(in_bind));

  in_buffer_len[0] = sizeof(pair_id);
  in_is_null[0] = 0;

  in_buffer_len[1] = strlen(c) + 1;
  in_is_null[1] = 0;

  in_buffer_len[2] = sizeof(pair_id);
  in_is_null[2] = 0;

  in_bind[0].buffer_type = MYSQL_TYPE_LONGLONG;
  in_bind[0].buffer = (void *) &pair_id;
  in_bind[0].buffer_length = in_buffer_len[0];
  in_bind[0].length = &in_buffer_len[0];
  in_bind[0].is_null = &in_is_null[0];
  in_bind[0].is_unsigned = 1;

  in_bind[1].buffer_type = MYSQL_TYPE_STRING;
  in_bind[1].buffer = (void *) c;
  in_bind[1].buffer_length = in_buffer_len[1];
  in_bind[1].length = &in_buffer_len[1];
  in_bind[1].is_null = &in_is_null[1];
  in_bind[1].is_unsigned = 0;

  in_bind[2].buffer_type = MYSQL_TYPE_LONGLONG;
  in_bind[2].buffer = (void *) &pair_id;
  in_bind[2].buffer_length = in_buffer_len[2];
  in_bind[2].length = &in_buffer_len[2];
  in_bind[2].is_null = &in_is_null[2];
  in_bind[2].is_unsigned = 1;

  if(mysql_stmt_bind_param(stmt, in_bind)) {
    // Print an error, close stmt, return -1
  }

  if(mysql_stmt_execute(stmt)) {
    // Print an error, close stmt, return -1
  }

  mysql_stmt_close(stmt);

  return 0;
}

我可以在数据库中看到发生这种情况的实例:

  if(save_to_database(b, c, insert_id)) {
    // Throw an error and exit
  }

  if(generate_matches(insert_id, c)) {
    // Throw an error and exit
  }

我的日志文件显示未引发任何错误,但是MariaDB [database]> SELECT * FROM table_a WHERE c = "1000140625" AND id != 27803; +-------+------------+-----------+ | id | c | b | +-------+------------+-----------+ | 27801 | 1000140625 | 537675600 | | 27802 | 1000140625 | 659036664 | +-------+------------+-----------+ 2 rows in set (0.00 sec) 中没有记录。

0 个答案:

没有答案