Liaison d'un 'unsigned long' (uint64) dans une instruction sqlite3? C ++
Je suis en utilisant le sqlite3 bibliothèque est disponible à sqlite.org.
J'ai quelques unsigned longs que j'aimerais stocker dans une base de données. Je ne veux pas construire la requête de moi-même et de la laisser ouverte à une sorte d'injection (qu'il soit accidentel ou pas). Donc, je suis en utilisant le sqlite_bind_*
fonctions de "désinfecter" mes paramètres.
Le problème est qu'il n'y a pas une fonction de type unsigned long des nombres entiers, tout entiers.
int sqlite3_bind_int(sqlite3_stmt*, int, int);
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
Je vais certainement avoir des numéros qui vont déborder si je suis incapable de les stocker dans un unsigned manière.
Vais-je avoir besoin pour gérer moi-même? (c'est à dire la conversion d'un type non signé après la sélection de la bd ou de la conversion en type signé avant l'insertion en base de données)
Si je dois gérer moi-même, comment pourrait-on comparer les requêtes qui sont stockés sous forme d'un entier long signé lorsque les comparaisons sont vraiment conçus pour être dans le non signé de gamme?
À la recherche à la Les types de données INTEGER qui se converti, on pourrait penser que unsigned longs peuvent être représentées sans problème.
Si il y a d'autres solutions, merci de m'éclairer!
Merci!
source d'informationauteur g19fanatic
Vous devez vous connecter pour publier un commentaire.
Si vous voulais stocker un uint64_t dans une base de données sqlite et encore lui permettent d'être utilisé comme un uint64_t en SQL, alors vous allez probablement avoir besoin d'écrire des fonctions personnalisées.
Il vous suffit de lancer le un uint64_t à un int64_t lors de l'envoi et de la base de données, puis d'écrire une fonction personnalisée à effectuer ce qu'comparaison etc. vous avez besoin d'. Par exemple, pour faire un plus grand que la comparaison:
Ensuite l'utiliser dans SQL:
Alternativement, si vous avez besoin de classement personnalisé en fonction sur un uint64_t, vous devriez être en mesure d'utiliser sqlite3_create_collation d'une manière similaire.
Ce n'est pas une solution parfaite, comme vous aurez besoin d'écrire une fonction personnalisée pour chaque opération que vous voulez faire, mais il devrait au moins fonctionner.
Une base de données SQLite n'a pas la capacité à stocker de 64 bits non signé entiers. C'est juste une limitation des données.
Vos options sont:
Puisque ce sont des tables de hachage, vous probablement ne se soucient pas de comparaisons autres que l'égalité des tests. Ainsi, la plupart de ces méthodes fonctionnent très bien pour vous.
J'ai essayé un certain nombre d'approches différentes, principalement en essayant d'obtenir le type de colonne à travailler comme un sqlite3_uint64 comme expliqué au https://www.sqlite.org/c3ref/int64.html
Pas eu de chance comme le uint64 n'a pas été stocké comme un uint64 dans le tableau. Quand j'ai regardé les données stockées, il a été signé, donc j'ai supposé que c'était stockée comme int64.
J'ai fini par la préfixation de la valeur avec un seul char à force de sqlite pour stocker sous forme de texte, sans aucune conversion. Il était beaucoup plus facile de simplement ajouter le char de la requête de sélection de la valeur à des fins de comparaison. Ainsi 9223360144090060712 est devenu A9223360144090060712, et je pourrais simplement faire un SELECT OÙ HASH = 'A9223360144090060712'
uint32_t
s'adapte entièrement à l'intérieur d'unint64_t
sans aucun soucis, donc vous pouvez faire une simple affectation.Assigner l'autre sens, vous devrait vérifier les limites de la
int64_t
de sorte que toutes les modifications apportées à la valeur à l'intérieur de la base de données sont pris tôt.Vous pouvez ensuite envoyer votre
int64
à la base de données sqlite comme vous le feriez normalement.Personnellement, j'ai trouvé que la meilleure façon de faire face à ce problème tout en permettant toujours à la base de données pour effectuer des comparaisons etc. est pour stocker des entiers non signés dans la base de données à l'aide de la
sqlite3_bind_int64
fonction. Je suis en supposant que vous êtes en utilisant 32 bits entiers non signés, qui peut facilement être stocké dans un environnement 64 bits entier signé.Par exemple:
Puis de récupérer votre variable (en supposant que vous êtes à l'aide de boost, sinon vous devrez écrire votre propre dépassement de code de vérification):
Bien sûr, cela tombe à l'eau si vous souhaitez stocker unsigned int64s, mais c'est un peu une limitation de sqlite.
il s'agit d'un hack mais de l'int et unsigned ont la même profondeur de bits de sorte que vous pourriez
et la reconvertir en
pour être sur le côté sûr, sur votre plaftform
ou de l'utilisation de la largeur spécifique