`
kodak_zhou
  • 浏览: 136632 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

PL/SQL 的学习日志(转)

阅读更多
《PL/SQL编程》                            
/*procedural language/sql*/
--1、过程、函数、触发器是pl/sql编写的
--2、过程、函数、触发器是在oracle中的
--3、pl/sql是非常强大的数据库过程语言
--4、过程、函数可以在java程序中调用

--提高效率:优化sql语句或写存储过程
--pl/sql移植性不好

--IDE(Integration Develop Environment)集成开发环境

--命令规则:
--变量(variable)           v_
--常量(constant)           c_
--指针、游标(cursor)         _cursor
--例外、异常(exception)    e_

--可定义的变量和常量:
  --标量类型:scalar
  --复合类型:composite    --存放记录、表、嵌套表、varray
  --参照类型:reference
  --lob(large object)
 


《PL/SQL 基本语法》
--例:创建存储过程
create or replace procedure pro_add
is
begin
  insert into mytest values('韩xx','123');
end;
exec pro_add; --调用

--查看错误信息
show error;
--调用过程
exec 过程(c1,c2,...);
call 过程(c1,c2,...);
--打开/关闭输出选项
set serveroutput on/off
--输入
&

--块结构示意图
declare   --定义部分,定义常量、变量、游标、例外、复杂数据类型
begin     --执行部分,执行pl/sql语句和sql语句
exception --例外处理部分,处理运行的各种错误
end;      --结束


--《实例演示》
declare
  v_ival number(4) :=100; --声明并初始化变量
  --v_dtm date;
  v_dtm syslogs.dtm%type; --取表字段类型
  v_content varchar(512);
begin
  v_ival := v_ival * 90;  --赋值运算
  insert into syslogs values(seq_syslogs.nextval,10,sysdate,'v_ival='||v_ival,user);--数据库存储
  dbms_output.put_line('v_ival'||v_ival);
 
  select count(*) into v_ival from syslogs;--使用select查询赋值
--select ename,sal into v_name,v_sal from emp where empno=&aa;
  insert into syslogs values (seq_syslogs.nextval,10,sysdate,'日志条数='||v_ival,user);
  dbms_output.put_line('日志条数'||v_ival);
  
  --获取日志序号==11的日志时间和日志内容
  select dtm , content
  into v_dtm,v_content
  from syslogs
  where logid=14;
 
  insert into syslogs values (seq_syslogs.nextval,'10',sysdate,'v_dtm='||v_dtm||'v_content='||v_content,user);
  dbms_output.put_line('v_dtm='||v_dtm||'v_content='||v_content);
  --修改日志序号=11的日志记录人
  update syslogs
  set whois='PL/SQL.'||v_ival
  where logid = 14;
 
  --delete syslogs where logid=15;
 
  --分支流程控制
  if v_ival>50 then
    dbms_output.put_line('日志需要清理了~');
  else
    dbms_output.put_line('日志空间正常!');
  end if;
 
  --Loop循环
  v_ival :=0;
  loop
      exit when v_ival>3;
           --循环体
           v_ival := v_ival+1;
           dbms_output.put_line('loop循环:'||v_ival);
  end loop;
 
  --While循环
  v_ival := 0;
  while v_ival < 4
  loop
     --循环体
     v_ival := v_ival+1;
     dbms_output.put_line('while循环:'||v_ival);
  end loop;
 
  --For循环
  for v_count in reverse 0..4 loop  --reverse递减
      dbms_output.put_line('for循环:'||v_count);  
  end loop;
  commit;--提交事物
end;

select * from syslogs;





《PL/SQL 异常处理》
--PL/SQL异常处理:oracle内置异常,oracle用户自定义异常
declare
   v_title logtypes.tid%type;
   v_ival number(9,2);
   --自定义的异常
   ex_lesszero exception ;
begin
  --select title into v_title
  --from logtypes     --;  too_many_rows
  --where tid = 30 ;  --NO_DATA_FOUND 异常
 
  v_ival := 12/-3;
 
  if v_ival < 0 then
    --直接抛出异常
    --raise ex_lesszero ;
    --使用系统存储过程抛出异常
    raise_application_error(/*错误代码,-20000~-20999*/-20003,/*异常描述*/'参数不能小于0!');
  end if; 
  commit;
exception
  --异常处理代码块
  when no_data_found then
    dbms_output.put_line('发生系统异常:未找到有效的数据!');
  when too_many_rows then
    dbms_output.put_line('发生系统异常:查询结果超出预期的一行!');
  when ex_lesszero then
    dbms_output.put_line('发生用户异常:数值不能为负!'||sqlcode||'异常描述:'||sqlerrm);
  when others then --other例如Exception
    rollback;
    dbms_output.put_line('发生异常!'||sqlcode||'异常的描述:'||sqlerrm);
end;





《PL/SQL 游标的使用》

declare
    --游标的声明
    cursor myCur is
           select tid,title from logtypes ;
    --定义接收游标中的数据变量
    v_tid   logtypes.tid%type;
    v_title logtypes.title%type;
    --通过记录来接受数据
    v_typercd myCur%rowtype ;
begin
    --打开游标
    open myCur ;
    --取游标中的数据
    loop
      --遍历游标中的下一行数据
      fetch myCur into v_tid,v_title ;
      --检测是否已经达到最后一行
      exit when myCur%notfound ;
      --输出游标中的数据
      dbms_output.put_line('读取tid='||v_tid||' title='||v_title);
    end loop;
    --关闭游标
    close myCur;
   
    --打开游标
    open myCur ;
    loop
      fetch myCur into v_typercd ;
      exit when myCur%notfound ;
      dbms_output.put_line('--//读取tid='||v_typercd.tid||' title='||v_typercd.title);
    end loop;
    --关闭游标
    close myCur ;
   
    --for循环游标
    for tmp_record in myCur loop
      dbms_output.put_line('++//读取tid='||tmp_record.tid||' title='||tmp_record.title);
    end loop;

end;






《PL/SQL 存储过程★》

--            可以声明入参in,out表示出参,但是无返回值。
create or replace procedure prc_writelog(/*日志类型*/ tid in number ,
                              /*日志内容*/ content in varchar2 ,
                              /*错误码  */ i_ret out number ,
                              /*错误描述*/ s_ret out varchar2 )
is

begin
      insert into syslogs values (seq_syslogs.nextval , tid ,sysdate ,content ,user);
      commit;
      i_ret := 1 ;
      s_ret := '记录日志成功!' ;
exception
    when others then
         rollback ;
         i_ret := -1 ;
         s_ret := '记录日志失败:'||sqlerrm ; 
end;

--测试
declare
  iRet number(4) ;
  sRet varchar2(128) ;
begin
  prc_writelog(10,'测试存储过程',iRet,sRet);
  dbms_output.put_line('iRet:'||iRet||'sRet'||sRet);
end;

select * from syslogs;





《PL/SQL 触发器》


--触发器 是一种基于数据库特定事件的 由数据库自动执行的pl/sql块
--触发的事件源:database 【启动、停止、用户联机...】
--              表名【insert/update/delete】
--触发时机 before/after
--语句级、行级(需要知道数据,对数据库运行速度有影响)
create or replace trigger tri_logtypes
after insert or update or delete --在所有的表的事件发生后执行
on logtypes
for each row --行级 (:new ,ld)
declare
    iret number(4);
    sret varchar2(128);
begin
    --不要有事物的管理
    --:new 新数据 记录型
    --:old 原有的数据 记录型
    --prc_writelog(10,'触发器执行了!',iret,sret);
    if inserting then
        insert into syslogs values(seq_syslogs.nextval,10,sysdate,'触发器执行添加数据!',user);
    elsif updating then
        if :new.title <>ld.title then
           raise_application_error(-20001,'不允许修改日志类型名称数据!');    --抛出异常
        end if;
        insert into syslogs values(seq_syslogs.nextval,10,sysdate,'触发器执行更新数据!',user);
    elsif deleting then
        raise_application_error(-20001,'不允许删除表中的数据!');
        insert into syslogs values(seq_syslogs.nextval,10,sysdate,'触发器执行删除数据!',user);
    end if;
end ;

--test!
insert into logtypes values(30,'test log');
delete from logtypes where tid = 30;
update logtypes set title = 'test log' where tid = 30;

select * from syslogs order by dtm desc;
select * from logtypes ;





《案例》


--创建表
create table emp2 (
  name varchar2(30),
  sal number(8,2)
);
insert into emp2 values('simple',99999);
insert into emp2 values(&a,&b);

--存储过程案例:
--修改员工工资
create or replace procedure pro_input(t_name in varchar2,
                           t_sal in number)
is
begin
  update emp2 set sal = t_sal where name=t_name;
end;
--Test!
declare
begin
  pro_input('simple',2000);
end;
select * from emp2;

--函数案例:
create or replace function fun_test(t_name varchar2)
return number is yearSal number(7,2);
begin
  select sal*12 into yearSal from emp2 where name = t_name;
  return yearSal;
end;

--包案例:
create package pac_test
is                           --创建一个包pac_test
  procedure pro_input(t_name varchar2,t_sal number); --声明该包有一个过程 pro_input
  function fun_test(t_name varchar2) return number;  --声明该包有一个函数 fun_test
end;

--包体案例:
create package body pac_test
is
  procedure pro_input(t_name in varchar2,t_sal in number)
  is
  begin
    update emp2 set sal = t_sal where name=t_name;
  end;
 
  function fun_test(t_name varchar2)
  return number is yearSal number(7,2);
  begin
    select sal*12 into yearSal from emp2 where name = t_name;
    return yearSal;
  end;
end ;
--调用包中的函数或过程
call pac_test.pro_input('summer',1000);
call pac_test.fun_test
select pac_test.fun_test('simple') from dual;

--案例:
select * from emp2;
--下面以输入员工工号,显示雇员姓名、工资、个人所得税
--税率(0.03)。
declare
  c_tax_rate number(3,2):=0.03;  --常量,税率
  --v_name varchar2(30);
  v_name emp2.name%type;
  --v_sal number(8,2);
  v_sal emp2.sal%type;
  v_tax_sal number(8,2);
begin
  --执行
  select name,sal into v_name,v_sal from emp2 where name = &na;
  --计算所得税
  v_tax_sal:=v_sal*c_tax_rate;
  --输出
  dbms_output.put_line('姓名:'||v_name||' 工资'||v_sal||' 交税'||v_tax_sal); 
end;

--pl/sql记录实例
declare
  --定义一个pl/sql记录类型 emp_record_type ,类型包含2个数据,t_name,t_sal
  type emp_record_type is record(t_name emp2.name%type,t_sal emp2.sal%type);
  --定义一个 record_test 变量,类型是 emp_record_type
  record_test emp_record_type;
begin
  select name,sal into record_test from emp2 where name = 'simple';
  dbms_output.put_line('员工工资:'||record_test.t_sal);
end;

--pl/sql表实例
declare
  --定义了一个pl/sql表类型 emp_table_type 该类型是用于存放 emp.name%type元素类型 的数组
  -- index by binary_integer 下标是整数
  type emp_table_type is table of emp2.name%type index by binary_integer;
  --定义一个 table_test 变量
  table_test emp_table_type;
begin
  --table_test(0)下标为0的元素
  select name into table_test(0) from emp2 where name='summer';
  dbms_output.put_line('员工:'||table_test(0));
end;


--案例
--显示该部门的所有员工和工资
declare
  --定义游标类型 emp_cursor
  type emp_cursor is ref cursor;
  --定义一个游标变量
  cursor_test emp_cursor;
  --定义变量
  v_name emp2.name%type;
  v_sal emp2.sal%type;
begin
  --执行
  --把cursor_test 和一个select结合
  open cursor_test for
  select name,sal from emp2;
  --循环取出
  loop
    --fetch取出 游标 给 v_name,v_sal
    fetch cursor_test into v_name,v_sal;
    --判断工资
    if v_sal<1000 then
      update emp2 set sal = v_sal+1000 where sal=v_sal;
    end if;
    --判断cursor_test是否为空
    exit when cursor_test%notfound;
    dbms_output.put_line('姓名:'||v_name||' 薪水:'||v_sal);
  end loop;
end;

select * from emp2;


--《分页》案例:
--建表
drop table book;
create table book(
  bookId number(5),
  bookName varchar2(50),
  publishHouse varchar2(50)
);
--编写过程
create or replace procedure pro_pagination( t_bookId in number,
                            t_bookName in varchar2,
                            t_publishHouse in varchar2)
is
begin
  insert into book values(t_bookId,t_bookName,t_publishHouse);
end;
--在java中调用
--select * from book;
--insert into book values(11,'流星','蝴蝶');
--commit;
--有输入和输出的存储过程
create or replace procedure pro_pagination2( i_id in number,
                                             o_name out varchar2,
                                             o_publishHouse out varchar2
                                             )
is
begin
  select bookName,publishHouse into o_name,o_publishHouse from book where bookId = i_id;
end;
--Test!
declare
  err book.bookname%type;
  err2 book.publishhouse%type;
begin
  pro_pagination2(10,err,err2);
  dbms_output.put_line(err||' '||err2);
end;
--返回结果集的过程
--1、创建一个包
create or replace package testpackage
as
  type cursor_test is ref cursor;
end testpackage;
--2、建立存储过程
create or replace procedure pro_pagination3(
                                            o_cursor out testpackage.cursor_test)
is
begin
  open o_cursor for
  select * from book;
end;
--3、如何在java中调用

--Test!
declare
  err testpackage.cursor;
begin
  pro_pagination2(10,err);
  dbms_output.put_line(err);
end;


<Oracle的分页>


select t1.*,rownum rn from (select * from emp) t1;

select t1.*,rownum rn from (select * from emp) t1 where rownum<=10;
--在分页的时候,可以把下面的sql语句当做一个模板使用
select * from (select t1.*,rownum rn from (select * from emp) t1 where rownum<=10) where rn>=6;

--开发一个包
--1、创建一个包
create or replace package testpackage
as
  type cursor_test is ref cursor;
end testpackage;
--开始编写分页的过程
create or replace procedure fenye(tableName in varchar2,
                                  pageSize in number, --每页显示记录数
                                  pageNow in number,
                                  myRows out number,--总记录数
                                  myPageCount out number,--总页数
                                  p_cursor out testpackage.cursor_test)
is
  --定义sql语句 字符串
  v_sql varchar2(1000);
  --定义2个整数
  v_begin number:=(pageNow-1)*pageSize+1;
  v_end number:=pageNow*pageSize;
begin
  v_sql:='select * from (select t1.*,rownum rn from (select * from '||tableName||' order by sal) t1 where rownum<='||v_end||') where rn>='||v_begin||'';
  --把游标和sql关联
  open p_cursor for v_sql;
  --计算myRows和myPageCount
  --组织一个sql
  v_sql:='select count(*) from '||tableName||'';
  --执行sql,并把返回的值,赋给myRows
  execute immediate v_sql into myRows;
  --计算myPageCount
  if mod(myRows,pageSize)=0 then
    myPageCount:=myRows/pageSize;
  else
    myPageCount:=myRows/pageSize+1;
  end if;
  --关闭游标
  --close p_cursor;
end;
--使用java测试

分享到:
评论

相关推荐

    PL/SQL学习笔记

    PL/SQL是Oracle公司开发的一种过程化SQL扩展,它是Oracle数据库的重要组成部分,用于在数据库服务器上编写存储过程、函数、触发器、包等可执行...通过学习和掌握PL/SQL,开发者可以构建高效、复杂的数据库应用程序。

    Oracle PL/SQL程序设计(第5版)(上下册)

    - **集合与记录**:学习如何使用PL/SQL中的集合和记录类型,这些结构可以帮助更高效地处理数据集。 - **游标**:介绍游标的使用方法,包括隐式游标和显式游标,以及如何利用游标遍历查询结果。 #### 四、PL/SQL中的...

    Oracle PL/SQL专家指南-高级PL/SQL解决方案的设计与开发

    通过学习这些内容,开发者可以掌握Oracle PL/SQL的高级特性,从而设计和实现更高效、更稳定的数据库应用程序。无论你是数据库管理员、系统架构师还是开发人员,这本书都将为你提供宝贵的指导,助你在Oracle数据库...

    PL/SQL安装包

    PL/SQL是Oracle数据库系统中的一个关键组成部分,它是一种结合了SQL与过程编程的语言,用于在Oracle环境中开发数据库应用程序。PL代表Procedural Language,SQL则代表Structured Query Language。这个"PL/SQL安装包...

    Oracle Database 12c PL/SQL开发指南 实例源代码

    总的来说,学习并熟练掌握Oracle Database 12c的PL/SQL开发不仅能够提升数据库管理能力,还能为构建高效、稳定且易于维护的企业级应用打下坚实的基础。而"Oracle Database 12c PL/SQL开发指南(第7版)"的源代码示例...

    DBAtools for PL/SQL表空间管理器

    PL/SQL Developer是Oracle数据库当前最流行的开发工具之一,它在ORACLE数据库开发设计方面功能强大,使用方便,但是数据库管理方面一直比较欠缺。 DBATools For PL/SQL Developer 是一款PL/SQL Developer的辅助插件...

    PL/SQL 详解

    ### PL/SQL 详解 #### 1. PL/SQL程序设计简介 ##### 1.1 SQL与PL/SQL **1.1.1 什么是PL/SQL?** PL/SQL (Procedure Language / Structured Query Language) 是Oracle为SQL语言添加的过程化特性的一种编程语言。它...

    pl/sql学习文档

    本文将从日志管理和表空间管理两个方面,详细介绍《pl/sql学习文档》中的关键知识点。 ### 第一章:日志管理 #### 日志管理概述 日志管理是数据库运维中的核心环节,特别是在Oracle数据库中,通过有效的日志管理...

    PL/SQL DEVELOPER(用户指南中文版)

    PL/SQL Developer是一款专为Oracle数据库开发者设计的强大集成开发环境(IDE),它旨在提升数据库应用程序的开发效率和质量。这款工具提供了丰富的特性,使得编写、调试、测试和管理PL/SQL代码变得更加简单易行。 ...

    PL/SQL Trigger PL/SQL TriggerPL/SQL TriggerPL/SQL Trigger

    PL/SQL Trigger是Oracle数据库中的一个关键特性,用于在特定的数据库事件发生时自动执行一段预定义的PL/SQL代码。这些事件可能包括对表的INSERT、UPDATE或DELETE操作,或者其他的数据库活动。触发器是数据库级别的...

    oracle pl/sql最佳实践

    Oracle PL/SQL是一种强大的编程语言,它结合了SQL的数据库操作能力和Procedural Language的控制结构,使得数据库管理员和开发人员...持续学习和实践,不断提升自己的技能,是成为优秀Oracle PL/SQL开发者的必经之路。

    DBATools For PL/SQL Developer

    软件名称:DBATools For PL/SQL Developer 发布版本:1.1.0 Beta 1 发布日期:2010-01-28 软件简介: PL/SQL Developer是Oracle数据库当前最流行的开发工具之一,它在ORACLE数据库开发设计方面功能强大,使用方便,...

    PL/SQL Developer 8.0.4.1514注册码

    PL/SQL Developer是一款专为Oracle数据库设计的强大开发工具,它支持PL/SQL语言的开发、调试与管理。该工具不仅能够帮助开发者高效地编写和维护PL/SQL代码,还提供了诸如代码格式化、重构、性能分析等多种高级功能。...

    PL/SQL Developer 7.0

    ### PL/SQL Developer 7.0 用户指南关键知识点解析 #### 一、介绍 **PL/SQL Developer** 是一款专为 Oracle 数据库设计的强大集成开发环境(IDE),它旨在简化和提升 PL/SQL 应用程序的开发效率。版本 7.0 作为该...

    pl/sql表空间插件

    PL/SQL是Oracle数据库的一种编程语言,它结合了SQL查询语句和过程式编程元素,使得数据库管理员和开发人员能够更高效地管理数据库。在Oracle环境中,表空间(Tablespaces)是存储数据库对象如表、索引、视图等的核心...

    PL/sql developer 用戶指南中文版.pdf

    **知识点详解:《PL/SQL Developer 用户指南》** 在IT领域,尤其是对于Oracle数据库开发者而言,《PL/SQL Developer 用户指南》是一份极其重要的资源。它不仅涵盖了软件的安装与配置,还深入讲解了如何利用该工具...

    Oracle PL/SQL编程详解

    Oracle PL/SQL编程详解是Oracle数据库开发人员必须掌握的技术之一。Oracle PL/SQL是一种用于Oracle数据库系统的程序设计语言,它是SQL语言的扩展,包含了许多能增加程序可读性和模块化的特性。PL/SQL代码被编译成...

    Oracle PL/SQL常用47个工具包

    Oracle PL/SQL是一种强大的编程语言,它将SQL与过程编程语言的功能结合起来,为数据库管理和开发提供了丰富的工具。在Oracle环境中,PL/SQL是构建高效、可靠应用程序的关键组件。以下是对"Oracle PL/SQL常用47个工具...

Global site tag (gtag.js) - Google Analytics