gpt4 book ai didi

mysql - 使用 C libmysqlclient 无法解释的 MySQL 行为

转载 作者:行者123 更新时间:2023-11-30 19:37:37 25 4
gpt4 key购买 nike

我用 C 语言编写了一个处理引擎,它从表中提取 40k 条记录,处理数据并将结果写入另一个表。当我将处理后的数据打印到屏幕上时,它看起来很完美,因此所有变量都持有正确的值。我需要将数据写入一个具有 3 列作为主键的表。我创建这样的表:

CREATE TABLE halfcomp 
(
MarketCode varchar(20) NOT NULL,
TRZNum varchar(20) NOT NULL,
origTRZNum varchar(20) NOT NULL,
PRIMARY KEY (MarketCode, TRZNum, origTRZNum)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

当 C 程序写入数据库时​​,我得到的结果是垃圾。我在不应该重复的地方得到了重复的值,结果乱序,列看起来在某些地方交换了,等等。我已经玩了几天了,我认为这与主键有关。

我认为这是因为我创建了另一个带有自动递增整数主键的表,这将我的其他值释放为普通的旧表值。我创建了这样的表:

CREATE TABLE halfcomp
(
Ind int(11) auto_increment NOT NULL,
MarketCode varchar(20) DEFAULT NULL,
TRZNum varchar(20) DEFAULT NULL,
origTRZNum varchar(20) DEFAULT NULL,
PRIMARY KEY (Ind)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

当我使用相同的 C 代码写入该表时,结果是完美的。没有重复值,没有混淆的列。但问题是,我需要 MarketCode、TRZNum 和 origTRZNum 列作为主键。我是否不恰本地创建了第一个表?我很茫然。

我已经仔细研究了 C 程序,它看起来是正确的,并且相同的 C 代码也适用于其他表。但对于这个表,它不起作用。任何见解将不胜感激!谢谢!

编辑:我已经更新了代码。我不再任意使用 malloc 或 sprintf,我将缓冲区值直接设置为字符串变量的值。我也尝试在字符串末尾添加“\0”。到目前为止,没有任何帮助,我也遇到了同样不稳定的行为。仅当值是主键时才会发生这种情况,否则它们会正确加载。我必须假设C在开始将数据库信息传递给我时在字符串末尾添加了一个空终止符,并且我在处理数据时使用strcpy来回传递值,所以我必须相信空终止符已经存在。还有其他想法吗?

int writeDB(void) {
MYSQL *conn2;
MYSQL_STMT *stmt2;
MYSQL_BIND bind2[3];

char *server = "localhost";
char *user = "root";
char *password = "";
char *database = "thekeydb";
int port = 3306;

int k;
int length = 15000;
unsigned long mc2_length, mn2_length, om2_length;
const char *insertStmt2 = "INSERT INTO tempcomp (MarketCode, TRZNum, origTRZNum) VALUES (?,?,?)";

conn2 = mysql_init(NULL);
mysql_real_connect(conn2, server,user,password,database, port, NULL, 0);
stmt2 = mysql_stmt_init(conn2);
mysql_autocommit(conn2, 0);
mysql_query(conn2, "START TRANSACTION");

for (k=0; k < length; k++) {
memset((void *) bind2, 0, sizeof(bind2));

mc2_length = strlen(comps[k].marketCode);
mn2_length = strlen(comps[k].trzNum);
om2_length = strlen(comps[k].origTrzNum);

if (mysql_stmt_prepare(stmt2, insertStmt2, strlen(insertStmt2)) != 0) {
printf("Unable to create new session: Could not prepare statement\n");
}

bind2[0].buffer_type = MYSQL_TYPE_STRING;
bind2[0].buffer = comps[k].marketCode;
bind2[0].buffer_length = STRING_SIZE;
bind2[0].is_null = 0;
bind2[0].length = &mc2_length;

bind2[1].buffer_type = MYSQL_TYPE_STRING;
bind2[1].buffer = comps[k].trzNum;
bind2[1].buffer_length = STRING_SIZE;
bind2[1].is_null = 0;
bind2[1].length = &mn2_length;

bind2[2].buffer_type = MYSQL_TYPE_STRING;
bind2[2].buffer = comps[k].origTrzNum;
bind2[2].buffer_length = STRING_SIZE;
bind2[2].is_null = 0;
bind2[2].length = &om2_length;

if (mysql_stmt_bind_param(stmt2, bind2) != 0) {
printf("Unable to create new session: Could not bind parameters");
}
mysql_stmt_execute(stmt2);
printf("%s, %s, %s, %s\n", comps[k].marketCode, comps[k].trzNum, comps[k].origTrzNum, comps[k].address);
}

mysql_query(conn2, "COMMIT");
mysql_autocommit(conn2, 1);
mysql_stmt_free_result(stmt2);
mysql_stmt_close(stmt2);
mysql_close(conn2);

return 1;
}

最佳答案

几乎可以肯定,您不会 null 终止字符串。如果将字符串作为参数传递给 libmysqlclient 中的准备语句,则必须指定字符串的长度。如果您的字符串不是 null 终止,并且您使用 strlen() 将长度传递给 MYSQL_BIND 结构,或者,您 1 将它们传递给 sprintf() 或类似的方法来构建查询,然后会出现意外行为,例如您的程序的行为。

<小时/>

1如果您确实这样做,请不要这样做,而是使用准备好的语句。

关于mysql - 使用 C libmysqlclient 无法解释的 MySQL 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39461529/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com