§ Oracle兼容-语法-WITH FUNCTION
§ 1. 语法
WITH FUNCTION
<func_name> {<function...>}
SELECT(query_block)
1
2
3
2
3
§ 2. 定义和用法
通过 WITH FUNCTION
子句,可以把很多原本需要存储过程来实现的复杂逻辑用一句SQL来进行表达,使用起来更方便。
相关使用说明如下:
定义的函数的作用域为所在的查询表达式内。
定义的存储函数对象不会存储到系统表中;
定义的存储函数比模式对象的存储函数拥有更高的优先级;
定义的存储函数比本地函数优先级低;
定义函数时不需要
CREATE FUNCTION
权限;无需要求
sql_mode = ORACLE
,只要创建函数时的语法不报错即可;不支持
PREPARE STMT
;函数名不支持
schema_name.func_name
这种格式,只能在当前Schema中创建函数;只支持SELECT子句,不支持其他子句,例如
DELET/UPDATE/MERGE
等。
备注:9点的功能是存储过程中,需清楚地看到函数定义,避免ddl操作开销的需求,暂时未支持,需收集具体使用场景后再进行适配开发
§ 3. 示例
-- 先切换到ORACLE模式
greatsql> SET sql_mode = ORACLE;
greatsql> DELIMITER //
-- 1. 创建函数
greatsql> WITH
FUNCTION f1(c INT) RETURN INT
AS
BEGIN
RETURN c * 10;
END;
SELECT f1(3306) FROM DUAL; //
+----------+
| f1(3306) |
+----------+
| 33060 |
+----------+
1 row in set (0.00 sec)
-- 2. 创建同名函数
greatsql> SELECT LENGTH('GreatSQL') FROM DUAL //
+--------------------+
| LENGTH('GreatSQL') |
+--------------------+
| 8 |
+--------------------+
1 row in set (0.00 sec)
-- 可以创建重名函数,但本地函数优先,可以看到结果并非返回6而是8
greatsql> WITH
FUNCTION LENGTH(c VARCHAR2(50)) RETURN INT
AS
BEGIN
RETURN 6;
END;
SELECT LENGTH('GreatSQL'), INSTR('Hello GreatSQL', 'G') FROM DUAL; //
+--------------------+------------------------------+
| LENGTH('GreatSQL') | INSTR('Hello GreatSQL', 'G') |
+--------------------+------------------------------+
| 8 | 7 |
+--------------------+------------------------------+
1 row in set, 1 warning (0.00 sec)
-- 提示重名
greatsql> SHOW WARNINGS; //
+-------+------+---------------------------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------------------------+
| Note | 1585 | This function 'LENGTH' has the same name as a native function |
+-------+------+---------------------------------------------------------------+
1 row in set (0.00 sec)
-- 3. 创建不同名函数
-- 可以返回函数中的固定值16
greatsql> WITH
FUNCTION LENGTH_tmp(c VARCHAR2(50)) RETURN INT
AS
BEGIN
RETURN 16;
END;
SELECT LENGTH_tmp('GreatSQL') FROM DUAL; //
-- 4. 切换到DEFAULT模式,在DEFAULT模式下创建函数
greatsql> SET sql_mode = DEFAULT; //
greatsql> WITH FUNCTION f2() RETURNS INT
BEGIN
DECLARE c, s INT;
DROP TEMPORARY TABLE IF EXISTS t1;
CREATE TEMPORARY TABLE t1(id INT);
INSERT INTO t1 VALUES (1), (2), (3);
SET c:= (SELECT COUNT(*) FROM t1);
SET s:= (SELECT SUM(id) FROM t1);
RETURN c * s;
END;
SELECT f2() FROM DUAL; //
+------+
| f2() |
+------+
| 18 |
+------+
1 row in set (0.00 sec)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
扫码关注微信公众号