看完这章后你会学习到以下内容:
1.练习场景
2.面试场景
3.工作应用场景
总览思维导图:
面试部分:
1.创建函数,从emp表中查询指定员工编号的职工的工资
CREATE OR REPLACE FUNCTION CHECK_SAL(F_EMPNO IN EMP.EMPNO%TYPE) RETURN NUMBER ISV_SAL VARCHAR(50);BEGINSELECT SAL INTO V_SAL FROM EMP WHERE EMPNO = F_EMPNO; --- 直接调用隐式游标RETURN V_SAL;EXCEPTION WHEN NO_DATA_FOUND THEN --- 异常值处理V_SAL:='没找到任何结果';RETURN V_SAL;END;--- 调用函数
SELECT CHECK_SAL(7499) AS 工资 FROM DUAL;
2.*创建函数,返回emp表中指定职工的工资和姓名。
返回值是两个,可用return返回一个,另一个用out参数带回
CREATE OR REPLACE FUNCTION F_EMP_SALENAME(FEMPNO IN EMP.EMPNO%TYPE,V_ENAME OUT EMP.ENAME%TYPE)RETURN NUMBER IS
V_SAL EMP.SAL%TYPE;
BEGINSELECT SAL,ENAME INTO V_SAL,V_ENAMEFROM EMPWHERE EMPNO = FEMPNO;RETURN V_SAL;END;--- 第一部分借用IN参数,返回其中一个SAL
--- 第二部分再重新定义一个OUT参数,不然程序不清楚要调用那个类型的参数DECLAREP_ENAME EMP.ENAME%TYPE;p_SAL EMP.SAL%TYPE;BEGINP_SAL:=F_EMP_SALENAME(7369,P_ENAME); --- 定义一个Out参数返回function的返回值SalDBMS_OUTPUT.put_line('员工'||P_ENAME||'薪酬'||P_SAL);END;
3.创建函数,根据给定的部门编号(提示: 利用&)计算该部门所有职工的平均工资。
CREATE OR REPLACE FUNCTION F_INPUTEMPNO(F_DEPTNO IN DEPT.DEPTNO%TYPE)
RETURN NUMBER IS
V_SAL NUMBER;BEGIN SELECT AVG(SAL) INTO V_SAL FROM EMP WHERE DEPTNO = F_DEPTNO; RETURN V_SAL;
END;--- 调用时候,在输入名称前加入&,类似于VBA里的Input函数SELECT F_INPUTEMPNO(&部门编号) AS 平均工资 FROM DUAL;
4.创建一个函数,仅有一个形参,它接收调用函数中传递过来的实参--部门号,函数的返回值为该部门的一整条记录信息.
CREATE OR REPLACE FUNCTION F_EMPINFO(F_DEPTNO IN DEPT.DEPTNO%TYPE)RETURN DEPT%ROWTYPE ISV_DEPT DEPT%ROWTYPE;BEGINSELECT * INTO V_DEPT FROM DEPT WHERE DEPTNO = F_DEPTNO;RETURN V_DEPT;END;DECLARE V_DEPT DEPT%ROWTYPE;BEGINV_DEPT := F_EMPINFO(20); --- 传递参数给到调用函数时新定义得变量V_Dept;DBMS_OUTPUT.PUT_LINE('部门名: '||V_DEPT.DNAME || ' 部门位置: ' || V_DEPT.LOC);END;
5*.创建函数,将emp表中工资低于平均工资的职工工资加上200,并返回修改了工资的总人数。注意:Update后面要加上Where语句否则全部都更新,其次我们善用%ROWCOUNT.
CREATE OR REPLACE FUNCTION F_MODIFY
RETURN NUMBER
IS
BEGINUPDATE EMP SET SAL=SAL+200 WHERE SAL<(SELECT AVG(SAL) FROM EMP);RETURN SQL%ROWCOUNT; /* sql%rowcount用于记录修改的条数,必须放在一个更新或者删除等修改类语句后面执行,select语句用于查询的话无法使用,当你执行多条修改语句时,按照sql%rowcount 之前执行的最后一条语句修改数为准。*/
END;
/
调用
BEGINDBMS_OUTPUT.PUT_LINE(F_MODIFY);
END;
/
面试过程
1.输入2个整数,返回最小到最大数之间的连乘的结果(两个整数在1到20之间);
思路: 先对两个数进行范围的设置,用IF加AND判断。
然后两个数字一共三种可能:
A大于B,A小于B,A等于B 用IF Elsif 方式做条件判断。
CREATE OR REPLACE FUNCTION FUNB(P1 IN INT, P2 IN INT) RETURN INTEGER IS --- 这两个的数据类型一定要一致V_RESULT INTEGER := 1;BEGINIF (P1 < 1 AND P1 > 20) AND (P2< 1 AND P2 > 20) THENIF P2 > P1 THENFOR I IN P1 .. P2 LOOPV_RESULT := V_RESULT * I;END LOOP;ELSIF P2 < P1 THENFOR I IN P2 .. P1 LOOPV_RESULT := V_RESULT * I;END LOOP;ELSEV_RESULT := P1 * P2;END IF;ELSE DBMS_OUTPUT.put_line('请输入正确的范围值');
END IF; RETURN V_RESULT;
END;
2.输入3个整数,取中位数。
--- 方法一 CREATE OR REPLACE FUNCTION FUNA(P1 IN INT,P2 IN INT,P3 IN INT)RETURN INTEGER IS V_RESULT INTEGER;BEGIN SELECT CASE WHEN P1 >= P2 AND P1 <= P3 THEN P1WHEN P2 >= P1 AND P2 <= P3 THEN P2WHEN P3 >= P1 AND P3 <= P2 THEN P3 ENDINTO V_RESULT FROM DUAL;RETURN V_RESULT;END;----- 方法二
CREATE OR REPLACE FUNCTION FUN_middle(X1 IN NUMBER,X2 IN NUMBER,X3 IN NUMBER)RETURN numberIS BEGINIF (X1-X2)*(X1-X3)<=0 then return x1;elsif (x2-x1)*(x2-x3)<=0 then return x2;elsif(x3-x1)*(x3-x2)<=0 then return x3;end if;end;
3. 对比两个数,返回一个最大值。可以在设置参数时,顺带设置默认值
-- 传入两个参数,返回最大值CREATE OR REPLACE FUNCTION FUN_MAX (P_NUM1 IN NUMBER, P_NUM2 IN NUMBER DEFAULT 99)RETURN NUMBER -- 函数的返回类型ISBEGINIF P_NUM1>P_NUM2 THEN RETURN P_NUM1; ELSE RETURN P_NUM2; END IF;END;
3. 工作场景(一)
-- 函数返回类型为游标(对应报表接口)
-- 传入部门编号,返回整个部门的员工信息(函数)
CREATE OR REPLACE FUNCTION FUN_REF(P_DEPTNO EMP.DEPTNO%TYPE)RETURN SYS_REFCURSOR ISC_EMP SYS_REFCURSOR;BEGINOPEN C_EMP FOR -- 不要忘记添加FORSELECT * FROM EMP WHERE DEPTNO = P_DEPTNO;RETURN C_EMP;END FUN_REF;-- 直接在Dual 表里直接调用SELECT FUN_REF(30) FROM DUAL;