Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C libmysqlclient无法解释的MySQL行为_Mysql_C_Key - Fatal编程技术网

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

使用C libmysqlclient无法解释的MySQL行为,mysql,c,key,Mysql,C,Key,我用C编写了一个处理引擎,它从一个表中提取40k条记录,处理数据并将结果写入另一个表。当我将处理后的数据打印到屏幕上时,它看起来非常完美,因此所有变量都保持正确的值。我需要将数据写入一个表,该表有3列作为主键。我创建如下表: CREATE TABLE halfcomp ( MarketCode varchar(20) NOT NULL, TRZNum varchar(20) NOT NULL, origTRZNum varchar(20) NOT NULL, P

我用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;
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程序写入数据库时,我得到的结果是垃圾。我得到了不应该重复的值,结果是无序的,列看起来在不同的位置切换,等等。我已经玩了几天了,我认为这与主键有关

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

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;
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;
}
int-writeDB(无效){
MYSQL*conn2;
MYSQL_STMT*stmt2;
MYSQL_BIND bind2[3];
char*server=“localhost”;
char*user=“root”;
字符*密码=”;
char*database=“thekeydb”;
int端口=3306;
int k;
整数长度=15000;
无符号长mc2_长度、mn2_长度、om2_长度;
const char*insertStmt2=“插入tempcomp(市场代码、TRZNum、origTRZNum)值(?,?)”;
conn2=mysql_init(NULL);
mysql\u real\u connect(conn2,服务器,用户,密码,数据库,端口,空,0);
stmt2=mysql\u stmt\u init(conn2);
mysql_自动提交(conn2,0);
mysql_查询(conn2,“启动事务”);
对于(k=0;k
几乎可以肯定,您没有终止字符串。如果将字符串作为参数传递给libmysqlclient中的准备语句,则必须指定字符串的长度。如果字符串没有
null
终止,并且您正在使用
strlen()
将长度传递给
MYSQL\u BIND
结构,或者,您正在将它们传递给
sprintf()
或类似的结构以构建查询,则会出现类似于程序行为的意外行为



1如果你真的这样做了,就不要这样做,而是使用事先准备好的陈述。

为了社区的利益,我必须诚实地回答这个问题,尽管我承认我这样做很尴尬。在这一点上,我认为我一直在正确地将数据写入数据库,但为了进行比较而错误地查看数据库数据。当我在屏幕上打印数据时,我看到了三列。第一个是完全重复的市场代码,第二个是相当随机的代码,第三个是一组5个或8个或其他任何人重复的代码。当我使用“SELECT*FROM tempcomp”查看数据时,第二列会重复,但在较小的组中,如2或3,第三列看起来是随机的。我现在相信MySQL Workbench在将数据呈现给我之前对数据进行了排序。因此,数据库显示与程序显示的内容不同。当我使用一个自动递增的整数作为主键时,数据库以与屏幕显示相同的顺序显示数据。但是当我的三列是主键时,它对输出进行了不同的排序。这是痛苦的三天试图弄明白这一点,和t