密钥大小超过了使用 UDF 调用对表达式索引的实现限制

key size exceeds implementation restriction for index on expression with UDF call

Firebird 允许 indexing on expressions 自版本 2.0。这包括调用 用户定义函数 (UDF).

目前,我正在尝试为此添加一个表达式索引 table:

CREATE TABLE M_ADSN_STRING_DATA (
    ID             DMN_AUTOINC NOT NULL /* DMN_AUTOINC = INTEGER NOT NULL */,
    CLTREF         DMN_REFID /* DMN_REFID = INTEGER NOT NULL */,
    ATTRIBUTEDATA  DMN_AFT_STRING /* DMN_AFT_STRING = VARCHAR(320) NOT NULL */
);

/******************************************************************************/
/****                          Unique constraints                          ****/
/******************************************************************************/

ALTER TABLE M_ADSN_STRING_DATA ADD CONSTRAINT UNQ_M_ADSN_STRING_DATA UNIQUE (CLTREF, ATTRIBUTEDATA);


/******************************************************************************/
/****                             Primary keys                             ****/
/******************************************************************************/

ALTER TABLE M_ADSN_STRING_DATA ADD CONSTRAINT PK_M_ADSN_STRING_DATA PRIMARY KEY (ID);


/******************************************************************************/
/****                             Foreign keys                             ****/
/******************************************************************************/

ALTER TABLE M_ADSN_STRING_DATA ADD CONSTRAINT FK_M_ADSN_STRING_DATA_CLT FOREIGN KEY (CLTREF) REFERENCES M_CLIENT (ID) ON DELETE CASCADE ON UPDATE CASCADE;


/******************************************************************************/
/****                               Indices                                ****/
/******************************************************************************/

CREATE INDEX M_ADSN_STRING_DATA_AD_UC ON M_ADSN_STRING_DATA COMPUTED BY (UPPER(ATTRIBUTEDATA));

请注意,它已经有一个名为 M_ADSN_STRING_DATA_AD_UC 的表达式索引。

我要使用的索引应该如下所示:

CREATE INDEX M_ADSN_STRING_DATA_AD_DIG
  ON M_ADSN_STRING_DATA
  COMPUTED BY (F_DIGITS(ATTRIBUTEDATA));

不幸的是,这给了我一条错误消息。

Unsuccessful metadata update key size exceeds implementation restriction for index "M_ADSN_STRING_DATA_AD_DIG"

我也阅读了 Firebird FAQ 条目 #213 and #211, and this SO questionF_DIGITSFreeAdhocUDF 库 的一个 UDF。最初,它被声明为

DECLARE EXTERNAL FUNCTION F_DIGITS
        CSTRING(32760)
RETURNS CSTRING(32760) FREE_IT
ENTRY_POINT 'digits' MODULE_NAME 'FreeAdhocUDF';

由于我的最大输入输出长度只有320个字符,所以我改成了

DECLARE EXTERNAL FUNCTION F_DIGITS
    CSTRING(320)
RETURNS CSTRING(320) FREE_IT
ENTRY_POINT 'digits' MODULE_NAME 'FreeAdhocUDF';

以满足索引大小要求。我的数据库页面大小是 16384。所以,我认为,我的密钥最多可达 4096 字节。

ATTRIBUTEDATA 的域 DMN_AFT_STRING 声明为

CREATE DOMAIN DMN_AFT_STRING AS
VARCHAR(320) CHARACTER SET ISO8859_1
NOT NULL
COLLATE DE_DE_CS_SF;

为什么密钥大小超过了?

长话短说:您是否尝试过将其关闭然后再打开?

看起来必须在更改 UDF 声明之后和添加表达式索引之前断开并连接

现在,它可以正常工作了。密钥大小不再超过