簡単に言えば、skel
スタイルのファイルとしてインポートしたいSQLファイルがあるので、これはプログラムによって繰り返し実行されます。必要に応じてSQLファイルを編集できますが、アプリケーション自体には触れたくないです。
このアプリケーションではuserid = 0
は、匿名ユーザーを表します。また、データベースには、この「ユーザー」を表す関連する(空白の)エントリがあります。したがって、私のskel.sql
は次のようになります。
INSERT INTO `{{TABLE_PREFIX}}users` VALUES (0, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, 0, NULL, '', '', '', NULL);
これの問題は、uid
がauto_increment
フィールド、技術的には、0
は無効な値です。または、少なくとも0に設定すると、基本的にMySQLに「次のIDをこのフィールドに挿入してください」と伝えます。
今、私はINSERT
クエリをUPDATE
クエリをSQLファイルに入れることができると思いますが、MySQLに、はい、実際に0
このフィールドに?
以下を使用して、SQL DBモードを確認します。
SELECT @@[GLOBAL|SESSION].sql_mode;
空または設定されていない場合は、次を使用します。
SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'
注意してください! GLOBAL
を使用する場合、すぐに変更されるわけではないため、接続を再起動して設定を適用する必要があります。
たとえば、あるDBから別のDBにデータを復元する場合、この設定が適用されるかどうかわからない場合は、SESSION
を使用して即時変更(接続を閉じるとリセットされます)。完了したら、値0を挿入します。sql_mode
が変更されます。
このモード(およびその他)をリセットするには
SET [GLOBAL|SESSION] sql_mode=''
ゼロの自動インクリメント値は、MySQLデータベースでデフォルトとして設定されていないためお勧めしません。
詳細情報については mysql dev page topic this
更新
MariaDBの場合は、 this comment で指摘されているコマンドを使用します
SET sql_mode='NO_AUTO_VALUE_ON_ZERO'
Mysql変数を処理したくない場合、便利なハックを次に示します。
INSERT INTO `{{TABLE_PREFIX}}users` VALUES (-1, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, 0, NULL, '', '', '', NULL);
その後
UPDATE `{{TABLE_PREFIX}}users` SET id = 0 where id = -1;
明らかに、これは符号付き整数を使用しており、テーブルIDに負の値を使用していないことを前提としています。
フェイルセーフ方法:
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