Oracle的PL SQL语法

PL/SQL

一、函数的应用

1.变量的声明与赋值

--声明一个变量,并赋值、打印

declare

        str varchar2(30);

        sname emp.ename%type;--声明一个与emp表的ename属性一致的类型

        ctable emp%rowtype;--声明一个与emp表相同的行类型

begin

        str:='&请输入:';--手动输入,是一种动态赋值

        select ename into sname from emp whereempno=7369;

        select * into ctable from emp whereempno=7499;

        dbms_output.put_line('str='||str);

        dbms_output.put_line('sname='||sname);

       dbms_output.put_line('ename='||ctable.ename);

end;

2.if语句的使用

--if 取出7369的薪水,判断是否纳税

declare

     salary emp.sal%type;

begin

     select sal into salary from emp whereempno=7369;

     if salary>=3000 then

        dbms_output.put_line('需要纳税');

     else            --elsif相当于javaelseif

        dbms_output.put_line('需努力');

     end if;

end;

--case 的两种用法

1>.declarestr varchar2(10);

begin

str:='A';

        case str

             when'A' then dbms_output.put_line('优秀');

             when 'B' thendbms_output.put_line('良好');

             when 'C' thendbms_output.put_line('好');

             when 'D' thendbms_output.put_line('一般好');

             when 'E' thendbms_output.put_line('不好');

             else dbms_output.put_line('很不好');

        end case;

end;

2>.

declare mysalnumber(6,2);

eno number(6);

begin

    eno:=7369;      --直接赋值

    select sal intomysal from emp where empno=eno;  --这也是一种赋值

    case when mysal>3500 then dbms_output.put_line('交税');

         when mysal=3500 thendbms_output.put_line('刚好');

         when mysal<3500 thendbms_output.put_line('努力');

         else dbms_output.put_line('其他');

     end case;

end;

3.Loop While For 三种循环

1>  --输出1..100;

declare inumber(6):=1;

mysumnumber(6):=0;

begin

<<b_loop>>--loop取个名字

loop

        dbms_output.put_line(i);

        mysum:=mysum+i;

        exit b_loopwhen i=200; --跳出循环

        i:=i+1;

end loop;

dbms_output.put_line(mysum);

end;

declare inumber(6):=1;

mysumnumber(6):=0;

begin

while i<=100 loop

      mysum:=mysum+i;

      i:=i+1;

end loop;

dbms_output.put_line(mysum);

end;

declare

mysumnumber(6):=0;

begin

for i in 1..100 loop  --1..100这两个参数均可使用变量

    mysum:=mysum+i;

    --i:=i+1;

end loop;

dbms_output.put_line(mysum);

end;

4.Oracle两种常见的报错

too_many_rows //太多行错误

no_data_found //没找到数据

二、游标

游标分为隐式游标、显示游标、REF游标。

1>.隐式游标

   隐式游标无需我们申明、创建、使用,它全由系统自动完成,我们在JDBC中使用的ResultSet对象就是这种用法。

2>显示游标

--pl/sql 声明(declare)  代码(begin  end) 异常(exception)

declare

cursor myc is select * from emp;--声明游标

myr emp%rowtype;

begin

open myc;--打开游标

--使用游标:fetch (从游标中提取一行)

loop

  fetch myc intomyr;

  exit when myc%notfound;

  dbms_output.put_line('名字'||myr.ename||' 薪水:'||myr.sal);

end loop;

close myc;

end;

--带条件的游标:打印2500以下的员工信息

declare

cursor myc isselect * from emp where sal<2500;

myr emp%rowtype;

begin

open myc;

loop

     fetch myc into myr;

     exit when myc%notfound;

      dbms_output.put_line('名字'||myr.ename||' 薪水:'||myr.sal);

end loop;

close myc;

end;

--由用户指定查询的薪水:带参数的游标

declare

cursor myc(mysal number) is select * from emp wheresal<mysal;

myr emp%rowtype;

issalnumber(8,2);

begin

issal:=&请输入;

open myc(issal);

loop

     fetch myc into myr; 

     exit when myc%notfound;

      dbms_output.put_line('名字'||myr.ename||' 薪水:'||myr.sal);

end loop;

close myc;

end;

--for 循环游标

declare

cursor myc(mysalnumber) is select * from emp where sal<mysal;

begin

for myr in myc(2500) loop

     dbms_output.put_line('名字'||myr.ename||' 薪水:'||myr.sal);

end loop;

end;

3.REF游标

declare

type myc is ref cursor

return emp%rowtype;--有返回值表示它是强类型,无则是弱类型

mycd myc;

myr emp%rowtype;

begin

open mycd for select * from emp;

loop

     fetch mycd into myr;

       exit when mycd%notfound;

      dbms_output.put_line('名字'||myr.ename||' 薪水:'||myr.sal);

end loop;    

close mycd;

end;

--动态ref

declare

type myc is refcursor;

myce myc;

myr emp%rowtype;

mysalnumber(7,2);

begin

mysal:=2500;

open myce for 'select * from emp where sal>:1' using mysal;--“:1”表预备的第一个参数,相当于JDBC中的预备语句的“?”

loop

     fetch myce into myr;

       exit when myce%notfound;

      dbms_output.put_line('名字'||myr.ename||' 薪水:'||myr.sal);

end loop;

close myce;

end;

三、同义词、授权、序列、视图、索引、

1.同义词

--创建同义词(需授权)

create or replacesynonym a for scott.emp;

--使用同义词

select * from a;

--删除同义词

drop synonym a;--为什么只删除该同义词的内容,此框架还存在,那应该怎么删除?

2、授权

  --授权

grant create synonym to scott;

--收权

revoke create synonym from scott;

3.序列

  --创建序列(它不能重复创建)

create sequence seq

start with 1

increment by 3

maxvalue 100

minvalue 1

cache 20;

create sequenceseq;--这也可以,默认为从1开始,每次加1;

--使用序列

select seq.nextvalfrom dual;

select seq.currvalfrom dual;

--删除序列

drop sequence seq;

--修改序列里的内容(不能修改其序列名,修改后也就不是此序列)

-- Alter sequence

alter sequence SEQ

minvalue 2

maxvalue 399

increment by 3;

-- Modify thelast number

alter sequenceSEQ increment by 2 nocache;

selectSEQ.nextval from dual;

alter sequenceSEQ increment by 3 cache 20;

4、视图

   --创建视图(需授权)

视图是一个虚表,数据表删除了,但它还存在,只是不能运行,也就是说,视图实际是一段select语句,它能保证数据的安全性。理论上视图是可修改,但实际上不去修改,视图可以嵌套视图,但不能无穷嵌套。并且sqlserver 只能嵌套32层。

create or replace view v_emp as select * from emp;

--使用视图

select * fromv_emp;

--删除视图

drop view v_emp;

5、索引(index

索引:是数据库内部编排数据的一种方法,两个列可以创建同一个索引,称为组合索引,表的每一个列都可以创建索引。索引依附于表存在,表删除了,索引也没了;能提高查询速度,但会降低增、删、改的速度。索引非常占硬盘空间,若一个表里有五个列,100万行数据,有一个列加了索引,则硬盘除了保存那原先的100万行数据外,还要保存100万行索引数据,其中包含两列,一个是主键,一个是创建索引的那个列,也就意味着,表里每增加一个索引就会增加100万行索引数据。

6.

  nvl(condition,value);此方法:若condition为空,则值用value的值来填充。

五、存储过程

存储过程:是一段预先编译好的存储在数据库里一段SQL语句集。

其优点:模块化,安全性,减少网络的流通量

--创建存储过程

create or replaceprocedure  pname_1203(eno number)

as

myename varchar2(80);

mysal number(8,2);

begin

select ename,sal into myename,mysal fromemp where empno=eno

dbms_output.put_line('姓名'||myename||' 薪水为'||mysal);

end;

  --使用存储过程

begin

pname_1203(7369);

end;

过程参数的三种模式

IN: 用于接受调用程序的值,默认的参数模式

OUT: 用于向调用程序返回值

IN OUT: 用于接受调用程序的值,并向调用程序返回更新的值

--out 类型表示该值是从存储过程传到外面去的

create or replace procedurepname_1203a(eno number,myjob out varchar2)

as

myename varchar2(50);

begin

select ename,job into myename,myjob fromemp where empno=eno;

dbms_output.put_line('姓名是'||myename);

end;

注意:oracle里的子程序包括存储过程与函数。

六、程序包(package)

--包头的创建

create or replacepackage pname1203 is

procedure pr1203(eno number);

function fu1203(eno number)returnvarchar2;

end pname1203;

--包体的创建

create or replacepackage body pname1203 is

    procedure pr1203(eno number)

     is

        myename varchar2(55);

    begin

        select ename into myename from emp whereempno=eno;

       dbms_output.put_line('姓名是'||ename);

      end pr1203;

     function fu1203(eno number) return varchar2 is

           myename varchar2(55);

     begin

         select ename into myename from emp whereempno=eno;

     return myename||'hello';

     end fu1203;

end pname1203;

 

--如何调用包里面的东西

select pname1203.fu1203(7369)from dual;

七、触发器

1.需记住的

       (1).三种操作:delete   update   insert

(2).两个临时表:  :new   :old

:old表用来保存要删除时的数据,只有一行数据

:new表用来保存要插入时的数据,只有一行数据

更新时需要:old  and  :new  两个表都需要

(3).两个时间点: after    before

(4).两种重要模式:行级   语句级(即表级)

(5).条件:when

     2. --建立触发器:学生信息表中‘s25301'不能删除、修改; 插入时,

--  检查名字叫'张洋洋'的不能添加  's25302'不能改

createor replace trigger t_stu

afterdelete or update or insert on stuinfo

for each row  //这表示是行级触发器,若没写,则为表级触发器。

declaresno varchar2(40);

snamevarchar2(50);

begin

sno:=:old.stuno;

sname:=:new.stuname;

if deleting then

  if sno='s25301'  then

     raise_application_error(-20009,'该学生不能动');//-20009是自定义错误,其自定义错误代码范围:-20000-21000.

  end if;

elsif updating then

   if sno='s25302'  then

     raise_application_error(-20004,'该学生不能动');

  end if;

elsif inserting then

      if sname='张洋洋'then

          raise_application_error(-20006,'该学生不能要');

      end if;

end if;

end;

   3.在插入数据时自动插入序列号

       create or replace trigger t_stua

beforeinsert on tb_study

for eachrow

begin

--:new.sid:=mys1208.nextval;     //11g版本可使用

select mys1208.nextval into :new.sid from dual;    //10g可使用

end;

猜你喜欢

转载自blog.csdn.net/u013254241/article/details/26626609