MariaDB 在插入 UUID 触发器之前

zer*_*ro0 3 sql uuid triggers mariadb

我在 Windows 64 平台上使用MariaDB 5.5.29 。我创建了这个表:

\n\n
CREATE TABLE DM_COUNTRIES\n(\n    COUNTRY_UUID BINARY(16) NOT NULL,\n    C_NAME VARCHAR(255) NOT NULL UNIQUE,\n    C_LOCALNAME VARCHAR(255) DEFAULT NULL,\n    C_COUNTRYCODE VARCHAR(255) DEFAULT NULL,\n    PRIMARY KEY (COUNTRY_UUID)\n)\nENGINE=InnoDB;\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在我想确保,如果未提供 UUID(将成为主键),则会自动插入。因此,我创建了这个触发器:

\n\n
DELIMITER |\nCREATE TRIGGER TRIG_BI_DM_COUNTRIES\nBEFORE INSERT ON DM_COUNTRIES\nFOR EACH ROW\nBEGIN\n    IF NEW.COUNTRY_UUID IS NULL THEN\n        SET NEW.COUNTRY_UUID = UUID();\n    END IF;\nEND|\nDELIMITER ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

为了确保一切都已提交(即使架构更改不需要它):

\n\n
COMMIT;\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,当我尝试插入新行时:

\n\n
INSERT INTO DM_COUNTRIES\n    (C_NAME, C_LOCALNAME, C_COUNTRYCODE)\nVALUES\n    ('Gro\xc3\x9fbritannien', 'Great Britain', 'UK');\n
Run Code Online (Sandbox Code Playgroud)\n\n

我希望触发器将新的 UUID 放置到位,然后成功插入到表中。但发生的事情是这样的:

\n\n
错误代码:1364。字段“COUNTRY_UUID”没有默认值
\n\n

这绝对是正确的答案,因为我没有提供 UUID。触发器应该自动填充它。

\n\n

我尝试使用 unhex 来制定触发器,只是为了确保生成的值适合该字段:

\n\n
DELIMITER |\nCREATE TRIGGER TRIG_BI_DM_COUNTRIES\nBEFORE INSERT ON DM_COUNTRIES\nFOR EACH ROW\nBEGIN\n    IF NEW.COUNTRY_UUID IS NULL THEN\n        SET NEW.COUNTRY_UUID = UNHEX(REPLACE(UUID(), '-', ''));\n    END IF;\nEND|\nDELIMITER ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果还是一样。

\n\n

问题是:我做错了什么?

\n

ype*_*eᵀᴹ 5

我认为问题在于该列没有定义默认值 - 我们不能输入它,DEFAULT NULL因为它是主键。

\n\n

尝试在列定义中添加一个DEFAULT 0值并将触发器内的条件更改为IF NEW.COUNTRY_UUID = 0 THEN

\n\n
DELIMITER |\n\nCREATE TABLE DM_COUNTRIES\n(\n    COUNTRY_UUID BINARY(16) NOT NULL DEFAULT 0,         -- changed here\n    C_NAME VARCHAR(255) NOT NULL UNIQUE,\n    C_LOCALNAME VARCHAR(255) DEFAULT NULL,\n    C_COUNTRYCODE VARCHAR(255) DEFAULT NULL,\n    PRIMARY KEY (COUNTRY_UUID)\n)\nENGINE=InnoDB |\n\n\nCREATE TRIGGER TRIG_BI_DM_COUNTRIES\nBEFORE INSERT ON DM_COUNTRIES\nFOR EACH ROW\nBEGIN\n    IF NEW.COUNTRY_UUID = 0 THEN                        -- and here\n        SET NEW.COUNTRY_UUID = UUID();\n    END IF;\nEND |\n\nINSERT INTO DM_COUNTRIES\n    (C_NAME, C_LOCALNAME, C_COUNTRYCODE)\nVALUES\n    (\'Gro\xc3\x9fbritannien\', \'Great Britain\', \'UK\') |\n\nDELIMITER ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

在SQL-Fiddle上测试(在 MySQL 5.5 上,没有可用的 MariaDB 实例)

\n