我想做这样的事情:
create table app_users
(
app_user_id smallint(6) not null auto_increment primary key,
api_key char(36) not null default uuid()
);
但是这会导致错误,有没有办法在mysql中调用函数作为默认值?
感谢。
答案 0 :(得分:114)
不,你不能。
但是,您可以轻松创建触发器来执行此操作,例如:
CREATE TRIGGER before_insert_app_users BEFORE INSERT ON app_users FOR EACH ROW SET new.api_key = uuid();
答案 1 :(得分:19)
如前所述,你不能。
如果要模拟此行为,可以使用以下方式触发:
CREATE TRIGGER before_insert_app_users
BEFORE INSERT ON app_users
FOR EACH ROW
IF new.uuid IS NULL
THEN
SET new.uuid = uuid();
END IF;
您仍然需要更新以前存在的行,如下所示:
UPDATE app_users SET uuid = (SELECT uuid());
答案 2 :(得分:10)
从mysql v8.0.13开始,可以使用表达式作为字段的默认值:
DEFAULT子句中指定的默认值可以是文字常量或表达式。除了一个例外,将表达式默认值放在括号内,以将它们与文字常量默认值区分开。
CREATE TABLE t1 (
uuid_field VARCHAR(32) DEFAULT (uuid()),
binary_uuid BINARY(16) DEFAULT (UUID_TO_BIN(UUID()))
);
答案 3 :(得分:8)
不幸的是,不需要,MySQL 5需要常量作为默认值。在下面的链接中更详细地讨论了该问题。但唯一的答案是允许null并添加表触发器。
MySQL最近才接受UUID作为其数据库包的一部分,并不像我们想要的那样功能丰富。
答案 4 :(得分:6)
我相信you can't:
默认值必须是常量;它不能是函数或表达式
答案 5 :(得分:0)
我不确定以上答案是否适用于旧版本,但是我看到可以使用unhex()函数执行此操作。我试过了,它有效。 (玛丽亚数据库版本10.2)
您可以
.... column_name binary(16) not null default unhex(replace(uuid(),'-',''))
,并且有效。要查看uuid,只需执行hex(column_name)。
答案 6 :(得分:0)
请注意,MySQL的UUID()
返回CHAR(36)
,并且将UUID作为文本存储(如其他答案所示)显然效率低下。相反,该列应为BINARY(16)
,并且在插入数据时可以使用UUID_TO_BIN()
,而在读回数据时可以使用BIN_TO_UUID()
。
CREATE TABLE app_users
(
app_user_id SMALLINT(6) NOT NULL AUTO_INCREMENT PRIMARY KEY,
api_key BINARY(16)
);
CREATE TRIGGER before_insert_app_users
BEFORE INSERT ON app_users
FOR EACH ROW
IF new.api_key IS NULL
THEN
SET new.api_key = UUID_TO_BIN(UUID());
END IF;
请注意,由于MySQL并不真正知道这是一个UUID,因此很难以二进制形式存储它的问题。本文介绍了如何创建一个生成的列,该列将根据需要将UUID转换为文本,而不会占用任何空间或担心保持单独的二进制版本和文本版本同步:https://mysqlserverteam.com/storing-uuid-values-in-mysql-tables/
答案 7 :(得分:0)
从10.2.1版开始的MariaDB中,您可以。参见its documentation。
CREATE TABLE test ( uuid BINARY(16) PRIMARY KEY DEFAULT unhex(replace(uuid(),'-','')) );
INSERT INTO test () VALUES ();
SELECT * FROM test;