GBase 8a数据库集群,支持自定义函数,来实现公用的功能。其支持标准的0-多个输入参数和一个返回值。如果没有返回值,建议使用存储过程。
如果在自定义函数里使用了表,则必须是【复制表】,不能是随即表。
目录导航
自定义函数样例
drop function if exists f_test;
delimiter //
create function f_test(inDate datetime) returns datetime
begin
return date_add(inDate, interval 1 day);
end //
delimiter ;
其中f_test是自定义函数名字
小括号里是输入参数, inDate 是日期类型
returns 后面是返回类型 datetime
函数以BEGIN和END结尾
计算结果,以return 返回
执行结果
gbase> select now(),f_test(now());
+---------------------+---------------------+
| now() | f_test(now()) |
+---------------------+---------------------+
| 2020-09-03 21:12:50 | 2020-09-04 21:12:50 |
+---------------------+---------------------+
1 row in set (Elapsed: 00:00:00.00)
注意
如用到了表,则必须是复制表
如果你在自定义函数里使用了表,那么必须是复制表,否则会报表找不到的错误信息:DETAIL: Table 'testdb.t1' doesn't exist。
判断是自定义函数,理论上在任何节点执行,相同的输入应该返回相同的结果(除非你故意里面随机数),其中的涉及的表也应该返回相同结果。但如果是随机分布表,那么相同的SQL在每个节点执行时,返回结果【极大可能】是不一致的。所以为了保证一致性,要求复制表,每个节点的数据完全一致了。
建议用存储过程来实现涉及分布表的自定义功能。
如用到了复制表,则直接select必须加上from
如果没有用到表,则可以直接 select XXXX(); 如果用到了,则必须用 select XXX from 表名, 如果就返回一行,可以用select XXX() from dual
否则会报错
gbase> select udfKQIScore('123');
ERROR 1149 (42000): (GBA-02SC-1001) The query includes syntax that is not supported by the gcluster.
测试自定义函数样例
drop function if exists f_test2;
delimiter //
create function f_test2(v_id int) returns varchar
begin
select num into @v from t1 where id=v_id;
return @v;
end //
delimiter ;
测试表
gbase> show create table t1;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE "t1" (
"id" bigint(20) DEFAULT NULL,
"num" decimal(20,0) DEFAULT NULL
) ENGINE=EXPRESS DEFAULT CHARSET=utf8 TABLESPACE='sys_tablespace' |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (Elapsed: 00:00:00.00)
测试结果
直接报表不存在的错误
gbase> select f_test2(1) from t1;
ERROR 1708 (HY000): [10.0.2.101:5050](GBA-02AD-0005)Failed to query in gnode:
DETAIL: Table 'testdb.t1' doesn't exist
SQL: SELECT /*10.0.2.101_250_22_2020-09-23_18:07:16*/ /*+ TID('3014950') */ "testdb"."f_test2"(1) AS `f_test2(1)` FROM `testdb`.`t1_n1` `testdb.t1`
改成复制表
一切正常了。
gbase> rename table t1 to t1_dis;
Query OK, 0 rows affected (Elapsed: 00:00:00.38)
gbase> create table t1 replicated as select * from t1_dis;
Query OK, 0 rows affected (Elapsed: 00:00:00.45)
gbase> show create table t1;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE "t1" (
"id" bigint(20) DEFAULT NULL,
"num" decimal(20,0) DEFAULT NULL
) ENGINE=EXPRESS REPLICATED DEFAULT CHARSET=utf8 TABLESPACE='sys_tablespace' |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (Elapsed: 00:00:00.00)
gbase> select f_test2(1) from t1;
Empty set, 1 warning (Elapsed: 00:00:00.03)
gbase> select * from t1;
\Empty set (Elapsed: 00:00:00.02)
gbase> insert into t1 values(1,121212);
Query OK, 1 row affected (Elapsed: 00:00:00.35)
gbase> select f_test2(1) from t1;
+------------+
| f_test2(1) |
+------------+
| 121212 |
+------------+
1 row in set (Elapsed: 00:00:00.02)
自定义存储过程样例,请参考
其它数据库内置函数,请参考
《南大通用GBase 8a自定义函数UDF样例,涉及表不能是随机表,必须是复制表》有1条评论
评论已关闭。