【PL/SQL 自定义函数】练习+面试+工作

看完这章后你会学习到以下内容:

1.练习场景
2.面试场景
3.工作应用场景


总览思维导图:

【PL/SQL 自定义函数】练习+面试+工作_第1张图片


面试部分:

1.创建函数,从emp表中查询指定员工编号的职工的工资

 CREATE OR REPLACE FUNCTION CHECK_SAL(F_EMPNO IN EMP.EMPNO%TYPE) RETURN NUMBER IS
 V_SAL VARCHAR(50);

 BEGIN
     SELECT 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;
BEGIN
  
   SELECT SAL,ENAME INTO V_SAL,V_ENAME
   FROM EMP
   WHERE EMPNO = FEMPNO;
   RETURN V_SAL;

END;

--- 第一部分借用IN参数,返回其中一个SAL
--- 第二部分再重新定义一个OUT参数,不然程序不清楚要调用那个类型的参数
 

 DECLARE
 P_ENAME EMP.ENAME%TYPE;
 p_SAL EMP.SAL%TYPE;
 
 BEGIN
    P_SAL:=F_EMP_SALENAME(7369,P_ENAME);      --- 定义一个Out参数返回function的返回值Sal
    DBMS_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 IS
  
    V_DEPT DEPT%ROWTYPE;
  BEGIN
    SELECT * INTO V_DEPT FROM DEPT WHERE DEPTNO = F_DEPTNO;
    RETURN V_DEPT;
  END;
  
  DECLARE 
  V_DEPT DEPT%ROWTYPE;
  BEGIN
  V_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
BEGIN
 UPDATE EMP SET SAL=SAL+200 WHERE SAL<(SELECT AVG(SAL) FROM EMP);
 RETURN SQL%ROWCOUNT; 

/* sql%rowcount用于记录修改的条数,必须放在一个更新或者删除等修改类语句后面执行,
   select语句用于查询的话无法使用,
   当你执行多条修改语句时,按照sql%rowcount 之前执行的最后一条语句修改数为准。*/
END;
/
调用
BEGIN
  DBMS_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;

BEGIN

 IF (P1 < 1 AND P1 > 20) AND (P2< 1 AND P2 > 20) THEN
    IF P2 > P1 THEN
      FOR I IN P1 .. P2 LOOP
        V_RESULT := V_RESULT * I;
      END LOOP;
    ELSIF P2 < P1 THEN
      FOR I IN P2 .. P1 LOOP
        V_RESULT := V_RESULT * I;
      END LOOP;
    ELSE
      V_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  P1
              WHEN P2 >= P1 AND P2 <= P3 THEN  P2
              WHEN P3 >= P1 AND P3 <= P2 THEN  P3 END
  INTO V_RESULT FROM DUAL;
  RETURN V_RESULT;
  
  END;
        
----- 方法二  
CREATE OR REPLACE FUNCTION FUN_middle(X1 IN NUMBER,X2 IN NUMBER,X3 IN NUMBER)
     RETURN number
    IS 
    BEGIN
    IF (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    -- 函数的返回类型
    IS
    BEGIN
        IF 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 IS
      C_EMP SYS_REFCURSOR;  -- C_EMP 游标类型
    BEGIN
      OPEN C_EMP FOR   -- 不要忘记添加FOR
        SELECT * FROM EMP WHERE DEPTNO = P_DEPTNO;
      RETURN C_EMP;
    END FUN_REF;

 -- 直接在Dual 表里直接调用

   SELECT FUN_REF(30) FROM DUAL;

你可能感兴趣的:(oracle,plsql)