web-dev-qa-db-ja.com

有効な自動インクリメント値として0をMySQLに強制させる方法

簡単に言えば、skelスタイルのファイルとしてインポートしたいSQLファイルがあるので、これはプログラムによって繰り返し実行されます。必要に応じてSQLファイルを編集できますが、アプリケーション自体には触れたくないです。

このアプリケーションではuserid = 0は、匿名ユーザーを表します。また、データベースには、この「ユーザー」を表す関連する(空白の)エントリがあります。したがって、私のskel.sqlは次のようになります。

INSERT INTO `{{TABLE_PREFIX}}users` VALUES (0, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, 0, NULL, '', '', '', NULL);

これの問題は、uidauto_incrementフィールド、技術的には、0は無効な値です。または、少なくとも0に設定すると、基本的にMySQLに「次のIDをこのフィールドに挿入してください」と伝えます。

今、私はINSERTクエリをUPDATEクエリをSQLファイルに入れることができると思いますが、MySQLに、はい、実際に0このフィールドに?

72

私が得た答えから ここ

次を使用できます。

SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO'

here で説明したように、MySQLは0のINSERT/UPDATE IDを次のシーケンスIDとして解釈しません。このような動作はNULLに制限されます。

それは私がアプリケーションからかなり悪い動作を考えるものです。特に後日レプリケーションを実装することを選択した場合は、一貫して使用されることに特に注意する必要があります。

89

以下を使用して、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'
26
I.G. Pascual

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に負の値を使用していないことを前提としています。

11
e18r

フェイルセーフ方法:

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
  • NO_AUTO_VALUE_ON_ZEROが既にsql_modeに設定されているかどうかを確認します
  • 空でない場合、sql_modeに追加します
  • セッションのみを設定します。0を挿入する必要があるセッションでのみ使用することをお勧めします
6
Stefan Rogin