数据库编程

PL SQL 块,基本写法

declare -- 声明
  a int;
  b int;
  res int;
begin -- 逻辑开始执行
  a := &a;
  b := &b;
  res := a + b;
  dbms_output.put_line(res); -- 输出到控制台 
end; -- 代码块的结束
--一个例子
declare  --变量声明

  --参照创建表,考虑变量声明和表中数据是否匹配
  v_ename varchar2(10);
  v_sal number(7,2);

begin    --开始执行

  v_ename := &v_ename;
  --into 将查询的结果输出到变量
  select sal into v_sal from emp where ename=v_ename;
  dbms_output.put_line(v_sal);   --输出
  
  --异常处理
  exception 
  when  no_data_found then
    dbms_output.put_line('没有' || v_ename || '这个用户~');

end;

上面的代码:1.定义变量时,我们要参考表的列类型

                      2. 用户输入需要按照指定使用大写

列类型   emp.ename%type  让程序自己去看列类型

行类型    % rowtype

declare  --变量声明

  --参照创建表,考虑变量声明和表中数据是否匹配
  v_ename varchar2(10);
  v_row emp%rowtype;   --自动匹配emp 表的行

begin    --开始执行

  v_ename := &v_ename;
  --into 将查询的结果输出到变量
  select * into v_row from emp where ename=upper(v_ename);
  dbms_output.put_line(v_row.ename || '---' || v_row.sal);   --输出
  
  --异常处理
  exception 
  when  no_data_found then
    dbms_output.put_line('没有' || v_ename || '这个用户~');

end;

循环loop

declare
  x int;
  y int;
begin
  x := &x;
  y := &y;
  loop 
    dbms_output.put_line(x);
    exit when x=y;    --退出循环
    x := x+1;
  end loop;
end;

for循环,主要用于变量集合

declare
  x int;
begin 
  for x in 1..10 
  loop
    dbms_output.put_line(x);
  end loop;
end;

while 循环

declare
  x int;
begin
  x := 1;
  while x <=10 loop
    dbms_output.put_line(x);
    x := x + 1;
  end loop;
end;

分支 if else

/* 分支  if else */
-- 输入员工的姓名, 判断员工的工资等级 
/*
>=2500  D
>=2000  C
>=1500  B
        A
*/

declare 
  v_ename emp.ename%type;
  v_sal emp.sal%type;
begin
  v_ename := &v_ename;
 select sal into v_sal from emp where ename = upper(v_ename);
  if v_sal >= 2500 then
    dbms_output.put_line('D');
  elsif  v_sal >= 2000 then
    dbms_output.put_line('C');
  elsif  v_sal >= 1500 then
    dbms_output.put_line('B');
  else
    dbms_output.put_line('A');
  end if;
end;

游标,遍历结果集

定义:CURSOR <游标名> IS <SELECT 语句> [FOR UPDATE | FOR UPDATE OF 字段];

declare
  --定义游标
  cursor mycur is select * from emp;
  v_row emp%rowtype;
begin
  --打开游标
  open mycur;
  loop  --循环
  fetch mycur into v_row;  --读取了一行数据
  --fetch失败退出循环,此时没有数据了
  exit when mycur%notfound;
  dbms_output.put_line(v_row.ename);
  end loop;
  --关闭游标
  close mycur;
end;

函数,提高代码的重复利用

有且仅有一个返回值

--fn1是函数名()里面是对应的参数,若无参数,则不用写
create function fn1(x int,y int) return int   --函数声明部分
is  --变量声明部分
  res int;
begin 
  res := x+y;
  return res;
end;
--从字典中查看此函数
select * from user_procedures;
--使用
select fn1(1,2) from dual;

存储过程

存储过程 和 函数 都是 过程 
-- 作用, 给第三方调用, 提供第三方调用的接口  Java 
-- 分页的结果 , 得到 总页数,没有的数据集. 提供的参数 页码, 每页的数据量

-- 定义一个游标类型保存到一个 package 中
create package pk_commons is type mycur is ref cursor;
end;

-- in 表示 入参 , out 表示返回值  inout 既可以当入参也可以当出参
create or replace procedure pro_page(
v_current in int, 
v_count in int,
v_page out int,
v_cur out pk_commons.mycur
)
as
  v_total int; -- 总条数
  v_sql varchar2(1000);
  v_s int;
  v_e int;
begin
  select count(ename) into v_total from emp;
  v_page := ceil(v_total/v_count);
  v_s := (v_current-1) * v_count; -- 0 5 10
  v_e := v_current * v_count; -- 5 10 15
  v_sql := 'select * from (select e.*,rownum rn from emp e where rownum <='||v_e||') t  where t.rn >'||v_s;
  open v_cur for v_sql;
end;

-- [授权]
/*
连接到数据库 scott。
执行 PL/SQL: ALTER SESSION SET PLSQL_DEBUG=TRUE
执行 PL/SQL: CALL DBMS_DEBUG_JDWP.CONNECT_TCP( '192.168.100.1', '58011' )
ORA-01031: 权限不足
ORA-06512: 在 "SYS.DBMS_DEBUG_JDWP", line 68
ORA-06512: 在 line 1
此会话需要 DEBUG CONNECT SESSION 和 DEBUG ANY PROCEDURE 用户权限。
进程已退出。
从数据库 scott 断开连接。
*/
grant DEBUG CONNECT SESSION,DEBUG ANY PROCEDURE to scott;

练习

--数据库编程练习
--员工编码 从1000开始 用序列
create sequence seq_emp_id
start with 990
increment by 1
nocycle;
drop sequence seq_emp_id;
select seq_emp_id.nextval from dual;
--dbms_random.string('U',dbms_random.value(3,5))生成一个长度在3到5之间的随机字符串,其中包含大写字母('U'表示大写字母)
--员工姓名
--生成3,5位的随机姓名
select dbms_random.string('U',dbms_random.value(3,5)) from dual;
--若姓名相同,则重新生成

--员工工作,从emp表中的job随机赋值,同时job不能为MANAGER 用随机序列排列,然后是伪列的第一个
select job 
from (
  select job,rownum,dbms_random.value 
  from emp 
  where job!='MANAGER' order by dbms_random.value
) where rownum=1;

--员工领导和部门编码,根据job指定,随机一个即可
select job,mgr,deptno 
from (
  select job,mgr,deptno,rownum,dbms_random.value 
  from emp 
  where job!='MANAGER' order by dbms_random.value
) where rownum=1; 

--入职时间在10--20年之间
select trunc(sysdate)-dbms_random.value(3650,7300) from dual;

--薪资 为所在部门的最低和最高之间
select round(dbms_random.value
((select min(sal) from emp where deptno=
 (select deptno 
 from (
   select job,mgr,deptno,rownum,dbms_random.value 
   from emp 
   where job!='MANAGER' order by dbms_random.value
 ) where rownum=1))
,
 (select max(sal) from emp where deptno=
 (select deptno 
 from (
   select job,mgr,deptno,rownum,dbms_random.value 
   from emp 
   where job!='MANAGER' order by dbms_random.value
 ) where rownum=1))
)) from dual;

--奖金  若job为SALESMAN 则设置奖金,为公司最低和最高之间
select round(dbms_random.value
((select min(comm) from emp)
,
(select max(comm) from emp))) from dual;


--在以上基础开始编程,插入10个员工
declare
  x int;
  v_empno   emp.empno%type;
  v_ename   emp.ename%type;
  v_job     emp.job%type;
  v_mgr     emp.mgr%type;
  v_sal     emp.sal%type;
  v_comm    emp.comm%type;
  v_deptno  emp.deptno%type;
  v_hiredate emp.hiredate%type;
begin 
  for x in 1..10
  loop
  --设置编号
  v_empno := seq_emp_id.nextval;
  --设置名称
  v_ename := dbms_random.string('U',dbms_random.value(3,5));
  --设置入职时间
  v_hiredate := trunc(sysdate)-dbms_random.value(3650,7300);
  --设置工作,领导,部门编码
  select job,mgr,deptno into v_job,v_mgr,v_deptno 
  from (
    select job,mgr,deptno,rownum,dbms_random.value 
    from emp 
    where job!='MANAGER' order by dbms_random.value
  ) where rownum=1;
  --设置工资
  select round(dbms_random.value(
                  (select min(sal) from emp where deptno=v_deptno)
                  ,
                  (select max(sal) from emp where deptno=v_deptno))
              ) 
  into v_sal from dual;
  --设置奖金
  if v_job='SALESMAN' then
    select round(dbms_random.value
          ((select min(comm) from emp)
           ,
          (select max(comm) from emp))) 
    into v_comm from dual;
  else 
    v_comm := null;
  end if;
  
  --插入数据
  insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno)
  values(v_empno,v_ename,v_job,v_mgr,v_hiredate,v_sal,v_comm,v_deptno);
  end loop;
end;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值