无法将存储列添加到 MariaDB 10.7.3,臭名昭著 "Error Code 1901"
Can't add a STORED column to MariaDB 10.7.3, Infamous "Error Code 1901"
我正在尝试将 GENERATED ALWAYS 列添加到 table,这会将两个字符解码为 DATE
。
它包含一个函数(返回 DATE
),但当表达式被内联时,它的行为方式相同。该函数在 SELECT 中运行良好。我已经检查了我的字符集和排序规则的一致性。
sql_mode 是“ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”
这是 table 架构。请注意,我有一个 Location
生成的列,它工作正常。
CREATE TABLE `Photo_Gear_Date_Codes` (
`ID` varchar(4) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL DEFAULT '....',
`Location` varchar(253) GENERATED ALWAYS AS (case left(`ID`,2) when 'TN' then 'Tatsuno, Hyogo' else 'Unknown' end) STORED,
`Note` varchar(1022) COLLATE latin1_general_ci DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
这是我为简化事情而定义的函数,尽管我在内联这段代码时遇到了同样的错误:
CREATE DEFINER=`root`@`127.0.0.1`
FUNCTION `Date_from_OM_date_code`(id3 char(1), id4 char(1))
RETURNS date
DETERMINISTIC
COMMENT 'Decode the last two digits of a four-character OM date code.'
RETURN CONVERT(
concat(
case ID3
when '1' then '1971'
when '2' then '1972'
when '3' then '1973'
when '4' then '1974'
when '5' then '1975'
when '6' then '1976'
when '7' then '1977'
when '8' then '1978'
when '9' then '1979'
when '0' then '1980'
when 'A' then '1981'
when 'B' then '1982'
when 'C' then '1983'
when 'D' then '1984'
when 'E' then '1985'
when 'F' then '1986'
when 'G' then '1987'
when 'H' then '1988'
when 'I' then '1989'
when 'J' then '1990'
when 'K' then '1991'
when 'L' then '1992'
when 'M' then '1993'
when 'N' then '1994'
when 'O' then '1995'
when 'P' then '1996'
when 'Q' then '1997'
when 'R' then '1998'
when 'S' then '1999'
when 'T' then '2000'
when 'U' then '2001'
when 'V' then '2002'
when 'W' then '2003'
when 'X' then '2004'
when 'Y' then '2005'
when 'Z' then '2006'
end,
case ID4
when '1' then '-01-00'
when '2' then '-02-00'
when '3' then '-03-00'
when '4' then '-04-00'
when '5' then '-05-00'
when '6' then '-06-00'
when '7' then '-07-00'
when '8' then '-08-00'
when '9' then '-09-00'
when 'A' then '-10-00'
when 'B' then '-11-00'
when 'C' then '-12-00'
when 'X' then '-10-00'
when 'Y' then '-11-00'
when 'Z' then '-12-00'
end), DATE);
以下是我尝试添加生成的列的方式:
USE `Personal`;
ALTER TABLE `Photo_Gear_Date_Codes` ADD COLUMN `Date` DATE AS
(Date_from_OM_date_code(SUBSTR(`ID`,3,1), RIGHT(`ID`,1))) STORED;
SELECT ID,
`Location`,
Date_from_OM_date_code(SUBSTR(`ID`,3,1), RIGHT(`ID`,1)) `Date`
FROM Photo_Gear_Date_Codes
当我执行这三个语句时,第二个抛出 1901 错误代码:
Function or expression 'Date_from_OM_date_code
()' cannot be used in
the GENERATED ALWAYS AS clause of Date
Error code 1901.
但我继续解决错误,SELECT
工作正常!
ID
Location
Date
S7Y
Unknown
1977-11-00
TND1
Tatsuno, Hyogo
1984-01-00
TND4
Tatsuno, Hyogo
1984-04-00
TNGB
Tatsuno, Hyogo
1987-11-00
TNH9
Tatsuno, Hyogo
1988-09-00
TNI5
Tatsuno, Hyogo
1989-05-00
TNJ2
Tatsuno, Hyogo
1990-02-00
TNJ3
Tatsuno, Hyogo
1990-03-00
TNJ5
Tatsuno, Hyogo
1990-05-00
TNM6
Tatsuno, Hyogo
1993-06-00
TNM9
Tatsuno, Hyogo
1993-09-00
TNOA
Tatsuno, Hyogo
1995-10-00
看起来它应该有用……我正在为这个而烦恼!
提前感谢您指出我的愚蠢之处! :-)
正如 mariadb 在 generated column 上的文档所说:
This expression might generate the value based on the values of other columns in the table, or it might generate the value by calling built-in functions or user-defined functions (UDFs).
UDF 是用 c++ 编写的函数,而不是 sql。如您所见,标准的 sql-based 用户创建的函数未包含在列表中,因此出现错误消息。
改为将函数体作为表达式包含在生成的列代码中。
我正在尝试将 GENERATED ALWAYS 列添加到 table,这会将两个字符解码为 DATE
。
它包含一个函数(返回 DATE
),但当表达式被内联时,它的行为方式相同。该函数在 SELECT 中运行良好。我已经检查了我的字符集和排序规则的一致性。
sql_mode 是“ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”
这是 table 架构。请注意,我有一个 Location
生成的列,它工作正常。
CREATE TABLE `Photo_Gear_Date_Codes` (
`ID` varchar(4) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL DEFAULT '....',
`Location` varchar(253) GENERATED ALWAYS AS (case left(`ID`,2) when 'TN' then 'Tatsuno, Hyogo' else 'Unknown' end) STORED,
`Note` varchar(1022) COLLATE latin1_general_ci DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
这是我为简化事情而定义的函数,尽管我在内联这段代码时遇到了同样的错误:
CREATE DEFINER=`root`@`127.0.0.1`
FUNCTION `Date_from_OM_date_code`(id3 char(1), id4 char(1))
RETURNS date
DETERMINISTIC
COMMENT 'Decode the last two digits of a four-character OM date code.'
RETURN CONVERT(
concat(
case ID3
when '1' then '1971'
when '2' then '1972'
when '3' then '1973'
when '4' then '1974'
when '5' then '1975'
when '6' then '1976'
when '7' then '1977'
when '8' then '1978'
when '9' then '1979'
when '0' then '1980'
when 'A' then '1981'
when 'B' then '1982'
when 'C' then '1983'
when 'D' then '1984'
when 'E' then '1985'
when 'F' then '1986'
when 'G' then '1987'
when 'H' then '1988'
when 'I' then '1989'
when 'J' then '1990'
when 'K' then '1991'
when 'L' then '1992'
when 'M' then '1993'
when 'N' then '1994'
when 'O' then '1995'
when 'P' then '1996'
when 'Q' then '1997'
when 'R' then '1998'
when 'S' then '1999'
when 'T' then '2000'
when 'U' then '2001'
when 'V' then '2002'
when 'W' then '2003'
when 'X' then '2004'
when 'Y' then '2005'
when 'Z' then '2006'
end,
case ID4
when '1' then '-01-00'
when '2' then '-02-00'
when '3' then '-03-00'
when '4' then '-04-00'
when '5' then '-05-00'
when '6' then '-06-00'
when '7' then '-07-00'
when '8' then '-08-00'
when '9' then '-09-00'
when 'A' then '-10-00'
when 'B' then '-11-00'
when 'C' then '-12-00'
when 'X' then '-10-00'
when 'Y' then '-11-00'
when 'Z' then '-12-00'
end), DATE);
以下是我尝试添加生成的列的方式:
USE `Personal`;
ALTER TABLE `Photo_Gear_Date_Codes` ADD COLUMN `Date` DATE AS
(Date_from_OM_date_code(SUBSTR(`ID`,3,1), RIGHT(`ID`,1))) STORED;
SELECT ID,
`Location`,
Date_from_OM_date_code(SUBSTR(`ID`,3,1), RIGHT(`ID`,1)) `Date`
FROM Photo_Gear_Date_Codes
当我执行这三个语句时,第二个抛出 1901 错误代码:
Function or expression '
Date_from_OM_date_code
()' cannot be used in the GENERATED ALWAYS AS clause ofDate
Error code 1901.
但我继续解决错误,SELECT
工作正常!
ID | Location | Date |
---|---|---|
S7Y | Unknown | 1977-11-00 |
TND1 | Tatsuno, Hyogo | 1984-01-00 |
TND4 | Tatsuno, Hyogo | 1984-04-00 |
TNGB | Tatsuno, Hyogo | 1987-11-00 |
TNH9 | Tatsuno, Hyogo | 1988-09-00 |
TNI5 | Tatsuno, Hyogo | 1989-05-00 |
TNJ2 | Tatsuno, Hyogo | 1990-02-00 |
TNJ3 | Tatsuno, Hyogo | 1990-03-00 |
TNJ5 | Tatsuno, Hyogo | 1990-05-00 |
TNM6 | Tatsuno, Hyogo | 1993-06-00 |
TNM9 | Tatsuno, Hyogo | 1993-09-00 |
TNOA | Tatsuno, Hyogo | 1995-10-00 |
看起来它应该有用……我正在为这个而烦恼!
提前感谢您指出我的愚蠢之处! :-)
正如 mariadb 在 generated column 上的文档所说:
This expression might generate the value based on the values of other columns in the table, or it might generate the value by calling built-in functions or user-defined functions (UDFs).
UDF 是用 c++ 编写的函数,而不是 sql。如您所见,标准的 sql-based 用户创建的函数未包含在列表中,因此出现错误消息。
改为将函数体作为表达式包含在生成的列代码中。