DM 支持用户自定义运算符。创建自定义运算符前需要首先创建一个存储函数,存储函数中需要包含输入参数、运算过程以及返回值,然后便可为该存储函数定义一个运算符。使用自定义运算符时,运算对象将作为存储函数的输入参数,参与存储函数中的运算过程,存储函数的返回值即运算结果。
20.1 创建自定义运算符
语法格式
CREATE OPERATOR [<模式名>.]<运算符名> (FUNCTION [<模式名>.]<函数名>, <运算对象类型>);
<运算对象类型>::=
LEFTARG <左侧对象类型> [, RIGHTARG <右侧对象类型>] |
RIGHTARG <右侧对象类型> [, LEFTARG <左侧对象类型>]
参数
- < 运算符名 > 运算符的名称,长度为 2~63 个字符;
- < 函数名 > 存储函数的名称;
- < 左侧对象类型 > 运算符左侧运算对象的数据类型,为 NULL 表示不存在左侧运算对象;
- < 右侧对象类型 > 运算符右侧运算对象的数据类型,为 NULL 表示不存在右侧运算对象。
图例
创建自定义运算符
语句功能
创建自定义运算符。
使用说明
- 只有拥有 CREATE OPERATOR 或 CREATE ANY OPERATOR 权限的用户可以创建自定义运算符。只有拥有 CREATE ANY OPERATOR 的用户才能在其他模式下创建自定义运算符;
- 自定义运算符至少存在一侧运算对象;
- 运算符名称必须由以下字符组成:“+”、“-”、“*”、“/”、“<”、“>”、“=”、“~”、“!”、“@”、“%”、“^”、“&”、“|”和“`”。其中,“!”不能作为起始字符,“+”、“-”、“~”和“@”不能作为结束字符;
- 运算符名称中不允许使用“--”、“/*”和“//”,因为会被识别为注释;
- 开启 MYSQL 兼容,"`"反引号不能作为运算符名称的字符
- 运算对象的数据类型支持基本数据类型和自定义类型。不支持 %TYPE 和 %ROWTYPE 类型、不支持 INTERVAL 类型、不支持指定精度;
- 部分不同名称的数据类型会被视为同一类型,例如 NUMBER 与 DECIMAL 被视为同一类型,CHAR 和 VARCHAR 不会被视为同一类型;
- 支持重载自定义运算符,即支持创建 < 函数名 > 相同,但 < 运算对象类型 > 不同的多个同名的自定义运算符。其中,< 运算对象类型 > 不同指实际数据类型不同,若仅类型名称不同但实际数据类型相同,则报错;
- 只有拥有 CREATE ANY OPERATOR 权限的用户可以为其他用户创建的运算符创建重载对象;
- 用户可以查询系统表 SYSOPARGS 获取自定义运算符的重载信息;
- 用户可以使用系统函数 OPERATORDEF 获取自定义运算符的定义。
20.2 删除自定义运算符
语法格式
DROP OPERATOR [IF EXISTS] [<模式名>.]<运算符名> (<左侧对象类型>, <右侧对象类型>);
参数
- < 运算符名 > 运算符的名称;
- < 左侧对象类型 > 运算符左侧运算对象的数据类型,为 NULL 表示不存在左侧运算对象;
- < 右侧对象类型 > 运算符右侧运算对象的数据类型,为 NULL 表示不存在右侧运算对象。
图例
删除自定义运算符
语句功能
删除自定义运算符。
使用说明
只有拥有 DROP OPERATOR 和 DROP ANY OPERATOR 权限的用户可删除自己模式下的自定义操作符。只有拥有 DROP ANY OPERATOR 权限的用户才可以删除其他用户模式下的自定义运算符。
20.3 使用自定义运算符
语法格式
左一元运算符: (<left_exp> <运算符名称子句>)
右一元运算符: <运算符名称子句> <right_exp>
二元运算符: <left_exp> <运算符名称子句> <right_exp>
<运算符名称子句>::=
<运算符名> |
OPERATOR([<模式名>.]<运算符名>)
参数
- <left_exp> 左侧运算对象表达式;
- <right_exp> 右侧运算对象表达式;
- < 运算符名称子句 > 可以直接使用运算符名称,也可使用 OPERATOR 子句。若使用 OPERATOR 子句,则指定运算符名称时可以带有模式名或双引号,否则不能带有模式名或双引号。
图例
左一元运算符
右一元运算符
二元运算符
语句功能
使用自定义运算符。
使用说明
自定义运算符的运算优先级低于系统原有的基础运算符。例如:“@^”为自定义二元运算符,则表达式“1+2@^3*4”等价于“(1+2)@^(3*4)”。
20.4 应用实例
例 1 创建一个左一元运算符,并使用该运算符进行计算。
首先在 SYSDBA 模式下创建一个存储函数 FUNC_OPL_TEST。
CREATE FUNCTION FUNC_OPL_TEST(
C IN INT
) RETURN INTEGER
AS
BEGIN
RETURN C*2;
END;
/
在 SYSDBA 模式下,为存储函数 FUNC_OPL_TEST 定义一个左一元运算符“<%”。
CREATE OPERATOR <% (FUNCTION FUNC_OPL_TEST, LEFTARG INT);
使用自定义运算符“<%”进行计算。
SELECT (2<%);
查询结果如下:
行号 2OPERATOR("<%")
---------- ---------------
1 4
以上查询结果为 2*2 的计算结果,结果为 4。
例 2 创建一个右一元运算符,并使用该运算符进行计算。
首先在 SYSDBA 模式下创建一个存储函数 FUNC_OPR_TEST。
CREATE FUNCTION FUNC_OPR_TEST(
C IN VARCHAR
) RETURN INTEGER
AS
BEGIN
RETURN LENGTH(C);
END;
/
在 SYSDBA 模式下,为存储函数 FUNC_OPR_TEST 定义一个右一元运算符“/>”。
CREATE OPERATOR /> (FUNCTION FUNC_OPR_TEST, RIGHTARG VARCHAR);
使用自定义运算符“/>”进行计算。
SELECT />'abc';
查询结果如下:
行号 OPERATOR("/>")'abc'
---------- -------------------
1 3
以上查询结果为运算对象“abc”中的字符个数,结果为 3。
例 3 创建一个二元运算符,并使用该运算符进行计算。
首先在 SYSDBA 模式下创建一个存储函数 FUNC_OP_TEST。
CREATE FUNCTION FUNC_OP_TEST(
C1 IN INT,
C2 IN INT
) RETURN INTEGER
AS
BEGIN
RETURN (C1 + C2) * 2;
END;
/
在 SYSDBA 模式下,为存储函数 FUNC_OP_TEST 定义一个二元运算符“@^”。
CREATE OPERATOR @^ (FUNCTION FUNC_OP_TEST, LEFTARG INT, RIGHTARG INT);
使用自定义运算符“@^”进行计算。
SELECT 2@^3;
查询结果如下:
行号 2OPERATOR("@^")3
---------- ----------------
1 10
以上查询结果为(2+3)*2 的计算结果,结果为 10。
例 4 删除自定义运算符。
删除左一元运算符“<%”。
DROP OPERATOR IF EXISTS <%(INT,NULL);
删除右一元运算符“/>”。
DROP OPERATOR IF EXISTS />(NULL,VARCHAR);
删除二元运算符“@^”。
DROP OPERATOR IF EXISTS @^(INT,INT);