2017-10-02 2 views
0

Lorsque vous essayez d'insérer des valeurs dans une colonne BIT (64) en utilisant les commandes préparées MySQLi, je reçois l'erreur (sur l'exécution):Insertion BIT (M) Les valeurs de la colonne à MySQL5.7 avec PHP7 MySQLi déclarations préparées

données trop long pour la colonne 'bits64' à la ligne 1

Voici mon code:

if ($Segments[0] == 'yes') {$bitmask = '1';}else{$bitmask = '0';} 
if ($Segments[1] == 'yes') {$bitmask = $bitmask.'1';}else{$bitmask = $bitmask.'0';} 
... 
if ($Segments[63] == 'yes') {$bitmask = $bitmask.'1';}else{$bitmask = $bitmask.'0';} 

$Upload = $conn->prepare("INSERT INTO `testtable` (`bits64`) VALUES (?)"); 
$Upload->bind_param("s", $bitmask); 
$Upload->execute(); 

Le code fournit une chaîne de 64 caractères. Si j'utilise PHPMyAdmin pour insérer la même sortie, il fonctionne avec succès et ressemble à ceci:

INSERT INTO `testtable` (`bits64`) VALUES (b'0000000000000000000000000000000000000000000000000000000000000000'); 
INSERT INTO `testtable` (`bits64`) VALUES (b'1111111111111111111111111111111111111111111111111111111111111111'); 

La seule chose qui a montré une « réussite » (* pas vraiment) est en train de changer le type de liaison à un nombre entier. Mais il semble qu'il soit traité comme un nombre entier qui devrait être converti en binaire, car il donne la même erreur avec les indicateurs de bit mis à 1.

D'autres choses que j'ai essayé comprennent le formatage $bitmask comme:

$bitmask = "b'".$bitmask."'"; 
$bitmask = "0b".$bitmask; 
// And others 

Pour autant que je sache, les seuls types de bind_param sont entier, chaîne, double et blob. Je suppose qu'il envoie les valeurs comme '101010' (échantillon de code), 101010 (comme nombre entier), 'b'101010'', et '0b101010', respectueusement; cependant, ce qui est nécessaire est b'101010'.

Pour des raisons de rapidité et de sécurité (d'autres champs), je dois utiliser des instructions préparées.

J'ai d'abord utilisé BIGINT pour cela, mais il est apparu que des erreurs d'arrondi se produisaient lorsque la plupart des indicateurs étaient définis.

Je pense que le mode strict de MySQL est désactivé. Mon remplacement est soit un grand nombre de colonnes TINYINT ou CHAR (64), mais je préfère un stockage plus efficace.

Il existe quelques questions connexes sur ce site, mais la plupart concernent des champs à un seul bit, où un entier 0 ou 1 est plus facilement corrélé au bit unique. Je devrais être très reconnaissant de tout conseil ou des solutions.

EDIT

j'ai réalisé que je n'avais pas SQL-mode complètement vide. Une fois le mode SQL est une chaîne vide, il n'y a pas d'erreurs mais je reçois 0111111111111111111111111111111111111111111111111111111111111111, peu importe ce que j'essaie.

EDIT 2

Insertion via phpMyAdmin avec les 1 drapeaux fixés donne également 0111111111111111111111111111111111111111111111111111111111111111, il doit y avoir d'autres problèmes avec la façon dont j'ai cette colonne configurée. J'utilise Ubuntu 16.04, version du serveur: 5.7.19, version PHP: 7.0.22.

Répondre

0

peut-être essayer

$Upload = $conn->prepare("INSERT INTO `testtable` (`bits64`) VALUES (b?)"); 

mais il ne me surprendrait pas si les déclarations préparées ne soutient pas vraiment bitfields du tout ..

Pour des raisons de rapidité et de sécurité (d'autres champs), je dois utiliser les instructions préparées .

vous ne le faites pas. ce serait tout aussi sûr:

if(strlen(rtrim($bitmask,'01'))!==0){throw new \RuntimeException('illegal characters found in bitmask!');} 
$conn->query('INSERT INTO `testtable` (`bits64`) VALUES (b\''.$bitmask.'\')'); 

et je vous assure que l'impact sur les performances sera absolument minime, la référence.

+0

Hanshenrik ... merci pour la réponse rapide. J'ai oublié de mentionner, j'ai essayé cela au début mais j'ai eu une erreur fatale à bind_param (c'est-à-dire que la ligne de préparation était mauvaise). Je pourrais faire quelque chose de mal, cependant. – Justin