plsql笔记

--plsql
--
declare --定义变量
begin --开始运行 代码实现区
exception --异常处理
end;
/ --反斜线
调用包 dbms_output.put_line()
dbms --database base manager system 数据库管理系统
rdbms --relation
--1 
set serveroutput on --打开输出选项
declare
begin
dbms_output.put_line('hello word');
end;
/

--2
--& 地址符
declare
begin
dbms_output.put_line('hello world !'||&name); --输入变量时需要加单引号
end;
/

--3 exception
declare
  v_no1      number;
  v_no2      number;
  v_division number;
begin
  dbms_output.put_line('请输入两个数字:');
  v_no1      := &v_no1;
  v_no2      := &v_no2;
  v_division := v_no1 / v_no2;
  dbms_output.put_line('这两个数字的商是:' || v_no1 || '/' || v_no2 || '=' ||
                       v_division);
exception
  when others then
    --when ZERO_DIVIDE then 
    dbms_output.put_line('输入错误'); --dbms_output.put_line('除数不能为0!')
end;
/
--4 if
declare
  v_no1      number;
  v_no2      number;
  v_division number;
begin
  dbms_output.put_line('请输入两个数字:');
  v_no1      := &v_no1;
  v_no2      := &v_no2;
  v_division := v_no1 / v_no2;
  if 
  end if;
  dbms_output.put_line('这两个数字的商是:' || v_no1 || '/' || v_no2 || '=' ||
                       v_division);
end;

--
declare
  v_no1      number;
  v_no2      number;
  v_division number;
begin
  dbms_output.put_line('请输入两个数字:');
  v_no1 := &v_no1;
  v_no2 := &v_no2;
  if v_no2 = 0 then
    dbms_output.put_line('除数不能为0');
  else
    v_division := v_no1 / v_no2;
    dbms_output.put_line('这两个数字的商是:' || v_division);
  end if;
end;
/
--输入1-7 对应输出星期一 到 星期天
declare
  v_1 number;
  v_2 number;
begin
  v_1 := &v_1;
  v_2 := 1;
  if v_1 = v_2 then
    dbms_output.put_line('星期一');
  elsif v_1 = 2 then
    dbms_output.put_line('星期二');
  elsif v_1 = 3 then
    dbms_output.put_line('星期三');
  elsif v_1 = 4 then
    dbms_output.put_line('星期四');
  elsif v_1 = 5 then
    dbms_output.put_line('星期五');
  elsif v_1 = 6 then
    dbms_output.put_line('星期六');
  elsif v_1 = 7 then
    dbms_output.put_line('星期天');
  end if;
end;

declare
  v_1    number;
  v_date varchar2(10);
begin
  v_1 := &v_1;
  if v_1 = 1 then
    v_date := '星期一';
  elsif v_1 = 2 then
    v_date := '星期二';
  elsif v_1 = 3 then
    v_date := '星期三';
  elsif v_1 = 4 then
    v_date := '星期四';
  elsif v_1 = 5 then
    v_date := '星期五';
  elsif v_1 = 6 then
    v_date := '星期六';
  elsif v_1 = 7 then
    v_date := '星期日';
  else
    v_date := '不符合要求';
  end if;
  dbms_output.put_line(v_date);
end;


--输入1-7 对应输出星期一 到 星期天 输入英文把当前国家改写
declare
  v_1    number;
  v_date varchar2(10);
begin
  v_1 := &v_1;
  select to_char(to_date('20161009', 'yyyymmdd') + mod(v_1, 7), 'day')
    into v_date
    from dual;
  dbms_output.put_line(v_date);
end;

--第二种方法
declare
  v1     number;
  v_date varchar2(10);
begin
  v1 := &v1;
  select to_char(to_date('20161009', 'yyyymmdd') + v1, 'day')
    into v_date
    from dual;
  dbms_output.put_line(v_date);
end;
/

--while语句 loop
--boolean 布尔值
--输入两个数字做商,不符合条件重新输入
declare 
v_1 number;
v_2 number;
v_division number;
begin
v_1:=&v_1;
v_2:=&v_2;
while v_2=0 loop
dbms_output.put_line('被除数为零,重新输入!');
v_1:=&v_1;
v_2:=&v_2;
end loop;
v_division:=v_1/v_2;
dbms_output.put_line('两个数字的商是:'||v_division);
end;
/

declare
  v1         number;
  v2         number;
  v_division number;
begin
  v1 := &v1;
  v2 := &v2;
  if v2 = 0 then
    dbms_output.put_line('被除数不能为零,重新输入');
    v1 := &v1;
    v2 := &v2;
  else
    v_division := v1 / v2;
  end if;
  dbms_output.put_line('两个数字的商是:' || v_division);
end;








--求1+2+3+...+100的值
declare
  v_i   number := 1;
  v_sum number := 0;
begin
  while v_i <= 100 loop
    v_sum := v_sum + v_i;
    v_i   := v_i + 1;
  end loop;
  dbms_output.put_line('1+2+...100的值=' || v_sum);
end;

--用for求1+2+  100的值
declare
  v_sum number := 0;
begin
  for i in 1 .. 100 loop
    v_sum := v_sum + i;
  end loop;
  dbms_output.put_line('1+2+...100的值=' || v_sum);
end;
/
--求1到1000的奇数相加
declare
  v_i   number := 1;
  v_sum number := 0;
begin
  while v_i <= 1000 loop
    v_sum := v_sum + v_i;
    v_i   := v_i + 2;
  end loop;
  dbms_output.put_line('求1到1000的奇数相加=' || v_sum);
end;
--
declare
  v_i   number := 1;
  v_sum number := 1;
begin
  while v_i < 500 loop
    v_sum := v_sum + 2 * v_i + 1;
    v_i   := v_i + 1;
  end loop;
  dbms_output.put_line('求1到1000的奇数相加=' || v_sum);
end;
--用for求1到1000内的奇数之和
declare
  v_sum number := 0;
begin
  for i in 1 .. 500 loop
    v_sum := v_sum + 2 * i - 1;
  end loop;
  dbms_output.put_line('求1到1000的奇数相加=' || v_sum);
end;

--1000之内所有的奇数之和 与偶数之和
declare
  v_i     number := 1;
  v_sum_j number := 0;
  v_sum_o number := 0;
begin
  while v_i <= 500 loop
    v_sum_j := v_sum_j + 2 * v_i - 1;
    v_sum_o := v_sum_o + 2 * v_i;
    v_i     := v_i + 1;
  end loop;
  dbms_output.put_line('1000之内所有的奇数之和=' || v_sum_j);
  dbms_output.put_line('1000之内所有的偶数之和=' || v_sum_o);
end;
--用for计算1000之内所有的奇数之和 与偶数之和
declare
  v_sum_j number := 0;
  v_sum_o number := 0;
begin
  for i in 1 .. 500 loop
    v_sum_j := v_sum_j + 2 * i - 1;
    v_sum_o := v_sum_o + 2 * i;
  end loop;
  dbms_output.put_line('1000之内所有的奇数之和=' || v_sum_j);
  dbms_output.put_line('1000之内所有的偶数之和=' || v_sum_o);
end;
/
--用mod计算1000之内所有的奇数之和 与偶数之和
declare
  v_1     number := 1;
  v_sum_j number := 0;
  v_sum_o number := 0;
begin
  while v_1 <= 1000 loop
    if mod(v_1, 2) = 1 then
      v_sum_j := v_sum_j + v_1;
    else
      v_sum_o := v_sum_o + v_1;
    end if;
    v_1 := v_1 + 1;
  end loop;
  dbms_output.put_line('1000之内所有的奇数之和=' || v_sum_j);
  dbms_output.put_line('1000之内所有的偶数之和=' || v_sum_o);
end;

--2.从键盘录入一个数,判断正负。
declare
  v1    number;
  v_out number;
begin
  v1 := &v1;
  select sign(v1) into v_out from dual;
  if v_out = 1 then
    dbms_output.put_line('');
  elsif v_out = 0 then
    dbms_output.put_line(v_out);
  else
    dbms_output.put_line('');
  end if;
end;
--课堂练习 1+2+3+4+...+ x 从键盘上录入一个整数X,从1一直加到X(以1递增)。
declare
  x     number;
  v_sum number := 0;
begin
  x := &x;
  for i in 1 .. x loop
    v_sum := v_sum + i;
  end loop;
  dbms_output.put_line(v_sum);
end;


--2016-10-13 
--if 条件的写法 
--boolean 布尔值 true false null
 SET SERVEROUTPUT ON FORMAT WRAPPED--在sqlplus窗口执行时输入
if 1<2 and 3<4 then 
dbms_output.put_line('if'); 
else 
dbms_output.put_line('else');
end if;

begin
if not null then
dbms_output.put_line('if'); 
else 
dbms_output.put_line('else');
end if;
end;

begin
if not false then
dbms_output.put_line('if'); 
else 
dbms_output.put_line('else');
end if;
end;





/*打印下面的图形:
*
**
***
****
*****
*/
begin
for i in 1..5 loop
dbms_output.put_line(lpad('*',i,'*'));
end loop;
end;
--
declare
v_len number := 0;
v_str varchar2(100);
begin
  while v_len <= 5 loop
  v_str:=lpad('*',v_len,'*');
  v_len:=v_len+1;
  dbms_output.put_line(v_str);
  end loop;  
end;
/
--
declare
v_len number := 0;
v_str varchar2(100);
begin
  while v_len < 5 loop
  v_str:=v_str || '*';
  v_len:=v_len+1;
  dbms_output.put_line(v_str);
  end loop;  
end;
 

/*打印下面的图形
     *
    ***
   *****
  *******
 *********
  *******
   *****
    ***
     *
*/

declare
v_blank varchar2(100);
v_xing varchar2(100);
begin
  for i in 1 .. 5 loop
    v_blank := substr('    ',i);
    v_xing := lpad('*', 2 * i - 1, '*');
    dbms_output.put_line(v_blank || v_xing);
  end loop; 
  
  v_blank:='';
  v_xing:='';
  
  for i in reverse 1 .. 4 loop
    v_blank:=('    ',i);
    v_xing:=lpad('*', 2 * i - 1, '*');
    dbms_output.put_line(v_blank || v_xing);
  end loop; 
end;
/
declare
v_blank varchar2(100);
v_xing varchar2(100);
begin
  for i in 1 .. 5 loop
    v_blank := substr('    ',i);
    v_xing := lpad('*', 2 * i - 1, '*');
    dbms_output.put_line(v_blank || v_xing);
  end loop;
  v_blank:='';
  v_xing:='';
  for i in reverse 1 .. 4 loop
  v_blank := substr('    ',i);
    v_xing := lpad('*', 2 * i - 1, '*');
    dbms_output.put_line(v_blank||v_xing);
  end loop;  
end;
/


declare
v_blank varchar2(100);
v_xing varchar2(100);
begin
  for i in reverse 1 .. 4 loop
    --v_blank := lpad(' ', 4 - i, ' ');
    v_blank := substr('   ',i);
    v_xing := lpad('*', 2 * i - 1, '*');
    dbms_output.put_line(v_blank || v_xing);
  end loop;
  
end;
/
/*打印下面的图形
     *
    ***
   *****
  *******
 *********
  *******
   *****
    ***
     *
*/
declare
  v_blank varchar2(100);
  v_xing  varchar2(100);
  v_num   number;
begin
  for i in 1 .. 9 loop
    v_num   := 5 - abs(5 - i);
    v_blank := substr('    ', v_num);
    v_xing  := lpad('*', 2*v_num - 1, '*');
    dbms_output.put_line(v_blank || v_xing);
  end loop;
end;

--九九乘法表 
declare
  v_str     varchar2(200);
  v_str_sum varchar2(200);
  v_num number;
begin
  for i in 1 .. 9 loop
    v_str_sum := '';
    for j in 1 .. i loop
      v_str     := i || '*' || j;
      v_str_sum := v_str_sum || ' ' || v_str;
      --v_num:=i*j;
    end loop;
    dbms_output.put_line(v_str_sum);
     --dbms_output.put_line(v_num);
  end loop;
end;
/
declare
  v_str     varchar2(200);
  v_str_sum varchar2(200); 
begin
  for i in 1 .. 9 loop
    v_str_sum := '';
    for j in 1 .. i loop
      v_str     := i || '*' || j||'='||i*j;
      v_str_sum := v_str_sum || ' ' || v_str;        
    end loop;
    --dbms_output.put_line(trim(v_str_sum));
    --dbms_output.put_line(substr(v_str_sum,2)); 
    dbms_output.put_line(ltrim(v_str_sum));     
  end loop;
end;
--
declare
  v_str       varchar2(200);
  v_str_sum   varchar2(200);
  c_multi_max number := 9;
  v_len       number;
begin
  for i in 1 .. c_multi_max loop
    v_str_sum := '';
    for j in 1 .. i loop
      v_len     := length(c_multi_max || '*' || j || '=' || c_multi_max * j);
      v_str     := i || '*' || j || '=' || i * j;
      v_str     := rpad(v_str, v_len + 1, ' ');
      v_str_sum := v_str_sum || ' ' || v_str;
    end loop;
    dbms_output.put_line(v_str_sum);
  end loop;
end;


--plsql datatype
declare 
begin
dbms_output.put_line(BINARY_FLOAT_MAX_NORMAL);
end;
/
declare 
p1 pls_integer :=1;
p2 integer :=1;

--record 集合类型
declare 
type emp_record is record(id number,name varchar2(200));
emp_rec emp_record;
begin 
emp_rec.id :=1;
emp_rec.name:=0;
dbms_output.put_line(emp_rec.id||emp_rec.name);
null;
end;


--
declare 
type emp_record is record(empno number,ename varchar2(200));
emp_rec emp_record;
begin 
select empno,ename into emp_rec from emp where rownum=1;
dbms_output.put_line(emp_rec.empno||emp_rec.ename);
end;
--
declare 
type dept_record is record(deptno number,dname varchar2(10),loc varchar2(20));
dept_rec dept_record;
begin
select deptno,dname,loc into dept_rec from dept where rownum=1;
dbms_output.put_line('部门编号是:'||dept_rec.deptno||', 部门名称'||dept_rec.dname||', 地址是'||dept_rec.loc);
end;
--
declare 
v_deptno number;
v_dname varchar2(10);
v_loc varchar2(10);
begin
select deptno,dname,loc into v_deptno,v_dname,v_loc from dept where rownum=1;
dbms_output.put_line('部门编号是:'||v_deptno||', 部门名称'||v_dname||', 地址是'||v_loc);
end;

--returning 
declare 
type dept_record is record(deptno number,dname varchar2(10),loc varchar2(20));
dept_rec dept_record;
begin
update dept set deptno='50',dname='北京' where rownum=1 
returning deptno,dname into dept_rec;
dbms_output.put_line('修改后的部门编号是:'||dept_rec.deptno||', 部门名称'||dept_rec.dname||', 地址是'||dept_rec.loc);
end;
--定义表类型
declare 
type emp_table is table of emp%rowtype;
emp_tab emp_table;
cursor cur_emp is select * from emp where rownum=1;
begin 
open cur_emp;
fetch cur_emp bulk collect into emp_tab;
dbms_output.put_line(emp_tab(1).ename);
close cur_emp;
end;


--
declare 
type emp_record is record(empno number,ename varchar2(100));
emp_rec emp_record;
cursor cur_emp is select empno,ename from emp;
begin 
open cur_emp;
for i in 1..14 loop
fetch cur_emp into emp_rec;
dbms_output.put_line(emp_rec.empno||' 的姓名是 '||emp_rec.ename);
--exit when cur_emp%notfound;
end loop;
close cur_emp;
end;
--
declare 
type emp_record is record(empno emp.empno%type,ename emp.ename%type);
emp_rec emp_record;
begin
update emp set empno='222',ename='' where rownum=1
returning empno,ename into emp_rec;
dbms_output.put_line('修改后: '||emp_rec.empno||' 的姓名是 '||emp_rec.ename);
end;
--
declare 
type emp_table is table of emp%rowtype index by binary_integer;
emp_tab emp_table;
cursor cur_emp is select * from emp;
begin
open cur_emp;
fetch cur_emp bulk collect into emp_tab;
/*for i in 1..emp_tab.count loop
dbms_output.put_line(emp_tab(i).empno||' 姓名是'||emp_tab(i).ename);
end loop;*/
for i in emp_tab.first..emp_tab.last loop
dbms_output.put_line(emp_tab(i).empno||' 的姓名是'||emp_tab(i).ename);
end loop;
close cur_emp;
end;
--
declare 
type emp_table is table of emp%rowtype index by binary_integer;
emp_tab emp_table ;
cursor cur_emp is select * from emp;
begin
open cur_emp;
fetch cur_emp bulk collect into emp_tab;
forall i in emp_tab.first..emp_tab.last
update emp set job='111' where ename=emp_tab(i).ename;
dbms_output.put_line('执行成功');
close cur_emp;
end;


---2016-10-15
create table wzh_t_empno --创建表
(
row_flag number(2),
empno number(4)
);

select * from wzh_t_empno;

create or replace procedure sp_cursor_fetch_wzh is --创建存储过程
  --DECLARE
  v_sid emp.empno%TYPE; --定义与emp中empno列相同的存储类型的定义变量
  i     number;

  CURSOR c_emp IS  --定义游标
    SELECT empno FROM emp WHERE sal>2000;--deptno=20;--empno < 7599;获取数据集给游标
BEGIN
  i := 0;
  OPEN c_emp;
  LOOP
    FETCH c_emp  --获取每行游标的数据
      INTO v_sid;  --赋值给变量v_sid
    EXIT WHEN c_emp%NOTFOUND; --如果游标没有数据,做异常处理,直接退出循环
    i := i + 10; --按规律递增
    insert into wzh_t_empno (row_flag, empno) values (i, v_sid); --插入数据到表中 
  END LOOP; --循环结束
  commit;
  CLOSE c_emp; --关闭游标
EXCEPTION
  WHEN OTHERS THEN
    IF c_emp%ISOPEN THEN --若游标未正常关闭,则关闭游标
      CLOSE c_emp;
    END IF;
END;

call scott.sp_cursor_fetch_wzh();
select * from wzh_t_empno;

--2016-10-16
-- 1 dept ,T_DEPT_DIM_WZH 
-- 2 用游标e_dept取出dept表的数据 
-- 3 用for循环游标的每一行 
-- 4 判断游标c_dept的deptno和name的对应记录是否在T_DEPT_DIM_WZH
-- 5 若不在,插入新记录 
create or replace procedure sp_wzh_test is 
v_deptno dept.deptno%type;
v_dname dept.dname%type;
v_rowcount number(5);
v_wid number(5):=1;
cursor c_dept is 
select deptno,dname from dept;
begin 
for i in c_dept loop 
v_deptno:=i.deptno;
v_dname:=i.dname;
select count(*) into v_rowcount from T_DEPT_DIM_WZH a
where a.deptno=v_deptno and a.dname=v_dname;
if v_rowcount=0 then 
insert into T_DEPT_DIM_WZH values (v_wid,v_deptno,v_dname,'Y');
v_wid:=v_wid+1;
end if;
end loop;
commit;
end;

--
create or replace procedure sp_wzh_test is 
v_deptno dept.deptno%type;
v_dname dept.dname%type;
v_rowcount number(5);
v_wid number(5):=1;
cursor c_dept is 
select deptno,dname from dept;
begin 
for i in c_dept loop 
v_deptno:=i.deptno;
v_dname:=i.dname;
select count(*) into v_rowcount from T_DEPT_DIM_WZH a
where a.deptno=v_deptno and a.dname=v_dname;
if v_rowcount=0 then 
insert into T_DEPT_DIM_WZH values (v_wid,v_deptno,v_dname,'Y');
select max(wid) into v_wid from T_DEPT_DIM_WZH;
v_wid:=v_wid+1;
end if;
end loop;
commit;
end;

--2016-10-18
--游标
declare 
v_empno emp.empno%type;
begin 
select empno into v_empno from emp where rownum=1;
dbms_output.put_line(v_empno);
end;
-- if sql%found then dbms_output.put_line() 查看是否游标
/* if sql%isopen then 
   dml语句都会产生游标*/
-- sql%rowcount  

declare
  type emp_refcur is ref cursor;
  emp_cur emp_refcur;
  emprow  emp%rowtype;
begin
  open emp_cur for
    select * from emp;
  loop
    fetch emp_cur
      into emprow;
    exit when emp_cur%notfound;
    dbms_output.put_line(emprow.empno);
  end loop;
  close emp_cur;

  /*open emp_cur for select * from emp --where deptno=10;
  loop
  fetch emp_cur into emprow;
  dbms_output.put_line(emprow.empno);
  exit when emp_cur%notfound;
  end loop;
  close emp_cur;*/ --可以多次调用
end;




-------
declare
  type emp_refcur is ref cursor; --return emp%rowtype;--必须返回所有行
  emp_cur  emp_refcur;
  emprow   emp%rowtype;
  deptrow  dept%rowtype;
  emp_sysc sys_refcursor; --可以接受任意值 多行多列 没有类型的划分
  salrow   salgrade%rowtype;
begin
  open emp_cur for
    select * from emp;
  loop
    fetch emp_cur
      into emprow;
    dbms_output.put_line(emprow.empno);
    exit when emp_cur%notfound;
  end loop;
  close emp_cur;
  dbms_output.put_line('=============================');
  for i in (select * from emp) loop
    dbms_output.put_line(i.empno);
  end loop;
  dbms_output.put_line('=============================');
  open emp_cur for
    select * from dept;
  loop
    fetch emp_cur
      into deptrow;
    exit when emp_cur%notfound;
    dbms_output.put_line(deptrow.dname);
  end loop;
  close emp_cur;
  dbms_output.put_line('=============================');
  open emp_sysc for
    select * from salgrade;
  loop
    fetch emp_sysc
      into salrow;
    exit when emp_sysc%notfound;
    dbms_output.put_line(salrow.losal);
  end loop;
  close emp_sysc;
end;

--网站资料 http://www.2cto.com/database/201402/282081.html
--http://blog.itpub.net/7607759/viewspace-710233

---
declare 
type emp_refcur is ref cursor; --return emp%rowtype;
emp_cur emp_refcur;
emprow emp%rowtype;
deptrow dept%rowtype;
cursor emp_c is select * from emp;
emp_sysc sys_refcursor;
salrow salgrade%rowtype;
begin
  open emp_cur for select * from emp ;  
  loop
  fetch emp_cur into emprow;
  exit when emp_cur%notfound;
  dbms_output.put_line(emprow.ename || ' ' || emprow.sal);
  end loop;   
  close emp_cur;

  dbms_output.put_line('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
  for i in ( select ename,sal from emp) loop
  dbms_output.put_line(i.ename || ' ' || i.sal);
  end loop;

  dbms_output.put_line('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
  open emp_c ;  
  loop
  fetch emp_c into emprow;
  exit when emp_c%notfound;
  dbms_output.put_line(emprow.ename || ' ' || emprow.sal);
  end loop;  
  close emp_c;
  
  dbms_output.put_line('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
  open emp_cur for select * from dept;  
  loop
  fetch emp_cur into deptrow;
  exit when emp_cur%notfound;
  dbms_output.put_line(deptrow.dname || ' ' || deptrow.loc);
  end loop;  
  close emp_cur;  
  
  dbms_output.put_line('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
  open emp_sysc for select * from salgrade;
    loop
  fetch emp_sysc into salrow;
  exit when emp_sysc%notfound;
  dbms_output.put_line(salrow.grade || ' ' || salrow.losal);
  end loop;  
  close emp_sysc; 

end;


--2016-10-19
--游标

--定义计数类型
--定义表类型
--定义显示游标
--带参数游标
declare 
type emp_record is record (
v_empno emp.empno%type,
v_ename emp.ename%type);
emp_rec emp_record;
cursor cur_emp is select empno,ename from emp;
begin 
--用fetch打开游标
open cur_emp;
loop 
fetch cur_emp into emp_rec;
exit when cur_emp%notfound;
dbms_output.put_line(emp_rec.v_empno);
end loop;
close cur_emp;
--for循环打开
--for循环隐式打开
--dml 取一行数据
select empno,ename into v_empno,v_ename from emp where rownum=1;
dbms_output.put_line(v_empno||v_ename);
--dml多行数据 放入表类型中
select empno,ename into emp_tab from emp;
--定义表类型
end;



--定义带参数游标 
cursor cur_emp(indeptno number) is select empno,ename from emp where deptno=indeptno;
begin 
for i in cur_emp loop 
dbms_output.put_line();
end;

--游标变量 动态
type emp_ref is ref cursou;
emp_ref_cur emp_ref;
emp_row emp%rowtype;
begin 
open emp_ref_cur for 'select * from emp'; --游标数据与接受变量相对应
loop 
fetch emp_ref_cur into emp_row;
exit when emp_ref_cur%notfound;
dbms_output.put_line();
end loop;
close emp_ref_cur;
end;
--做返回集  emp_sys_cur sys_refcursor 
emp_sys_cur sys_refcursor --用来返回结果


--存储过程  存储过程 存储过程是一组带程序处理逻辑的过程。可选输入、输出参数。 
create or replace procedure blank is
  v_blank varchar2(100);
  v_xing  varchar2(100);
  v_num   number;
begin
  for i in 1 .. 9 loop
    v_num   := 5 - abs(5 - i);
    v_blank := substr('    ', v_num);
    v_xing  := lpad('*', 2 * v_num - 1, '*');
    dbms_output.put_line(v_blank || v_xing);
  end loop;
end;

--创建带输入输出参数的存储过程
  create or replace procedure blank(n int := 9, a out varchar2) is
    v_blank varchar2(100);
    v_xing  varchar2(100);
    v_num   number;
  begin
    if mod(n, 2) = 0 then
      a := '输入的是偶数';
    else
      a := '输入的是奇数';
      begin
        for i in 1 .. n loop
          v_num   := (n + 1) / 2 - abs((n + 1) / 2 - i);
          v_blank := substr(lpad(' ', (n - 1) / 2, ' '), v_num);
          v_xing  := lpad('*', 2 * v_num - 1, '*');
          dbms_output.put_line(v_blank || v_xing);
        end loop;
      end;
    end if;
  end;
--有输入输出参数时 调用存储过程
--调用时注意存储过程中的输入输出参数 对应关系
--用=>可以选择需要输入的参数 有默认值时
  declare
    v_pri varchar2(100) := '你好'; --默认值
  begin
    dbms_output.put_line(v_pri); --开始时是默认值
    blank(11, v_pri); --输入参数 赋值给变量
    dbms_output.put_line(v_pri); --现在v_pri值为存储过程中的输出值
    dbms_output.put_line('=====================');
    blank(a => v_pri); --输入值有默认值时 输出赋值给v_pri用a=>v_pri 不能直接用blank( v_pri);
    dbms_output.put_line(v_pri);
    dbms_output.put_line('=====================');
    blank(8, v_pri);
    dbms_output.put_line(v_pri);
    dbms_output.put_line('=====================');
    dbms_output.put_line(v_pri);
  end;

--调用dbms_rowid包中的rowid_info存储过程
  declare
    ls_my_rowid   varchar2(200);
    rowid_type    number;
    object_number number;
    relative_fno  number;
    block_number  number;
    row_number    number;
  begin
    dbms_rowid.rowid_info('AAAWFqAAEAAABIcAAA',
                          rowid_type,
                          object_number,
                          relative_fno,
                          block_number,
                          row_number);
    ls_my_rowid := 'Object# is      :' || to_char(object_number) || chr(10) ||
                   'Relative_fno is :' || to_char(relative_fno) || chr(10) ||
                   'Block number is :' || to_char(block_number) || chr(10) ||
                   'Row number is   :' || to_char(row_number);
    dbms_output.put_line(ls_my_rowid);
  end;
----调用dbms_rowid包中的rowid_info存储过程
--创建函数
  create or replace function get_rowid(l_rowid in varchar2) return varchar2 is
    ls_my_rowid   varchar2(200);
    rowid_type    number;
    object_number number;
    relative_fno  number;
    block_number  number;
    row_number    number;
  begin
    dbms_rowid.rowid_info(l_rowid,
                          rowid_type,
                          object_number,
                          relative_fno,
                          block_number,
                          row_number);
    ls_my_rowid := 'Object# is      :' || to_char(object_number) || chr(10) ||
                   'Relative_fno is :' || to_char(relative_fno) || chr(10) ||
                   'Block number is :' || to_char(block_number) || chr(10) ||
                   'Row number is   :' || to_char(row_number);
    return ls_my_rowid;
  end;
--通过函数查看参数
  select get_rowid(rowid) from emp;


--编写一个存储过程 synscottinfo(1111,'张三','MANAGER','2011-09-01',6000,NULL,90,'SCIENCE','SHENZHENG')
--要求根据人员编号同步信息,如果没有添加

--编写一个存储过程 synScottInfo 要求根据人员编号同步信息,如果没有添加
EXEC synScottInfo(1111,'张三','MANAGER',7839,'2011-09-01',
6000,NULL,90,'SCI-TECH','SHENZHEN');

EXEC synScottInfo(7369,'SMITH','CLERK','1980-12-17',
1000,NULL,20,'RESEARCH','DALLAS');

select * from emp;
select * from dept;

create procedure synScottInfo

is
--编写一个存储过程 synScottInfo 要求根据人员编号同步信息,如果没有添加
EXEC synScottInfo(1111,'张三','MANAGER','2011-09-01',
6000,NULL,90,'SCI-TECH','SHENZHEN');

EXEC synScottInfo(7369,'SMITH','CLERK','1980-12-17',
1000,NULL,20,'RESEARCH','DALLAS');

select * from emp;
select * from dept;


create procedure synScottInfo

is

begin
  
end;
--编写一个存储过程 synScottInfo 要求根据人员编号同步信息,如果没有添加
--批处理时 可以提交
--出现问题 不往下面执行时可以用ruturn 可以回滚 前面没有提交
EXEC synScottInfo(1111,'张三','MANAGER',7839,'2011-09-01',
6000,NULL,90,'SCI-TECH','SHENZHEN');

EXEC synScottInfo(7369,'SMITH','CLERK',7839,'1980-12-17',
1000,NULL,20,'RESEARCH','DALLAS');

exec synscottinfo (1111,'','MANAGER',7839,'2011-09-01',6000,NULL,90,'SCI-TECH','SHENZHEN')

select * from emp;
select * from dept;


create or replace procedure synScottInfo(
in_empno emp.empno%type,
in_ename inarchar2,
in_job inarchar2,
in_mgr number,
in_hiredate inarchar2,
in_sal number,
in_comm number,
in_deptno number,
in_dname inarchar2 default null,
in_loc inarchar2 default null);
is

v_empno emp.empno%type;
v_ename varchar2:=in_ename;
v_job varchar2:=in_job;
v_mgr number,
v_hiredate varchar2,
v_sal number,
v_comm number,
v_deptno number,
v_dname varchar2 default null,
v_loc varchar2 default null);

begin
null;
end;

create or replace procedure synScottInfo
(inEmpno number,
inEname varchar2,
inJob varchar2, 
inMgr number,
inHiredate varchar2,
inSal number,
inComm number,
inDeptno number,
inDname varchar2 default null,
inLoc varchar2 default null)
is
v_ename emp.ename%type := upper(trim(inEname));
v_job emp.job%type := upper(trim(inJob));
v_inhiredate varchar2(20) := trim(inHiredate);
v_dname dept.dname%type := upper(trim(inDname));
v_loc dept.loc%type := upper(trim(inLoc));
v_hiredate date;
v_cnt number;
begin
  if inEmpno is null or inDeptno is null or v_ename is null or v_job is null then
    dbms_output.put_line('输入信息错误');
    return;
  end if;

  select nvl2(v_inhiredate,to_date(v_inhiredate,'yyyy-mm-dd'),trunc(sysdate)) into v_hiredate from dual;

  select count(*) into v_cnt from dept where deptno = inDeptno;
  if v_dname is not null and v_loc is not null and v_cnt = 0 then
    dbms_output.put_line('插入部门信息');
    insert into dept values (inDeptno,v_dname,v_loc);
  elsif v_cnt = 1 then
    if  v_dname is null and v_loc is null then
      null;
    else
      dbms_output.put_line('更新部门信息');
      update dept set dname = nvl(v_dname, dname) , loc = nvl(v_loc, loc) 
      where deptno = inDeptno;
    end if;
  else 
    dbms_output.put_line('部门信息有误');
    rollback;
    return;
  end if;

  /*if v_dname is not null and v_loc is not null and v_cnt = 0 then
    dbms_output.put_line('插入部门信息');
    insert into dept values (inDeptno,v_dname,v_loc);
  elsif v_cnt = 1 and v_dname is null and v_loc is null then
    null;
  elsif v_cnt = 1 and v_dname is not null and v_loc is not null then
    dbms_output.put_line('更新部门信息');
    update dept set dname = v_dname, loc = v_loc where deptno = inDeptno;
  elsif v_cnt = 1 and v_dname is null and v_loc is not null then
    update dept set loc = v_loc where deptno = inDeptno; 
  elsif v_cnt = 1 and v_dname is not null and v_loc is null then
    update dept set dname = v_dname where deptno = inDeptno; 
  else 
    dbms_output.put_line('部门信息有误');
    return;
  end if;*/

  select count(*) into v_cnt from emp where empno = inEmpno;
  if v_cnt = 0 then
    dbms_output.put_line('插入人员信息');
    insert into emp values (inEmpno,v_ename,v_job,inMgr,v_hiredate,inSal,inComm,inDeptno);
  else
    dbms_output.put_line('更新人员信息');
    update emp set ename = v_ename, job = v_job, mgr = inMgr, hiredate = v_hiredate, 
    sal = inSal, comm = inComm, deptno = inDeptno
    where empno = inEmpno;
  end if;
  
  dbms_output.put_line('完成任务');
  null;
  commit;
end;

--动态sql
declare
  v_sql   varchar2(32000);
  v_ename varchar2(100);
begin
  v_sql := 'select ename from emp where rownum=1';
  execute immediate v_sql
    into v_ename;
  dbms_output.put_line('第一行姓名是' || v_ename);
  
   v_sql := 'select ename from emp where rownum=1';
  execute immediate 'select ename from emp where rownum=1' --字符代码 执行一个字符串去掉引号可以执行
    into v_ename;
    --字符串是正确的sql命令
  dbms_output.put_line('第一行姓名是' || v_ename);
  dbms_output.put_line('=========================');
  dbms_output.put_line('删除表中第一行');
  v_sql := 'delete from emp where rownum=1';
  execute immediate v_sql;
  dbms_output.put_line('删除完成');
  dbms_output.put_line('=========================');
  v_sql := 'select ename from emp where rownum=1';
  execute immediate v_sql
    into v_ename;
  dbms_output.put_line('第一行姓名是' || v_ename);
end;


select * from user_tables;

/*求100至110之间的素数*/
DECLARE
   v_m NUMBER := 101;
   v_i NUMBER;
   v_n NUMBER := 0;
BEGIN
   WHILE v_m < 110 LOOP
      v_i := 2;
      LOOP
         IF mod(v_m, v_i) = 0 THEN
            v_i := 0;
            EXIT;
         END IF;
    
         v_i := v_i + 1;
         EXIT WHEN v_i > v_m - 1; 
      END LOOP;
      
      IF v_i > 0 THEN
         v_n := v_n + 1;
         DBMS_OUTPUT.PUT_LINE(''|| v_n || '个素数是' || v_m);
      END IF;

      v_m := v_m + 2;
   END LOOP;
END;

猜你喜欢

转载自www.cnblogs.com/wangzihong/p/9291580.html
今日推荐