我对我不太了解的INSERT INTO ... SELECT ...
语句遇到了麻烦。我不确定这是MariaDB的问题还是我做错了。
我有一个表(我们称为table_a
),该表由列id
,c
和b
组成。 c
和b
不是唯一的,但是我在c
上设置了索引。
我有另一个表(我们称为table_b
),该表由列table_a_id_1
,table_a_id_1
组成。我使用此表来跟踪table_a
中彼此具有相同值c
的行-即,如果第1-4行都具有相同的值c
,则存在将是table_b
-1, 2
,1, 3
,1, 4
,2, 3
,2, 4
和3, 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运行查询,它就可以正常工作。我没有在该程序中使用交易记录...因此,我实在感到困惑,为什么在我手动进行编程而不是以编程方式进行操作时会起作用。
任何人都知道为什么要这样做吗?
编辑:我更改了程序,以便分别进行c
和SELECT
查询。在我的程序中,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)
中没有记录。