Oracle学习笔记

函数
声明:

Create or replace function uosv1.FN_GET_MISID (p_param VARCHAR2)
    Return VARCHAR2
    Is
    rtn VARCHAR2(32);
    begin
        select …….. into rtn from dual;
        return rtn;
    end FN_GET_MISID_1Q;
CREATE OR REPLACE
FUNCTION get_salary(
  Dept_no NUMBER, --注意VARCHAR2不能给精度,如:VARCHAR2(10),其它类似
  Emp_count OUT NUMBER)
  RETURN NUMBER 
IS
  V_sum NUMBER;
BEGIN
  SELECT SUM(SALARY), count(*) INTO V_sum, emp_count
    FROM EMPLOYEES WHERE DEPARTMENT_ID=dept_no;
  RETURN v_sum;
EXCEPTION
   WHEN NO_DATA_FOUND THEN 
      DBMS_OUTPUT.PUT_LINE('你需要的数据不存在!');
   WHEN OTHERS THEN 
      DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END get_salary;

函数调用

DECLARE
  V_num NUMBER;
  V_sum NUMBER;
BEGIN
  V_sum :=get_salary(10, v_num);
  DBMS_OUTPUT.PUT_LINE('部门号为:10的工资总和:'||v_sum||',人数为:'||v_num);
END;

存储过程

CREATE OR REPLACE
PROCEDURE QueryEmp
(v_empno IN  employees.employee_id%TYPE,
 v_ename OUT employees.first_name%TYPE,
 v_sal   OUT employees.salary%TYPE) 
AS
BEGIN
       SELECT last_name || last_name, salary INTO v_ename, v_sal 
    FROM employees 
    WHERE employee_id = v_empno; 
       DBMS_OUTPUT.PUT_LINE('温馨提示:编码为'||v_empno||'的员工已经查到!');
EXCEPTION
       WHEN NO_DATA_FOUND THEN 
      DBMS_OUTPUT.PUT_LINE('温馨提示:你需要的数据不存在!');
      WHEN OTHERS THEN 
      DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END QueryEmp;
--调用
 DECLARE
    v1 employees.first_name%TYPE;
    v2 employees.salary%TYPE;
 BEGIN
   QueryEmp(100, v1, v2);
   DBMS_OUTPUT.PUT_LINE('姓名:'||v1);
   DBMS_OUTPUT.PUT_LINE('工资:'||v2);
   QueryEmp(103, v1, v2);
   DBMS_OUTPUT.PUT_LINE('姓名:'||v1);
   DBMS_OUTPUT.PUT_LINE('工资:'||v2);
   QueryEmp(104, v1, v2);
   DBMS_OUTPUT.PUT_LINE('姓名:'||v1);
   DBMS_OUTPUT.PUT_LINE('工资:'||v2);
END;
CREATE OR REPLACE
PROCEDURE proc_demo
(
  dept_no NUMBER DEFAULT 10,
    sal_sum OUT NUMBER,
    emp_count OUT NUMBER
  )
IS
BEGIN
    SELECT SUM(salary), COUNT(*) INTO sal_sum, emp_count
  FROM employees WHERE department_id = dept_no;
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('温馨提示:你需要的数据不存在!');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END proc_demo;

游标

declare
       --类型定义
       cursor c_job
       is
       select empno,ename,job,sal
       from emp
       where job='MANAGER';
       --定义一个游标变量v_cinfo c_emp%ROWTYPE ,该类型为游标c_emp中的一行数据类型
       c_row c_job%rowtype;
begin
       for c_row in c_job loop
         dbms_output.put_line(c_row.empno||'-'||c_row.ename||'-'||c_row.job||'-'||c_row.sal);
       end loop;
end;

Fetch游标

--Fetch游标
--使用的时候必须要明确的打开和关闭

declare 
       --类型定义
       cursor c_job
       is
       select empno,ename,job,sal
       from emp
       where job='MANAGER';
       --定义一个游标变量
       c_row c_job%rowtype;
begin
       open c_job;
         loop
           --提取一行数据到c_row
           fetch c_job into c_row;
           --判读是否提取到值,没取到值就退出
           --取到值c_job%notfound 是false 
           --取不到值c_job%notfound 是true
           exit when c_job%notfound;
            dbms_output.put_line(c_row.empno||'-'||c_row.ename||'-'||c_row.job||'-'||c_row.sal);
         end loop;
       --关闭游标
      close c_job;
end;
--3,使用游标和while循环来显示所有部门的的地理位置(用%found属性)
declare
       --游标声明
       cursor csr_TestWhile
       is
       --select语句
       select  LOC
       from Depth;
       --指定行指针
       row_loc csr_TestWhile%rowtype;
begin
  --打开游标
       open csr_TestWhile;
       --给第一行喂数据
       fetch csr_TestWhile into row_loc;
       --测试是否有数据,并执行循环
         while csr_TestWhile%found loop
           dbms_output.put_line('部门地点:'||row_loc.LOC);
           --给下一行喂数据
           fetch csr_TestWhile into row_loc;
         end loop;
       close csr_TestWhile;
end; 
--4,接收用户输入的部门编号,用for循环和游标,打印出此部门的所有雇员的所有信息(使用循环游标)
--CURSOR cursor_name[(parameter[,parameter],...)] IS select_statement;
--定义参数的语法如下:Parameter_name [IN] data_type[{:=|DEFAULT} value]  

declare 
      CURSOR 
      c_dept(p_deptNo number)
      is
      select * from emp where emp.depno=p_deptNo;
      r_emp emp%rowtype;
begin
        for r_emp in c_dept(20) loop
            dbms_output.put_line('员工号:'||r_emp.EMPNO||'员工名:'||r_emp.ENAME||'工资:'||r_emp.SAL);
        end loop;
end;

Select for update

select * from test for update; 会对table test进行加锁. 此时只允许当前的session对已经存在的数据进行更新. 但其它session仍可以进行insert的操作.

如果加了for update后 该语句用来锁定特定的行(如果有where子句,就是满足where条件的那些行)。当这些行被锁定后,其他会话可以选择这些行,但不能更改或删除这些行,直到该语句的事务被commit语句或rollback语句结束为止。

for update of columns 用在多表连接锁定时,可以指定要锁定的是哪几张表,而如果表中的列没有在for update of 后面出现的话,就意味着这张表其实并没有被锁定,其他用户是可以对这些表的数据进行update操作的。这种情况经常会出现在用户对带有连接查询的视图进行操作场景下。用户只锁定相关表的数据,其他用户仍然可以对视图中其他原始表的数据来进行操作。

触发器
在Oracle中用:old和:new表示执行前的行,和执行后的行。在MySQL中用old和new表示执行前和执行后的数据。

create or replace trigger test_trigger
  before insert or update on test  
  for each row
declare
  -- local variables here
begin
  :new.c := :new.a + :new.b;
end test_trigger;

Mysql语法:

delimiter //
create trigger trigger1 before insert on person 
for each row 
BEGIN 
        set NEW.pname = 'newname';
END;//

对于INSERT语句,只有NEW是合法的;对于DELETE语句,只有OLD才合法;而UPDATE语句可以在和NEW以及OLD同时使用。

  1. 非常遗憾,MYSQL中触发器中不能对本表进行 insert ,update ,delete 操作,以免递归循环触发
  2. 对于update 只能用set 进行操作,insert与delete只能借助第二张表才能实现需要的目的

Mysql定时任务
1) 首先来看一个简单的例子来演示每秒插入一条记录到数据表

USE test;
      CREATE TABLE aaa (timeline TIMESTAMP);
      CREATE EVENT e_test_insert
       ON SCHEDULE EVERY 1 SECOND
       DO INSERT INTO test.aaa VALUES(CURRENT_TIMESTAMP);

2) 5天后清空test表:

    CREATE EVENT e_test
       ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 5 DAY
       DO TRUNCATE TABLE test.aaa;

3) 2007年7月20日12点整清空test表:

    CREATE EVENT e_test
       ON SCHEDULE AT TIMESTAMP '2007-07-20 12:00:00'
       DO TRUNCATE TABLE test.aaa;

4) 每天定时清空test表:
  

    CREATE EVENT e_test
       ON SCHEDULE EVERY 1 DAY
       DO TRUNCATE TABLE test.aaa;

5) 5天后开启每天定时清空test表:

    CREATE EVENT e_test
       ON SCHEDULE EVERY 1 DAY
       STARTS CURRENT_TIMESTAMP+ INTERVAL 5 DAY
       DO TRUNCATE TABLE test.aaa;

6) 每天定时清空test表,5天后停止执行:

    CREATE EVENT e_test
       ON SCHEDULE EVERY 1 DAY
       ENDS CURRENT_TIMESTAMP+ INTERVAL 5 DAY
       DO TRUNCATE TABLE test.aaa;

ORACLE 定时任务
1、创建测试表

    create table job_test(id integer,add_time date);  

2、创建过程

    create or replace procedure prc_job_test is  
    begin  
      insert into job_test values (SEQ_TM_ID.nextval, sysdate);  
      commit;  
    end prc_job_test;  

3、创建任务

declare  
      tm_job number;  
    begin  
      sys.dbms_job.submit(tm_job, --任务名称  
                          'prc_job_test;',--执行的过程  
                          sysdate,--执行时间  
                          'sysdate+1/(24*60*10)');--下次执行时间  
    end;  

4、查看任务id

    select * from dba_jobs;  

5、执行任务

    begin  
    dbms_job.run(41);--41为任务的id  
    end;   

6、删除任务

    begin  
    dbms_job.remove(41);  
    end;   

JDBC 调用oracle函数和存储过程

//Java调用存储过程和函数
 2 public class OracleDao {
 3     //调用存储过程
 4     @Test
 5     public void callProcedure() throws Exception{
 6         Connection conn = JdbcUtil.getConnection();
 7         //第一参数:in  编号 7902
 8         //第二参数:out 姓名
 9         //第三参数:out 工作
10         //第四参数:out 薪水
11         String sql = "call findEmpNameAndSalAndJob(?,?,?,?)";
12         //创建专用于调用过程或函数的对象
13         CallableStatement cstmt = conn.prepareCall(sql);
14         //为?占位符设置in、out值
15         //hibernate从0开始,jdbc从1开始
16         cstmt.setInt(1,7902);//in值
17         cstmt.registerOutParameter(2,Types.VARCHAR);//out值
18         cstmt.registerOutParameter(3,Types.VARCHAR);//out值
19         cstmt.registerOutParameter(4,Types.INTEGER);//out值
20         cstmt.execute();//抛行调用存储过程
21         //依次接收3个返回值
22         String ename = cstmt.getString(2);
23         String job = cstmt.getString(3);
24         Integer sal = cstmt.getInt(4);
25         //显示
26         System.out.println(ename+"的工作是:" + job + ",它是薪水是" + sal);
27         //关闭连接对象
28         JdbcUtil.close(cstmt);
29         JdbcUtil.close(conn);
30     }
31     //调用存储函数
32     @Test
33     public void callFunction() throws Exception{
34         Connection conn = JdbcUtil.getConnection();
35         //参数一:in  编号 数值型
36         //参数二:out 姓名 字符串型
37         //返回值:out 薪水 数值型
38         String sql = "{? = call findEmpNameAndSal(?,?)}";
39         CallableStatement cstmt = conn.prepareCall(sql);
40         cstmt.setInt(2,7788);//in
41         cstmt.registerOutParameter(3,Types.VARCHAR);//out
42         cstmt.registerOutParameter(1,Types.INTEGER);//返回值
43         cstmt.execute();//执行调用存储函数
44         String ename = cstmt.getString(3);
45         Integer sal = cstmt.getInt(1);
46         System.out.println(ename+"的薪水是"+sal);
47         //关闭连接对象
48         JdbcUtil.close(cstmt);
49         JdbcUtil.close(conn);
50     }
51 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值