oracle实验40:编写函数

函数

  • 是命名的PL/SQL块
  • 有返回值
  • 以编译后的形式存放在数据库中用来重复执行
  • 作为表达式的一部分被调用

创建函数的语法

CREATE [OR REPLACE] FUNCTION
[schema.] function_name[(argument [in|out|inout] type…)]RETURN returning_datatype
IS | AS
[本地变量声明]
BEGIN
  -执行语句部分
[EXCEPTION]
  -错误处理部分
END[function_name];

调用函数

可以在SQL语句中或Sql*Plus中调用函数

在SQL语句中调用函数好处

    • 可以实现用简单的SQL语句不能实现的计算
    • 提高查询的效率

在SQL语句中调用函数使用规则

    • 只能使用函数,而不是过程
    • 从SQL语句中调用的函数中不允许DML语句
    • 形参必须为IN
    • 必须返回Oracle支持数据类型,不能使用PL/SQL数据类型
    • 必须有EXECUTE权限

可以在任何有效的SQL子句中中调用函数

    • SELECT命令的选择列表
    • WHERE和HAVING条件子句
    • ORDER BY, 和GROUP BY子句
    • INSERT命令的VALUES 子句
    • UPDATE 命令的SET 子句

实验40:编写函数

SQL> conn scott/scott

已连接。

创建函数

SQL> create or replace function get_sal
     (v_id in emp.empno%type)
     return number
     is
     v_salary emp.sal%type :=0;
     begin
     select sal into v_salary from emp where empno=v_id;
     return(v_salary);
     end get_sal;
     /

函数已创建。

验证对象

在user_source数据字典中查询

SQL>  col object_name for a50;

SQL>  select object_name,object_type from user_objects;

OBJECT_NAME                                       OBJECT_TYPE 

------------------------------------------ ---------------         
DEPT                                                     TABLE   
PK_DEPT                                                INDEX    
EMP                                                       TABLE 
PK_EMP                                                 INDEX                       
BONUS                                                  TABLE                       
SALGRADE                                            TABLE                       
GET_SAL                                               FUNCTION                    
T3                                                        TABLE                       
EMP2                                                    TABLE                       
T4                                                        TABLE                       
DEPT2                                                  TABLE                       

T2                                                       TABLE                       
TRG1                                                   TRIGGER                     
E                                                         TABLE                       
D_UPDATE                                           TRIGGER                     
TRIGGER_INSTEAD_OF                          TRIGGER                     
E2                                                       TABLE                       
D                                                        TABLE                       
V2                                                       VIEW                        
EMPVU20                                             VIEW                        
EMPVU10                                             VIEW                        
E_UPDATE                                            TRIGGER                     

BIN$rLjPu5EOS+61wSmunaaMcg==$0    TABLE                       
T1                                                       TABLE                       
BIN$qkEJzOqSSfGWtMsfdkcPXA==$0     TABLE                       
E1                                                       TABLE                       
V1                                                       VIEW                        
LOGIN_TABLE                                       TABLE                       

已选择28行。

SQL> set linesize 2000

查看原程序

SQL> select text from user_source;

TEXT                                                                                                              
-------------------------------------------------------------------------------------------------
function get_sal                                                                                                  
 (v_id in emp.empno%type)                                                                                         
 return number                                                                                                    
 is                                                                                                               
 v_salary emp.sal%type :=0;                                                                                       
 begin                                                                                                            
 select sal into v_salary from emp where empno=v_id;                                                              
 return(v_salary);                                                                                                
 end get_sal;                                                                                                     
trigger trg1                                                                                                      
before insert or update of sal on emp                                                                             

TEXT                                                                                                              
-------------------------------------------------------------------------------------------------
for each row                                                                                                      
begin                                                                                                             
insert into t1 values(:old.sal,:new.sal);                                                                         
end;                                                                                                              
trigger d_update                                                                                                  
after delete or update of deptno on d                                                                             
for each row                                                                                                      
begin                                                                                                             
if (updating and :old.deptno != :new.deptno)                                                                      
then update e                                                                                                     
set deptno =:new.deptno                                                                                           

TEXT                                                                                                              
-------------------------------------------------------------------------------------------------
where deptno=:old.deptno;                                                                                         
end if;                                                                                                           
if deleting then                                                                                                  
delete e where deptno=:old.deptno;                                                                                
end if;                                                                                                           
end;                                                                                                              
trigger trigger_instead_of                                                                                        
instead of insert or update or delete on v1                                                                       
begin                                                                                                             
if updating then                                                                                                  
update e1 set deptno=:new.deptno where deptno=:old.deptno;                                                        

TEXT                                                                                                              
-------------------------------------------------------------------------------------------------
end if;                                                                                                           
end;                                                                                                              
trigger e_update                                                                                                  
before update of sal on e                                                                                         
begin                                                                                                             
if updating then                                                                                                  
raise_application_error(-20001,'工资不能被改动');                                                                 
end if;                                                                                                           
end;                                                                                                              

已选择42行。

调用函数

SQL> select get_sal(7839) from dual;

GET_SAL(7839)                                                                                                     
-------------                                                                                                     
         5000                                                                                                     

删除函数

SQL> drop function get_sal;

函数已删除。

加密函数

将建立函数的文本存储为F:ora_learncreat_fun.TXT

warp iname=F:ora_learncreat_fun.TXT oname=F:ora_learncreat_fun2.TXT

SQL>  @F:ora_learncreat_fun2.TXT

函数已创建。

SQL> select * from user_source where type='FUNCTION' and name='GET_SAL;

NAME          TYPE                 LINE                   TEXT                                                                                                     

----------- ----------- ----------------- --------------------------
GET_SAL   FUNCTION  ##########   function get_sal wrapped

                                                          a000000
                                                          354
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
                                                          abcd
8                                                                                                                 
b7 df                                                                                                             
UckvEIf5L+ZKc3hgtBmqbeO1pUcwg+nwmJ5qfHTp2vjVuQlapyW+G4Qc8ifjQ4+A8hu3a/Up                                          
PPkkDbJr1mdxkAqCObntZV+xTv0k+LoOo4yrDgQanAyr3xedYsOZVJuvZVd9StipwOH29c1o                                          
gzvd3mIWSNdcnvUhPm+4IV6790opJni1lxHw/wB6uZG96T2RvnrDPa88PmYcfPdy9HpzpkpG                                          
fKQ=                                                                            

建立索引用的函数

SQL> create or replace function f_sal
    (v1 in number)
    return number deterministic  --确定性,定义中指明
    as
    begin
    if v1<1000 then return 1;
    elsif v1<2000 then return 2;
    else return 3;
    end if;
    end;
    /

函数已创建。

创建索引

SQL> drop index i1;

索引已删除。

SQL> create index i1 on emp(f_sal(sal));

索引已创建。

SQL> select * from emp where f_sal(sal)=1;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM   DEPTNO
  -------- ---------- --------- ---------- -------------- ---------- ---------- --------                                                                    
      7369 SMITH      CLERK           7902 17-12月-80            800                  20
      7900 JAMES      CLERK           7698 03-12月-81            950                  30
                                                                      
                                                                               

原文地址:https://www.cnblogs.com/downpour/p/3145088.html