SQL列の定義:デフォルト値であり、null冗長ではありませんか?


88

create / alterDDLステートメントの列を定義する次の構文を何度も見てきました。

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault"

問題は、デフォルト値が指定されているため、列がNULLを受け入れないように指定する必要があるかどうかです。言い換えれば、DEFAULTはNOT NULLを冗長にしませんか?

回答:


133

DEFAULT挿入/更新ステートメントに明示的な値がない場合に挿入される値です。DDLにNOT NULL制約がなかったとしましょう。

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT 'MyDefault'

次に、これらのステートメントを発行できます

-- 1. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B) VALUES (NULL, NULL);

-- 2. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, DEFAULT);

-- 3. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B, col) DEFAULT VALUES;

-- 4. This will insert NULL into tbl.col
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, NULL);

または、SQL-1992標準に従ってDEFAULTUPDATEステートメントで使用することもできます

-- 5. This will update 'MyDefault' into tbl.col
UPDATE tbl SET col = DEFAULT;

-- 6. This will update NULL into tbl.col
UPDATE tbl SET col = NULL;

すべてのデータベースがこれらのSQL標準構文のすべてをサポートしているわけではないことに注意してください。NOT NULL制約を追加すると、ステートメント4, 6でエラーが発生します1-3, 5が、それでも有効なステートメントです。だからあなたの質問に答えるために:いいえ、それらは冗長ではありません。


クエリのパフォーマンスに多大な影響があることの説明(おそらくいくつかの数字を含む)を見ることを期待して(あなたのブログ投稿への)あなたのリンクに行きましたが、それが影響を与えると簡単に言い換えただけでした。不快感はありませんが、リンクは少し誤解を招く可能性があります。
セスフラワーズ

@SethFlowers:ポインター、セスに感謝します。リンク先の記事はその間に編集されました。代わりに他の何かをリンクできるかどうか、またはリンクを削除できるかどうかを確認します。今のように、あなたは絶対に正しいです、それはここでの答えに何の価値も加えません。
LukasEder19年

ありがとう-失礼に聞こえなかったといいのですが。私はリンクを見たばかりで、「ええ、それは間違いなく私が読みたいものです」のようでした-それから少しがっかりしました:)。
セスフラワーズ

@SethFlowers:心配ありません。同意します。私の救助のために:私のブログスキルは過去数年間で大幅に向上しました:)
LukasEder19年

19

デフォルト値でも、列データはいつでも。で上書きできますnull

NOT NULLそれがで作成された後に制限は、あなたがその行を更新させませんnull


これは言い換えるべきだと思います。「NOTNULL制限では、null値で作成された後、その行を更新できません」もちろん、NOT NULL列を持つ行は更新できますが、nullとして更新することはできません。その列の値。さらに、行を作成するということは、行を挿入することを意味すると思います。INSERTステートメントは、NOTNULLで指定された列にもNULL値を含めることはできません。
makrom 2017年

4

私のSQLの先生は、DEFAULT値とNOT NULLまたNULLはの両方を指定する場合は、DEFAULT常にNOT NULLまたはの前に表現する必要があると言いましたNULL

このような:

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NOT NULL

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NULL


5
こんにちは、参加していただきありがとうございます。ただし、これは当面の問題に対処するものではなく、両方の順序付けは完全に効果的です。テーブルを手動でスクリプト化する場合は、NULL値とNOT NULL値の位置合わせが適切になるため、最後にデフォルトを設定する方が簡単です。
emragins 2017年

さて、あなたも正しいと思います。私のコースが私の答えに書いたことを明確に述べている理由がわかりません。私の答えが実際には質問に対応していないことは知っていますが、コメントはあまり読みにくいことがわかりました。
タンギーラブラドールルイス2017

3
(主観的な)ベストプラクティスとルールには違いがあります。一貫したスタイルを持つことは悪い考えではありませんが、この特定のケースでは、私は個人的にDEFAULTの前にNOTNULLを好みます。とにかく、答えの代わりにコメントを書くこともできます、これはより適切だったでしょう。
makrom 2017年

それはおそらく質問に答えません。しかし、それはまさに私が探していたものです。ありがとうございました。
うちはサスケ

2

私はそうは言わないでしょう。

列がNULL値を受け入れる場合、フィールドにNULL値を挿入することを止めるものは何もありません。私の知る限り、デフォルト値は新しい行の作成にのみ適用されます。

nullが設定されていない場合、エラーがスローされるため、フィールドにnull値を挿入することはできません。

nullを防ぐためのフェイルセーフメカニズムと考えてください。


2
あなたは「新しいルールの作成」と言いました。「新しい列の作成」と言うつもりでしたか?
bielawski

それがこの質問のより実際的な答えだと思います。
Noman_ibrahim

@bielawskiほぼ8年後、私は:)そのタイプミスを修正するに動き回る
ダークカバ

これは受け入れられた答えでなければなりません。OPは簡単な質問をし、答えは単に「いいえ」です。ただし、ドキュメントには説明と例が必要です。
NicolasHevia20年

0

言い換えれば、DEFAULTはNOT NULLを冗長にしませんか?

いいえ、冗長ではありません。受け入れられた答えを拡張する。カラム用colnull許容の場合、DEFAULTが定義されている場合でも、畏敬の念を起こしてNULLを挿入できます。

CREATE TABLE t(id INT PRIMARY KEY, col INT DEFAULT 10);

-- we just inserted NULL into column with DEFAULT
INSERT INTO t(id, col) VALUES(1, NULL);

+-----+------+
| ID  | COL  |
+-----+------+
|   1 | null |
+-----+------+

Oracleは、このようなシナリオに追加の構文を導入して、デフォルトで明示的なNULLをオーバーライドしました。 DEFAULT ON NULL

CREATE TABLE t2(id INT PRIMARY KEY, col INT DEFAULT ON NULL 10);
-- same as
--CREATE TABLE t2(id INT PRIMARY KEY, col INT DEFAULT ON NULL 10 NOT NULL); 

INSERT INTO t2(id, col) VALUES(1, NULL);

+-----+-----+
| ID  | COL |
+-----+-----+
|  1  |  10 |
+-----+-----+

ここではNULLを挿入しようとしましたが、代わりにデフォルトを取得しました。

db <>フィドルデモ

ON NULL

ON NULL句を指定すると、後続のINSERTステートメントがNULLと評価される値を割り当てようとするときに、OracleDatabaseはDEFAULT列の値を割り当てます。

ON NULLを指定すると、NOTNULL制約とNOTDEFERRABLE制約状態が暗黙的に指定されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.