DB2—03(DB2中常见基础操作 ➕ DB2实现递归查询 ➕ DB2中自定义递归函数)
移动开发
2023-12-16 22:33:50
阅读次数: 0
DB2—03(DB2中常见基础操作 ➕ DB2实现递归查询 ➕ DB2中自定义递归函数)
1. 前言
1.1 oracle和mysql相关
部分语法和oracle、mysql都大同小异、关于oracle和mysql的可以看下面的文章:
2. db2中的"dual"
2.1 SYSIBM.SYSDUMMY1
2.2 使用VALUES
2.3 SYSIBM.SYSDUMMY1 “变” dual
3. db2中常用函数
3.1 nvl()、value()、COALESCE()
先说一下nvl()
nvl()
,语法如下:nvl( val1, val2)
功能: 如果val1为空(注意:这里的空是null
,不算空字符串),则返回val2,否则返回val1本身,例子如下:SELECT nvl( null , 0 ) , nvl( 234 , 0 ) , nvl( '' , 'aa' ) FROM SYSIBM. SYSDUMMY1;
注意: 其表达式的值可以是数字型、字符型和日期型。但是表达式1和表达式2的数据类型必须为同一个类型 。
value()
、COALESCE()
用法同nvl()
再说一下nvl2()
SELECT nvl2( null , 0 , 1 ) , nvl2( 234 , 0 , 1 ) , nvl2( '' , '不空' , '空' ) FROM SYSIBM. SYSDUMMY1;
接着说一下 value()
、COALESCE()
value()
、COALESCE()
就简单,因为用法同nvl()
,给两个语句,自己下去测测看:SELECT value ( null , 0 ) , value ( 56 , 0 ) , value ( '' , 'bb' ) FROM SYSIBM. SYSDUMMY1;
SELECT COALESCE ( null , 0 ) , COALESCE ( 56 , 0 ) , COALESCE ( '' , 'bb' ) FROM SYSIBM. SYSDUMMY1;
最后选哪个,个人觉得还是用nvl()
和 nvl2()
吧,除了熟悉之外还有就是以后换数据库的话也好移植。
3.2 NULLIF() 函数
如果相同返回NULL,否则返回第一个参数,如下:
3.3 LISTAGG() 与 xml2clob()、xmlagg()
4. DB2中自定义函数
4.1 简单入门函数
4.1.1 语法结构
4.1.2 例子
4.1.2.1 例子1——求两数和
代码如下(end后面不用结束符合):create or replace function fun_sum_number( num1 bigint , num2 bigint )
returns bigint
BEGIN
declare v_result bigint ;
SET v_result = num1 + num2;
return v_result;
END
测试如下:values ( fun_sum_number( 1 , 5 ) ) ;
4.1.2.2 例子2——自定义等差数列的n项和
求最小数、最大数以及步长
确定的等差数列的n项和,实现代码如下:CREATE OR REPLACE FUNCTION fun_all_num_sum( start_num bigint , end_num bigint , step_num bigint )
RETURNS bigint
LANGUAGE SQL
BEGIN
DECLARE loop_start bigint ;
DECLARE total_sum bigint ;
SET loop_start = start_num;
SET total_sum = 0 ;
WHILE loop_start <= end_num DO
SET total_sum = total_sum + loop_start;
SET loop_start = loop_start + step_num;
END WHILE ;
RETURN total_sum;
END
效果如下:SELECT fun_all_num_sum( 1 , 3 , 1 ) , fun_all_num_sum( 1 , 4 , 1 ) , fun_all_num_sum( 2 , 8 , 2 ) FROM SYSIBM. SYSDUMMY1 ;
4.2 返回table的自定义函数
代码如下:CREATE OR REPLACE FUNCTION fun_query_dog_by_id( dogId varchar ( 10 ) )
RETURNS TABLE (
DOG_ID varchar ( 10 ) ,
dog_name varchar ( 10 ) ,
dog_kind varchar ( 10 )
)
RETURN
SELECT DOG_ID, dog_name, dog_kind
FROM dog
WHERE dog. DOG_ID = fun_query_dog_by_id. dogId;
测试如下:
4.3 自定义递归查询函数
先看原始数据结构
根据部门ID找公司ID,函数实现如下:CREATE OR REPLACE FUNCTION fun_get_company_id_by_dept_id( v_dept_id varchar ( 10 ) )
RETURNS varchar ( 10 )
LANGUAGE SQL
BEGIN
DECLARE dept_level bigint ;
DECLARE loop_dept_id varchar ( 10 ) ;
DECLARE result_company_id varchar ( 10 ) ;
select t. DEPT_LEVEL into dept_level from sys_company_dept t where t. dept_id = v_dept_id;
SET loop_dept_id = v_dept_id;
WHILE dept_level >= 2 DO
SELECT t1. PARENT_ID , t2. DEPT_LEVEL into loop_dept_id, dept_level FROM sys_company_dept t1
LEFT JOIN sys_company_dept t2 ON t1. PARENT_ID = t2. DEPT_ID
where t1. dept_id = loop_dept_id;
END WHILE ;
SET result_company_id = loop_dept_id;
RETURN result_company_id;
END
效果如下:
递归查询部门及对应的公司列表,如下:SELECT temp . * , t2. DEPT_NAME AS company_name FROM (
SELECT t1. * , fun_get_company_id_by_dept_id( t1. DEPT_ID) AS company_id FROM sys_company_dept t1
) temp LEFT JOIN sys_company_dept t2 ON temp . company_id = t2. DEPT_ID
5. DB2中使用with实现递归查询
如果嫌自定义递归函数麻烦的话,也可以直接写sql实现递归,如下,要查B001及其下的所有部门
,使用with实现递归查询如下:WITH temp ( dept_id, dept_name, parent_id) AS
(
SELECT dept_id, dept_name, parent_id FROM SYS_COMPANY_DEPT WHERE dept_id= 'B001'
UNION ALL
SELECT t1. dept_id, t1. dept_name, t1. parent_id FROM SYS_COMPANY_DEPT AS t1, temp AS t2 WHERE t1. parent_id= t2. dept_id
)
SELECT dept_id, dept_name, parent_id FROM temp ;
6. 解决 db2-表 处于暂挂状态
转载自 blog.csdn.net/suixinfeixiangfei/article/details/134184274