Pour faire court, j'ai un fichier SQL que je veux importer en tant que fichier de style skel
, donc cela se fera à plusieurs reprises, par programme. Je peux modifier le fichier SQL comme je le souhaite, mais je préfère ne pas toucher l'application elle-même.
Cette application utilise userid = 0
pour représenter l'utilisateur anonyme. Il a également une entrée pertinente (vide) dans la base de données pour représenter cet "utilisateur". Par conséquent, la ligne dans mon skel.sql
ressemble à ceci:
INSERT INTO `{{TABLE_PREFIX}}users` VALUES (0, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, 0, NULL, '', '', '', NULL);
Le problème est que uid
est un auto_increment
champ, pour lequel, techniquement, 0
est une valeur non valide. Ou du moins, si vous le définissez sur 0, vous dites essentiellement à MySQL: "Veuillez insérer l'ID suivant dans ce champ."
Maintenant, je suppose que je pourrais mettre une INSERT
puis une requête UPDATE
dans mon fichier SQL, mais existe-t-il un moyen de dire à MySQL en général que oui, je veux réellement insérer 0
dans ce domaine?
D'après la réponse que j'ai obtenue ici :
Vous pouvez utiliser:
SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'
Ce qui, comme décrit ici , empêchera MySQL d'interpréter un ID INSERT/UPDATE de 0 comme étant le prochain ID de séquence. Un tel comportement sera limité à NULL.
C'est ce que je considérerais comme un comportement assez mauvais de l'application. Vous devrez faire très attention à ce qu'il soit utilisé de manière cohérente, surtout si vous choisissez d'implémenter la réplication à une date ultérieure.
Vérifiez votre mode sql DB avec:
SELECT @@[GLOBAL|SESSION].sql_mode;
S'il est vide ou non défini, utilisez:
SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'
FAITES ATTENTION! Si vous utilisez GLOBAL
, ce n'est pas un changement immédiat, vous devez redémarrer votre connexion pour appliquer le paramètre.
Ainsi, si vous restaurez des données d'une base de données à une autre, par exemple, et que vous n'êtes pas sûr si ce paramètre est appliqué, utilisez SESSION
pour un changement immédiat (il se réinitialise à la fermeture de la connexion). Une fois terminé, insérez la valeur 0 et elle ne changera pas même si le sql_mode
est changé.
Pour réinitialiser ce mode (et d'autres), utilisez
SET [GLOBAL|SESSION] sql_mode=''
Les valeurs zéro auto-incrémentées ne sont pas recommandées car elles ne sont pas définies par défaut dans les bases de données MySQL.
Pour plus d'informations, vérifiez sujet de la page de développement mysql sur ce
Mise à jour
Pour MariaDB, utilisez la commande indiquée dans ce commentaire
SET sql_mode='NO_AUTO_VALUE_ON_ZERO'
Si vous ne voulez pas traiter les variables mysql, voici un hack utile:
INSERT INTO `{{TABLE_PREFIX}}users` VALUES (-1, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, 0, NULL, '', '', '', NULL);
Et alors
UPDATE `{{TABLE_PREFIX}}users` SET id = 0 where id = -1;
Évidemment, cela suppose que vous utilisez un entier signé et que vous n'utilisez pas de valeurs négatives pour vos identifiants de table.
Manière sûre:
SET @@session.sql_mode =
CASE WHEN @@session.sql_mode NOT LIKE '%NO_AUTO_VALUE_ON_ZERO%'
THEN CASE WHEN LENGTH(@@session.sql_mode)>0
THEN CONCAT_WS(',',@@session.sql_mode,'NO_AUTO_VALUE_ON_ZERO') -- added, wasn't empty
ELSE 'NO_AUTO_VALUE_ON_ZERO' -- replaced, was empty
END
ELSE @@session.sql_mode -- unchanged, already had NO_AUTO_VALUE_ON_ZERO set
END