zoukankan      html  css  js  c++  java
  • oracle函数

    函数(存储函数)也是一种较为方便的存储结构,用户定义函数可以被SQL语句或者PL/SQL直接调,函数和过程最大的区别在于,函数可以有返回值,
    而过程只能依靠OUT 或者IN OUT返回数据
    定义函数语法:
    CREATE [OR REPLACE] FUNCTION 函数([参数,...]])
    RETURN 返回值类型
    [AUTHID [DEFINER | CURRENT_USER]]
    AS || IS
    [PRAGMA AUTONOMOUS_TRANSACTION;]
    声明部分;
    BEGIN
    程序部分;
    [RETURN 返回值;]
    EXCEPTION
    导常处理;
    END [函数名];
    参数中定义参数模式表示过程的数据的接收操作,一般分为IN,OUT,IN OUT 3类
    CREATE [OR REPLACE]:表示创建或者替换过程,如果过程存在则替换,如果不存在就创建一个新的
    AUTHID子句定义了一个过程的所有者权限,DEFINER(默认)表示定义者权限执行,或者用CURRENT_USER覆盖程序的默认行为,变为使用者权限
    PRAGMA AUTONOMOUS_TRANSACTION:表示过程启动一个自治事务,自治事务可以让主事挂起,在过程中执行完SQL后,由用户处理提交或者回滚自治事务,
    然后恢复主事务
    和过程的语法基本相似,唯一不同的是在定义函数时候需要有返回值类型(RETURN 返回值类型)声明

    定义一个函数返回系统时间

    复制代码
    CREATE OR REPLACE FUNCTION datetime_fun
    RETURN VARCHAR2
    AS
    BEGIN
       RETURN to_char(SYSDATE,'yyyy-mm-dd hh24:mi:ss');
    END;
    --调用
    DECLARE
    BEGIN
      dbms_output.put_line(datetime_fun);
    END;
    复制代码
    复制代码
    带出输入和输出的函数
    create or replace function getinfo_fun(eno emp.empno%type, job out emp.job%type) return varchar2 is
         v_name        emp.ename%TYPE;
         v_count          NUMBER;
    BEGIN
        SELECT COUNT(eno) INTO v_count FROM emp WHERE empno=eno;
        IF v_count>0 THEN 
        SELECT ename,job INTO v_name,job FROM emp WHERE empno=eno;
        END IF;
      RETURN v_name;
    end getinfo_fun;
    --调用
    DECLARE
       v_id                 emp.empno%TYPE:=&empno;
       v_name               emp.ename%TYPE;
       v_job                emp.job%TYPE;
    BEGIN
      v_name:=getinfo_fun(v_id,v_job);
      dbms_output.put_line('员工编号是:'||v_id||' 姓名:'||v_name||' 职位:'||v_job);
    END;
    复制代码

    示例一、定义函数通过员工编号来查询员工的工资

    复制代码
    CREATE OR REPLACE FUNCTION GET_SAL_FUN(F_NO EMP.EMPNO%TYPE) 
      RETURN NUMBER 
      AS
      V_SAL EMP.SAL%TYPE;
    BEGIN
      SELECT SAL INTO V_SAL FROM EMP WHERE EMPNO = F_NO;
      RETURN V_SAL;
    END;
    
    --调用
    DECLARE
     v_id           emp.empno%TYPE:=&empno;
     v_sal          emp.sal%TYPE;
     BEGIN
       v_sal:=get_sal_fun(v_id);
       dbms_output.put_line('员工编号:'||v_id||' 的工资为: '||v_sal);
     END;
    复制代码

    第二种

    复制代码
    -使用过程来调用
    CREATE OR REPLACE PROCEDURE invoke_proc
    AS
    v_id           emp.empno%TYPE:=&empno;
    v_sal              emp.sal%TYPE;
    BEGIN
       v_sal:=get_sal_fun(v_id);
       dbms_output.put_line('员工编号:'||v_id||' 的工资为: '||v_sal);
    END;
    
    EXEC invoke_proc ;
    复制代码

     第三种

    使用sql语句来调用
     SELECT get_sal_fun(&v_id) FROM dual;

    参数模式

    IN模式

    示例一、定义函数使用IN

    复制代码
    CREATE OR REPLACE FUNCTION in_fun(
        
        f_b  VARCHAR2 DEFAULT 'Java开发实战经典',                     --默认的参数模式为in
         f_a IN VARCHAR2 DEFAULT '好好学习'                --明确定义IN参数模式
    ) 
    RETURN VARCHAR2
    AS
    BEGIN
      RETURN f_a;
    END;
    
    执行
    DECLARE
        v_a VARCHAR2(50);
        v_b VARCHAR2(50);
    BEGIN
       v_b:=in_fun(v_a);
       dbms_output.put_line(v_b);
       dbms_output.put_line(SQLERRM);
    END;
    结果:
    好好学习
    ORA-0000: normal, successful completion
    复制代码

    OUT模式

    示例二、定义函数使用OUT

    复制代码
    CREATE OR REPLACE FUNCTION out_fun(
           f_a OUT Varchar2,
           f_b OUT VARCHAR2
    )
    RETURN VARCHAR2
    AS
    BEGIN
      f_a:='Java开发实战经典';
      f_b:='Oracle开发实战经典';
      RETURN f_b;
    END;
    
    --调用
    DECLARE
       v_a         VARCHAR2(100);
       v_b         VARCHAR2(100);
       v_result    VARCHAR2(100);
    BEGIN
      v_result:=out_fun(v_a,v_b);
      dbms_output.put_line(v_result);
       dbms_output.put_line(SQLERRM);
    END;
    复制代码

    示例三、通过函数完成部门增加

    复制代码
    CREATE OR REPLACE FUNCTION dept_inser_fun(
      f_dno             dept.deptno%TYPE,
      f_dname           dept.dname%TYPE,
      f_loc             dept.loc%TYPE
    )
    RETURN NUMBER
    AS 
    v_count            NUMBER;
    BEGIN
      SELECT COUNT(deptno) INTO v_count FROM dept WHERE deptno=f_dno;
      
      IF v_count>0 THEN
        RETURN -1;                --返回失败
        ELSE
          INSERT INTO dept(deptno,dname,loc)VALUES(f_dno,f_dname,f_loc);
          COMMIT;
          RETURN 0;
          END IF;
    END;
    
    --调用
    DECLARE
          v_result     NUMBER;
    BEGIN
      v_result:=dept_inser_fun(&deptno,'&dname','&loc');
       IF V_RESULT = 0 THEN
        DBMS_OUTPUT.PUT_LINE('新部门增加成功');
      ELSE
        DBMS_OUTPUT.PUT_LINE('新部门增加失败');
      END IF;
    END;
    
     VAR v_sal NUMBER;
     CALL get_sal_fun(&v_id) INTO v-sal;
     print v_sal;
    复制代码

     示例四、函数根所员工编号,输出姓名,返回工资

    复制代码
    --定义函数根所员工编号,输出姓名,返回工资
    CREATE OR REPLACE FUNCTION get_sal(eno NUMBER,eme OUT VARCHAR2) RETURN NUMBER
    IS
    v_sal                 emp.sal%TYPE;
    BEGIN
      SELECT sal,ename INTO v_sal,eme FROM emp WHERE empno=eno;
      RETURN v_sal;
      EXCEPTION
        WHEN OTHERS THEN
          dbms_output.put_line('没有这个员工');
    END;
    --调用
    DECLARE
       v_eno         emp.empno%TYPE:=&empno;
       v_ename       emp.ename%TYPE;
       v_sal         emp.sal%TYPE;
    BEGIN
        v_sal:=get_sal(v_eno,v_ename);
        dbms_output.put_line(' 编号:'||v_eno||' 姓名:'||v_ename||' 工资:'||v_sal);
        
    END;
    复制代码
  • 相关阅读:
    hbase存储优化
    cloudera manager下phoenix的安装
    Cloudera manager的服务安装以及spark升级到2.2
    redis学习总结
    kylin基础概念和基础性能优化
    mycat使用注意事项
    kylin2.0环境搭建
    ETL实践--kettle转到hive
    集成 SOLR 到 TOMCAT 中(傻瓜教程)
    局域网ip扫描
  • 原文地址:https://www.cnblogs.com/hjiongjiong/p/4227601.html
Copyright © 2011-2022 走看看