文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  資料類型  /  資料類型預設值

13.6 資料類型預設值

資料類型規格可以有明確或隱含的預設值。

資料類型規格中的 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())
);

例外情況是,對於 TIMESTAMPDATETIME 欄位,您可以將 CURRENT_TIMESTAMP 函數指定為預設值,而無需括在括號中。請參閱 第 13.2.5 節,「TIMESTAMP 和 DATETIME 的自動初始化和更新」

BLOBTEXTGEOMETRYJSON 資料類型只能在值寫為運算式時才可被指定為預設值,即使運算式值是常值也是如此。

  • 這是允許的(常值預設值指定為運算式)

    CREATE TABLE t2 (b BLOB DEFAULT ('abc'));
  • 這會產生錯誤(常值預設值未指定為運算式)

    CREATE TABLE t2 (b BLOB DEFAULT 'abc');

運算式預設值必須遵守下列規則。如果運算式包含不允許的結構,就會發生錯誤。

  • 允許使用常值、內建函數(確定性和非確定性)和運算子。

  • 不允許使用子查詢、參數、變數、儲存函數和可載入函數。

  • 運算式預設值不能取決於具有 AUTO_INCREMENT 屬性的欄位。

  • 一個欄位的運算式預設值可以參考其他表格欄位,但參考產生的欄位或具有運算式預設值的欄位必須是參考表格定義中較早出現的欄位。也就是說,運算式預設值不能包含對產生欄位或具有運算式預設值的欄位的前向參考。

    排序限制也適用於使用 ALTER TABLE 來重新排序表格欄位。如果產生的表格具有包含對產生欄位或具有運算式預設值的欄位的前向參考的運算式預設值,則陳述式會失敗。

注意

如果運算式預設值的任何元件取決於 SQL 模式,除非在所有使用期間 SQL 模式都相同,否則表格的不同使用可能會產生不同的結果。

對於 CREATE TABLE ... LIKECREATE TABLE ... SELECT,目的地表格會保留原始表格的運算式預設值。

如果運算式預設值參考非確定性函數,則任何導致運算式被評估的陳述式對於以陳述式為基礎的複寫都是不安全的。這包括諸如 INSERTUPDATE 等陳述式。在此情況下,如果二進位日誌記錄已停用,則陳述式會照常執行。如果二進位日誌記錄已啟用且 binlog_format 設定為 STATEMENT,則陳述式會被記錄和執行,但會將警告訊息寫入錯誤日誌,因為複本可能會發散。當 binlog_format 設定為 MIXEDROW 時,陳述式會照常執行。

當插入新列時,可以使用省略欄位名稱或將欄位指定為 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 欄位的資料,如果 INSERTREPLACE 陳述式中沒有包含該欄位的值,或是 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));

請參閱 第 7.1.11 節,「伺服器 SQL 模式」

對於給定的資料表,SHOW CREATE TABLE 陳述式會顯示哪些欄位具有明確的 DEFAULT 子句。

隱含預設值的定義如下