資料類型規格可以有明確或隱含的預設值。
資料類型規格中的 DEFAULT
子句明確指出欄的預設值。範例value
CREATE TABLE t1 (
i INT DEFAULT -1,
c VARCHAR(10) DEFAULT '',
price DOUBLE(16,2) DEFAULT 0.00
);
SERIAL DEFAULT VALUE
是一種特殊情況。在整數欄的定義中,它是 NOT NULL AUTO_INCREMENT UNIQUE
的別名。
如下所述,明確 DEFAULT
子句處理的某些方面與版本相關。
DEFAULT
子句中指定的預設值可以是文字常數或表達式。除了一個例外,請將表達式預設值括在括號內,以將它們與文字常數預設值區分開。範例
CREATE TABLE t1 (
-- literal defaults
i INT DEFAULT 0,
c VARCHAR(10) DEFAULT '',
-- expression defaults
f FLOAT DEFAULT (RAND() * RAND()),
b BINARY(16) DEFAULT (UUID_TO_BIN(UUID())),
d DATE DEFAULT (CURRENT_DATE + INTERVAL 1 YEAR),
p POINT DEFAULT (Point(0,0)),
j JSON DEFAULT (JSON_ARRAY())
);
例外情況是,對於 TIMESTAMP
和 DATETIME
欄,您可以將 CURRENT_TIMESTAMP
函數指定為預設值,而無需加上括號。請參閱 第 13.2.5 節「TIMESTAMP 和 DATETIME 的自動初始化和更新」。
只有在將值寫成表達式時,才能將預設值指派給 BLOB
、TEXT
、GEOMETRY
和 JSON
資料類型,即使表達式值是文字
這是允許的 (以表達式指定文字預設值)
CREATE TABLE t2 (b BLOB DEFAULT ('abc'));
這會產生錯誤 (文字預設值未指定為表達式)
CREATE TABLE t2 (b BLOB DEFAULT 'abc');
表達式預設值必須遵守下列規則。如果表達式包含不允許的結構,則會發生錯誤。
允許使用文字、內建函數 (確定性和不確定性) 和運算子。
不允許使用子查詢、參數、變數、儲存函數和可載入函數。
表達式預設值不能依賴於具有
AUTO_INCREMENT
屬性的欄。一個欄的表達式預設值可以參考其他表格欄,但例外情況是,對產生的欄或具有表達式預設值的欄的參考必須是指表格定義中較早出現的欄。也就是說,表達式預設值不能包含對產生的欄或具有表達式預設值的欄的前向參考。
排序限制也適用於使用
ALTER TABLE
來重新排序表格欄。如果產生的表格會有一個包含對產生的欄或具有表達式預設值的欄的前向參考的表達式預設值,則陳述式會失敗。
如果表達式預設值的任何元件依賴於 SQL 模式,則在所有使用期間 SQL 模式都相同的情況下,表格的不同使用可能會發生不同的結果。
對於 CREATE TABLE ... LIKE
和 CREATE TABLE ... SELECT
,目的地表格會保留原始表格中的表達式預設值。
如果表達式預設值參考不確定性函數,則任何導致評估表達式的陳述式對於基於陳述式的複寫都是不安全的。這包括諸如 INSERT
和 UPDATE
等陳述式。在這種情況下,如果停用二進位記錄,則會正常執行陳述式。如果啟用二進位記錄且 binlog_format
設定為 STATEMENT
,則會記錄並執行陳述式,但會將警告訊息寫入錯誤記錄,因為複本可能會發散。當 binlog_format
設定為 MIXED
或 ROW
時,會正常執行陳述式。
當插入新列時,可以使用省略欄名稱或將欄指定為 DEFAULT
(就像具有文字預設值的欄一樣) 的方式來插入具有表達式預設值的欄的預設值
mysql> CREATE TABLE t4 (uid BINARY(16) DEFAULT (UUID_TO_BIN(UUID())));
mysql> INSERT INTO t4 () VALUES();
mysql> INSERT INTO t4 () VALUES(DEFAULT);
mysql> SELECT BIN_TO_UUID(uid) AS uid FROM t4;
+--------------------------------------+
| uid |
+--------------------------------------+
| f1109174-94c9-11e8-971d-3bf1095aa633 |
| f110cf9a-94c9-11e8-971d-3bf1095aa633 |
+--------------------------------------+
但是,只有具有文字預設值的欄才允許使用 DEFAULT(
來指定具名欄的預設值,而具有表達式預設值的欄則不允許。col_name
)
並非所有儲存引擎都允許表達式預設值。對於不允許的儲存引擎,會發生 ER_UNSUPPORTED_ACTION_ON_DEFAULT_VAL_GENERATED
錯誤。
如果預設值評估為與宣告的欄類型不同的資料類型,則會根據通常的 MySQL 類型轉換規則,將其隱含強制轉換為宣告的類型。請參閱 第 14.3 節「表達式評估中的類型轉換」。
如果資料類型規格未包含明確的 DEFAULT
值,MySQL 會依照下列方式決定預設值:
如果欄位可以接受 NULL
值,則該欄位會定義為具有明確的 DEFAULT NULL
子句。
如果欄位不能接受 NULL
值,MySQL 會定義該欄位時不使用明確的 DEFAULT
子句。
對於一個沒有明確 DEFAULT
子句的 NOT NULL
欄位進行資料輸入時,如果 INSERT
或 REPLACE
陳述式未包含該欄位的值,或者 UPDATE
陳述式將該欄位設定為 NULL
,MySQL 會根據當時生效的 SQL 模式來處理該欄位。
如果啟用了嚴格 SQL 模式,則交易式表格會發生錯誤,並且陳述式會回滾。對於非交易式表格,會發生錯誤,但如果此情況發生在多行陳述式的第二行或後續行中,則會插入前面的行。
如果未啟用嚴格模式,MySQL 會將欄位設定為該欄位資料類型的隱含預設值。
假設表格 t
的定義如下:
CREATE TABLE t (i INT NOT NULL);
在此情況下,i
沒有明確的預設值,因此在嚴格模式下,下列每個陳述式都會產生錯誤,且不會插入任何列。當未使用嚴格模式時,只有第三個陳述式會產生錯誤;前兩個陳述式會插入隱含預設值,但第三個陳述式會失敗,因為 DEFAULT(i)
無法產生值。
INSERT INTO t VALUES();
INSERT INTO t VALUES(DEFAULT);
INSERT INTO t VALUES(DEFAULT(i));
對於指定的表格,SHOW CREATE TABLE
陳述式會顯示哪些欄位具有明確的 DEFAULT
子句。
隱含預設值定義如下:
對於數值類型,預設值為
0
,但使用AUTO_INCREMENT
屬性宣告的整數或浮點數類型除外,其預設值為序列中的下一個值。對於
TIMESTAMP
以外的日期和時間類型,預設值是該類型適用的 「零」值。如果啟用了explicit_defaults_for_timestamp
系統變數(請參閱 第 7.1.8 節,「伺服器系統變數」),對於TIMESTAMP
也是如此。否則,對於表格中的第一個TIMESTAMP
欄位,預設值為目前的日期和時間。請參閱 第 13.2 節,「日期和時間資料類型」。