简体   繁体   中英

SQLite query gives different results

I am developing a small application in C and I want to use SQLite to perform some queries on a database. The problem is that I am getting a weird behaviour.

If I run the same query on the same database on Firefox plugin "SQLite Manager" I get the expected result, but if I run it through the C interface in my program I get a wrong order of the resulting tuples.

You can find the database here (CSV or SQLite format), while the problematic query is this one:

SELECT name, slot, id, species_id 
FROM type_names T, pokemon_types PT, pokemon P 
WHERE T.type_id = PT.type_id 
AND P.id = PT.pokemon_id AND T.local_language_id = 9 
AND P.identifier LIKE '%char%' 
ORDER BY P.species_id;

On Firefox I get the expected result:

+--------+------+-------+------------+
|  name  | slot |  id   | species_id |
+--------+------+-------+------------+
| Fire   |    1 |     4 |          4 |
| Fire   |    1 |     5 |          5 |
| Fire   |    1 |     6 |          6 |
| Flying |    2 |     6 |          6 |
| Fire   |    1 | 10034 |          6 |
| Dragon |    2 | 10034 |          6 |
| Fire   |    1 | 10035 |          6 |
| Flying |    2 | 10035 |          6 |
| Fire   |    1 |   390 |        390 |
+--------+------+-------+------------+

while in CI get this:

+--------+------+-------+------------+
|  name  | slot |  id   | species_id |
+--------+------+-------+------------+
| Fire   |    1 |     4 |          4 |
| Fire   |    1 |     5 |          5 |
| Flying |    2 |     6 |          6 |
| Flying |    2 | 10035 |          6 |
| Fire   |    1 |     6 |          6 |
| Fire   |    1 | 10034 |          6 |
| Fire   |    1 | 10035 |          6 |
| Dragon |    2 | 10034 |          6 |
| Fire   |    1 |   390 |        390 |
+--------+------+-------+------------+

I also tried with some simple code that only access the database with that query and I always get the same problem, here is the code:

#include <stdio.h>
#include <sqlite3.h>

// argument 1 is path to db, argument 2 is query

static int callback(void *NotUsed, int argc, char **argv, char **azColName){

    int i;
    for(i=0; i<argc; i++){
        printf("%s\t", argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}

int main(int argc, char **argv){
    sqlite3 *db;
    char *zErrMsg = 0;
    int rc;

    if( argc!=3 ){
        fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
        return(1);
    }
    rc = sqlite3_open(argv[1], &db);
    if( rc ){
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return(1);
    }
    rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
    if( rc!=SQLITE_OK ){
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    }
    sqlite3_close(db);
    return 0;
}

The entirety of your ORDER BY clause is ORDER BY P.species_id . Therefore, both outputs are 100% correct (they are both sorted with the P.species_id value ascending). If you want the results to be sorted by additional columns, you will need to include those columns in your ORDER BY clause.

Seems like you are expecting:

SELECT name, slot, id, species_id 
FROM type_names T, pokemon_types PT, pokemon P 
WHERE T.type_id = PT.type_id 
AND P.id = PT.pokemon_id 
AND T.local_language_id = 9 
AND P.identifier LIKE '%char%' ORDER BY P.species_id, id, slot ASC;

Further qualify your ORDER BY to be able to replicate the results exactly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM