Definizione colonna SQL: valore predefinito e non ridondante null?


88

Ho visto molte volte la seguente sintassi che definisce una colonna in un'istruzione crea / modifica DDL:

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

La domanda è: poiché viene specificato un valore predefinito, è necessario specificare anche che la colonna non deve accettare NULL? In altre parole, DEFAULT non rende NOT NULL ridondante?

Risposte:


133

DEFAULTè il valore che verrà inserito in assenza di un valore esplicito in un'istruzione di inserimento / aggiornamento. Supponiamo che il tuo DDL non avesse il NOT NULLvincolo:

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

Quindi potresti rilasciare queste dichiarazioni

-- 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);

In alternativa, puoi anche usare DEFAULTnelle UPDATEistruzioni, secondo lo standard SQL-1992 :

-- 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;

Nota, non tutti i database supportano tutte queste sintassi standard SQL. L'aggiunta del NOT NULLvincolo causerà un errore con le istruzioni 4, 6, mentre 1-3, 5sono ancora valide le istruzioni. Quindi, per rispondere alla tua domanda: No, non sono ridondanti.


Sono andato al tuo link (al tuo post sul blog) aspettandomi di vedere una spiegazione (possibilmente con alcuni numeri) dell'enorme impatto sulle prestazioni delle query, ma ho visto solo brevemente ribadire che ha un impatto. Senza offesa, ma il collegamento è un po 'fuorviante.
Seth Flowers

@SethFlowers: Grazie per il puntatore, Seth. L'articolo collegato è stato modificato nel frattempo. Vedrò se posso collegare qualcos'altro o rimuovere il collegamento. Così com'è ora, hai assolutamente ragione, non aggiunge alcun valore alla risposta qui.
Lukas Eder

Grazie - spero di non essere sembrato scortese. Ho appena visto il link ed ho pensato "sì, è sicuramente qualcosa che voglio leggere" - poi sono rimasto un po 'deluso :).
Seth Flowers

@SethFlowers: Nessun problema. Sono completamente d'accordo. In mio soccorso: le mie capacità di blogging sono notevolmente migliorate negli ultimi anni :)
Lukas Eder

19

Anche con un valore predefinito, puoi sempre sostituire i dati della colonna con null .

La NOT NULLrestrizione non ti consentirà di aggiornare quella riga dopo che è stata creata con nullvalore


Penso che questo dovrebbe essere riformulato: "La restrizione NOT NULL non ti consentirà di aggiornare quella riga dopo che è stata creata con valore null" Ovviamente le righe con colonne NOT NULL possono essere aggiornate, semplicemente non possono essere aggiornate con null come un valore per quella colonna. Inoltre: presumo che creare una riga significhi inserire una riga. Anche le istruzioni INSERT non possono avere valori nulli per le colonne specificate con NOT NULL.
dal

4

Il mio insegnante di SQL ha detto che se specifichi sia un DEFAULTvalore che NOT NULLo NULL, DEFAULTdovrebbe sempre essere espresso prima di NOT NULLo NULL.

Come questo:

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

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


5
Ciao e grazie per aver partecipato. Tuttavia, questo non risolve la domanda in questione ed entrambi gli ordini sono completamente efficaci. Trovo più facile mettere il valore predefinito alla fine quando scrivo manualmente le tabelle perché i valori NULL e NOT NULL si allineano meglio.
emragins

Ok, immagino che anche tu abbia ragione. Non capisco perché il mio corso dica esplicitamente ciò che ho scritto sulla mia risposta. So che la mia risposta non risponde davvero alla domanda, ma ho scoperto che un commento non sarebbe molto leggibile.
Tanguy Labrador Ruiz

3
C'è una differenza tra le migliori pratiche (soggettive) e le regole. Non è una cattiva idea avere uno stile coerente, ma in questo caso particolare, personalmente preferirei NOT NULL prima di DEFAULT. Indipendentemente da ciò, puoi anche scrivere commenti invece di risposte, questo sarebbe stato più appropriato.
dal

Questo probabilmente non risponde alla domanda. Ma è esattamente quello che stavo cercando. Grazie.
Sasuke Uchiha

2

Direi di no.

Se la colonna accetta valori nulli, non c'è nulla che ti impedisca di inserire un valore nullo nel campo. Per quanto ne so, il valore predefinito si applica solo alla creazione di una nuova riga.

Con non impostato nullo, non è possibile inserire un valore nullo nel campo poiché genererà un errore.

Consideralo come un meccanismo di sicurezza per prevenire i valori nulli.


2
Hai detto "creazione di una nuova regola". Volevi dire "creazione di una nuova riga"?
bielawski

Penso che sia una risposta più pratica a questa domanda.
Noman_ibrahim

@bielawski E quasi 8 anni dopo, riesco a correggere quel refuso :)
Dark Hippo

Questa dovrebbe essere la risposta accettata. OP chiede una semplice domanda e la risposta è semplicemente "no". Tuttavia, la spiegazione e l'esempio sono necessari per la documentazione.
Nicolas Hevia

0

In altre parole, DEFAULT non rende NOT NULL ridondante?

No, non è ridondante. Alla risposta accettata estesa. Per la colonna colche è nullable awe può inserire NULL anche quando DEFAULT è definito:

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 ha introdotto una sintassi aggiuntiva per tale scenario per sostituire il NULL esplicito con l'impostazione predefinita 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 |
+-----+-----+

Qui abbiamo provato a inserire NULL ma ottenere invece il valore predefinito.

db <> fiddle demo

ON NULL

Se si specifica la clausola ON NULL, Oracle Database assegna il valore della colonna DEFAULT quando un'istruzione INSERT successiva tenta di assegnare un valore che restituisce NULL.

Quando si specifica ON NULL, il vincolo NOT NULL e lo stato del vincolo NOT DEFERRABLE vengono specificati in modo implicito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.