Oracle兼容-语法-WITH FUNCTION


1. 语法

  1. WITH FUNCTION
  2. <func_name> {<function...>}
  3. SELECT(query_block)

2. 定义和用法

通过 WITH FUNCTION 子句,可以把很多原本需要存储过程来实现的复杂逻辑用一句SQL来进行表达,使用起来更方便。

相关使用说明如下:

  1. 定义的函数的作用域为所在的查询表达式内。

  2. 定义的存储函数对象不会存储到系统表中;

  3. 定义的存储函数比模式对象的存储函数拥有更高的优先级;

  4. 定义的存储函数比本地函数优先级低;

  5. 定义函数时不需要 CREATE FUNCTION 权限;

  6. 无需要求 sql_mode = ORACLE,只要创建函数时的语法不报错即可;

  7. 不支持 PREPARE STMT

  8. 函数名不支持 schema_name.func_name 这种格式,只能在当前Schema中创建函数;

  9. 只支持SELECT子句,不支持其他子句,例如 DELET/UPDATE/MERGE 等。

备注:9点的功能是存储过程中,需清楚地看到函数定义,避免ddl操作开销的需求,暂时未支持,需收集具体使用场景后再进行适配开发

3. 示例

  1. -- 先切换到ORACLE模式
  2. greatsql> SET sql_mode = ORACLE;
  3. greatsql> DELIMITER //
  4. -- 1. 创建函数
  5. greatsql> WITH
  6. FUNCTION f1(c INT) RETURN INT
  7. AS
  8. BEGIN
  9. RETURN c * 10;
  10. END;
  11. SELECT f1(3306) FROM DUAL; //
  12. +----------+
  13. | f1(3306) |
  14. +----------+
  15. | 33060 |
  16. +----------+
  17. 1 row in set (0.00 sec)
  18. -- 2. 创建同名函数
  19. greatsql> SELECT LENGTH('GreatSQL') FROM DUAL //
  20. +--------------------+
  21. | LENGTH('GreatSQL') |
  22. +--------------------+
  23. | 8 |
  24. +--------------------+
  25. 1 row in set (0.00 sec)
  26. -- 可以创建重名函数,但本地函数优先,可以看到结果并非返回6而是8
  27. greatsql> WITH
  28. FUNCTION LENGTH(c VARCHAR2(50)) RETURN INT
  29. AS
  30. BEGIN
  31. RETURN 6;
  32. END;
  33. SELECT LENGTH('GreatSQL'), INSTR('Hello GreatSQL', 'G') FROM DUAL; //
  34. +--------------------+------------------------------+
  35. | LENGTH('GreatSQL') | INSTR('Hello GreatSQL', 'G') |
  36. +--------------------+------------------------------+
  37. | 8 | 7 |
  38. +--------------------+------------------------------+
  39. 1 row in set, 1 warning (0.00 sec)
  40. -- 提示重名
  41. greatsql> SHOW WARNINGS; //
  42. +-------+------+---------------------------------------------------------------+
  43. | Level | Code | Message |
  44. +-------+------+---------------------------------------------------------------+
  45. | Note | 1585 | This function 'LENGTH' has the same name as a native function |
  46. +-------+------+---------------------------------------------------------------+
  47. 1 row in set (0.00 sec)
  48. -- 3. 创建不同名函数
  49. -- 可以返回函数中的固定值16
  50. greatsql> WITH
  51. FUNCTION LENGTH_tmp(c VARCHAR2(50)) RETURN INT
  52. AS
  53. BEGIN
  54. RETURN 16;
  55. END;
  56. SELECT LENGTH_tmp('GreatSQL') FROM DUAL; //
  57. -- 4. 切换到DEFAULT模式,在DEFAULT模式下创建函数
  58. greatsql> SET sql_mode = DEFAULT; //
  59. greatsql> WITH FUNCTION f2() RETURNS INT
  60. BEGIN
  61. DECLARE c, s INT;
  62. DROP TEMPORARY TABLE IF EXISTS t1;
  63. CREATE TEMPORARY TABLE t1(id INT);
  64. INSERT INTO t1 VALUES (1), (2), (3);
  65. SET c:= (SELECT COUNT(*) FROM t1);
  66. SET s:= (SELECT SUM(id) FROM t1);
  67. RETURN c * s;
  68. END;
  69. SELECT f2() FROM DUAL; //
  70. +------+
  71. | f2() |
  72. +------+
  73. | 18 |
  74. +------+
  75. 1 row in set (0.00 sec)

问题反馈

联系我们

扫码关注微信公众号

greatsql-wx