PL/sql语言基础

  exception    

   异常处理   

end   

exception    

   异常处理   

end;

第一类  :PL/SQL     变量   

(DECLARE  阶段别声明和初始化)   

(每一行只声明一个变量)

(在执行阶段被赋予新值)   

(可以在PL/SQL之间传递)

(通过标准输出包可以看到结果)

  表汇总的字段数据类型  

varchar2   4000   

char  2000

long  2G  



SQL> declare

  2      v_1 number;

  3      v_2 number(2);

  4      v_3 int;

  5      v_4 varchar2(20) default 'abc';

  6      v_5 constant varchar2(20) :='zyx';

  7      v_6 number not null  :=120;

  8      v_7 boolean  :=false;

  9      v_8 rowid;

10    begin

11    null;

12    v_1:=1.232434;

13    v_1 :=200;

14    end;

15    /

PL/SQL 过程已成功完成。

SQL>



SQL> ed

已写入 file afiedt.buf

  1  declare

  2    empno number;

  3      v_2 number(2);

  4      v_3 int;

  5      v_4 varchar2(20) default 'abc';

  6      v_5 constant varchar2(20) :='zyx';

  7      v_6 number not null  :=120;

  8      v_7 boolean  :=false;

  9      v_8 rowid;

10    begin

11    null;

12    empno:=7788;

13    delete emp where empno=empno;

14*  end;

SQL> /

PL/SQL 过程已成功完成。

SQL> select  * from  emp;

未选定行

SQLPLUS 或者「命令窗口」中如果没有输出,可以使用 set serveroutp  on  来修改   是否能输出

ed

已写入 file afiedt.buf

  1  declare

  2        empno number;

  3          v_2 number(2);

  4        v_3 int;

  5        v_4 varchar2(20) default 'abc';

  6          v_5 constant varchar2(20) :='zyx';

  7          v_6 number not null  :=120;

  8        v_7 boolean  :=false;

  9          v_8 rowid;

10        begin

11      null;

12    empno :=7788;

13      v_2:=1;

14      dbms_output.put_line('变量v2的值是:'|| v_2);   这里也可以写sysdate

15*    end;

SQL> /

变量v2的值是:1

PL/SQL 过程已成功完成。

也可以缓存v_4  v_5  

已写入 file afiedt.buf

  1  declare

  2  v_var1  number:=123;

  3  begin

  4    dbms_output.put_line('OUT:v_var1:'||v_var1);

  5    declare

  6        v_var2 number:=456;

  7  begin

  8    dbms_output.put_line('IN:v_var1:'||v_var1);

  9    dbms_output.put_line('IN:v_var2:'||v_var2);

10  END;

11  --dbms_output.put_line('IN:v_var2:'||v_var2);  内部中的变量不能被外部块使用,去掉注释就报错

12* end;

SQL> /

OUT:v_var1:123

IN:v_var1:123

IN:v_var2:456

PL/SQL 过程已成功完成。

外部的变量可以内部使用,但是内部的变量外部不能使用

SQL> ed

已写入 file afiedt.buf

  1  declare

  2  v_out  varchar2(20)  :='this  is  out';

  3  begin

  4    dbms_output.put_line(v_out);

  5    declare

  6    v_inner  varchar2(20) :='this  is  inner';

  7    begin

  8        v_out:='abc';  --这里还可以重新赋值

  9        dbms_output.put_line(v_out);

10        dbms_output.put_line(v_inner);

11    end;

12* end;

SQL> /

this  is  out

abc

this  is  inner

PL/SQL 过程已成功完成。

语句库的标签可以加在一个语句块开始的位置上   当外部块和内部块出现同命名变量时   借助标签 来区别  但是这样的程序可读性太差 尽量不要使用变量名来重复


在PL  sql  里面嵌入  sql  语句   使用SELECT 查询结果对变量赋值

PL/SQL  中的select  必须使用into  将选出结果存入变量之内

SQL> ed

已写入 file afiedt.buf

  1  declare

  2  v_sal  number ;

  3  v_job    varchar2(20);

  4  begin

  5  select  sal , job  into  v_sal,v_job  from  emp  where  empno=7788;

  6  dbms_output.put_line(v_sal||','||v_job);

  7* end;

SQL> /

3000,ANALYST

PL/SQL 过程已成功完成。

使用  %type  参照方式定义变量的类型     

  有时在程序中声明的变量  很多时候是为了存放表中的列数据   这样我们自己定义变量类型时往往都是和表中的类型以及长度一致的    %type 就可以避免复杂的输入  直接可以参照表的某列的类型直接作为变量的类型这样即使表中的类型被修改了  程序中的类型也随之改变     程序的健壮性提高   

SQL> declare

  2  v_ename  scott.emp.ename%type;

  3  begin

  4  select  ename  into  v_ename  from  scott.emp  where  empno=7788;

  5  dbms_output.put_line(v_ename);

  6  end;

  7  /

SCOTT

PL/SQL 过程已成功完成。

2  复合变量  

  记录  (record)  

  使用方法  

1  先定义类型,类型中国描述了这是一个  RECORD  

2  但却没有  说明内部  具体列的内容

定义自定义  类型就是为了 定义  record  内部  包含什么列  

3  在将定义好的类型 关联一个变量  

  引用 record  类型中的值   记录名   内部列名  

declare

  2  type rec_typ  is  record(

  3  v_ename  emp.ename%type,

  4  v_job  emp.job%type,

  5  v_sal  emp.sal%type);

  6

  7  v_rec rec_typ;

  8  begin

  9  select  ename,job,sal  into v_rec.v_ename,v_rec.v_job,v_rec.v_sal  from emp  where

10  empno=&no;

11  dbms_output.put_line(

12  'his name is'||v_rec.v_ename||','||chr(10)||

13  'his job is'||v_rec.v_job||','||chr(10)||

14  'his name is'||v_rec.v_sal||','

15  );

16  end;

17  /

输入 no 的值:  7788

原值  10: empno=&no;

新值  10: empno=7788;

his name isSCOTT,

his job isANALYST,

his name is3000,

PL/SQL 过程已成功完成。



使用8个变量在一行  

使用  %rowtype 来代替 record  的类型定义     

  和  %type 类型 %type是参照一列的类型  

 而  %rowtype 是将表的所有列做为了record中的成员     

列名即是成员名  


此时当然也可以使用 加入sal   job   ename  

PL/SQL   表 (INDEX  BY  表)

类似于属组,但下标除了定义成数字外还可以定义为字符,定义成数值下标时必须要使用  

binary_integer  类型      binary_integer  类型相比  number  类型区别   :

  存储的数据以二进制方式存储  占用更少的空间    

可以存储  -2147483747-  2147483747    之间的任意整数   

主要使用在PL/SQL  表的下标类型撒花姑娘不能出现在常规的类型上反之  PL/SQL 表的下标也不能使用number  来取代  

使用方法

 1  先定义类型,指出下面是数字还是字符

2  在类型关联变量   

引用  PL/SQL  表中的元素  :表名 (下标)

SQL> ed

已写入 file afiedt.buf

  1  declare

  2  type  tab_typ  is  table  of  varchar2(20)  index  by  binary_integer  ;

  3  v_tab  tab_typ;

  4  begin

  5  v_tab(1):='jason';

  6  v_tab(2):='jack';

  7  select  ename  into  v_tab(3)  from  emp  where  empno=7788;

  8  dbms_output.put_line(v_tab(1)||',' ||v_tab(2)||','||v_tab(3));

  9* end;

SQL> /

jason,jack,SCOTT

PL/SQL 过程已成功完成。

也可以修改里面的   变量值

SQL> ed

已写入 file afiedt.buf

  1  declare

  2  type  tab_typ  is  table  of  varchar2(20)  index  by    varchar2(1);

  3  v_tab  tab_typ;

  4  begin

  5  v_tab('a'):='jason';

  6  v_tab('b'):='jack';

  7  select  ename  into  v_tab('c')  from  emp  where  empno=7788;

  8  dbms_output.put_line(v_tab('a')||',' ||v_tab('b')||','||v_tab('c'));

  9  dbms_output.put_line(v_tab.first);

10  dbms_output.put_line(v_tab.last);

11  dbms_output.put_line(v_tab.prior('b'));

12  /*

13  前一个下标

14  */

15  dbms_output.put_line(v_tab.next('b'));

16  /*

17    b  的下一个下标

18  */

19  dbms_output.put_line(v_tab.count);

20* end;

PL/SQL  表的缺陷是: 

of  类型的定义比较死板  

定义的类型是字符  所有值就只能存储字符  

  定义的累累是数字  所有值就只能存储数字 

解决办法是使用PL/SQL  表+ record 可以随心所欲的存不同类型值  

PL/SQL  表+record  

PL/SQL  中不能直接使用select  需要使用  select  into  将查询结果插入到标量在   

dms_output打印标量    

  1  先定义record  类型,声明类型中包含哪些列  

2  在定义PL/SQL 类型 PL/SQL 表类型关联之前定义的record 类型  

3  这样就将  record  作为了PL/SQL 表中的元素  

4  在将PL/SQL  类型关联到变量中


  引用方法 :

  赋值 :PL/SQL  表名  下标

取值: PL/SQL  表名(下标).record  的列名

SQL> ed

已写入 file afiedt.buf

  1  declare

  2  type  rec_typ  is record(

  3  v_ename varchar2(20),

  4  v_sal  number);

  5  type  tab_typ  is table  of  rec_typ index  by  binary_integer;

  6  /*

  7  默认为整形

  8  */

  9  v_tab  tab_typ;

10  begin

11  v_tab(1).v_ename:='jack';

12  v_tab(1).v_sal:=3000;

13  select  ename,sal  into v_tab(2).v_ename,v_tab(2).v_sal

14  from  emp  where  empno=7788;

15  dbms_output.put_line(v_tab(1).v_ename|| chr(10)||

16  v_tab(1).v_sal|| chr(10)||

17  v_tab(2).v_ename|| chr(10)||

18  v_tab(2).v_sal);

19* end;

SQL> /

jack

3000

SCOTT

3000

PL/SQL 过程已成功完成。

当然此时我们也可以简写 

在sqlplus的外部声明一下  

SQL> var x varchar2(100);

SQL> begin

  2  :x:='tttt';

  3  end;

  4  /

PL/SQL 过程已成功完成。

SQL> print x

X

--------------------------------------------------------------------------------

tttt   这可以操作

SQL> begin

  2  select  ename  into :x  from  emp  where  empno=7839;

  3  end;

  4  /

PL/SQL 过程已成功完成。

SQL> print  x

X

--------------------------------------------------------------------------------

KING

使用  IF语句按条件判断,控制PL/SQL  流程 ;

if  -then  -end  if  

if- then-else-end  if 

if-then-elsif-then-else-end if  

Oracle  的写法

if   expr1  

then   

    action1  

elif   expr2  

then  

       action2  

else   

   default_action;

fi  

if  

expr1  

then   

    action1;

elsif  expr2;

then   action2  ;

...

else 

default  action;

end  if;

set  serveroutput  on   打开后台显示 

开始声明

SQL> ed

已写入 file afiedt.buf

  1  declare

  2  v_hour  number :=(to_char(sysdate,'hh24'));

  3  begin

  4  if  v_hour >=6 and  v_hour<=11 then

  5  dbms_output.put_line('现在是上午');

  6  else

  7  dbms_output.put_line('现在不是上午');

  8  end  if;

  9* end;

SQL> /

现在不是上午

PL/SQL 过程已成功完成。  单分支情况  

我们还可以继续嵌套

使用  CASE  分支 

1 declare

  2  v_grade  varchar2(1) :=upper('&grade');

  3  v_info    varchar2(20);

  4  begin

  5  v_info:=

  6  case  v_grade  when  'A' then

  7  'excellent'

  8  when  'B'  then

  9  'very good!!!'

10  when  'C' then

11  'yiban'

12  else  'No  such  as  grade!!!'

13  end;

14  dbms_output.put_line(

15  'the  grade  is'|| v_grade||chr(10)||

16  '    the information is  '  ||  v_info

17  );

18* end;

SQL> /

输入 grade 的值:  C

原值    2: v_grade  varchar2(1) :=upper('&grade');

新值    2: v_grade  varchar2(1) :=upper('C');

the  grade  isC

    the information is  yiban

PL/SQL 过程已成功完成。

使用别的分支函数 

SQL> ed

已写入 file afiedt.buf

  1  declare

  2  v_grade  varchar2(1) :=upper('&grade');

  3  v_info    varchar2(20);

  4  begin

  5  case

  6  when

  7  v_grade =  'A' then

  8  v_info:='excellent!!!!';

  9  when  v_grade='B'  then

10  v_info:='very good!!!';

11  when  v_grade='C' then

12  v_info:='yiban';

13  else

14  v_info:='No  such  as  grade!!!';

15  end  case;

16  dbms_output.put_line(

17  'the  grade  is  '  || v_grade||chr(10)||

18  '    the information is  '  ||  v_info

19  );

20* end;

SQL> /

输入 grade 的值:  a

原值    2: v_grade  varchar2(1) :=upper('&grade');

新值    2: v_grade  varchar2(1) :=upper('a');

the  grade  is  A

    the information is  excellent!!!!

PL/SQL 过程已成功完成

循环

SQL> ed

已写入 file afiedt.buf

  1  declare

  2  i  int :=1;

  3  begin

  4  loop   开始

  5  dbms_output.put_line(i);

  6  i:=i+1;

  7  exit  when  i>10;

  8  end  loop;  结束

  9* end;

SQL> /

1

2

3

4

5

6

7

8

9

10

PL/SQL 过程已成功完成。


数字FOR 循环   

SQL> begin

  2  for  i  in 1..10  loop

  3  dbms_output.put_line(i);

  4  end  loop;

  5  end;

  6  /

1

2

3

4

5

6

7

8

9

10

PL/SQL 过程已成功完成。

双重循环

外循环和内循环都执行5次  ,内外计数器变量名相同 i

显示内循环的计数器和外循环的计数器的乘积  

当乘积超过15时候  退出  

SQL> ed

已写入 file afiedt.buf

  1  begin

  2  for  i  in 1..5  loop

  3    for  j in 1..5 loop

  4  /*

  5  exit  when  i*j>15 ;

  6  */

  7  if  i*j>15 then

  8  return;

  9  end  if;

10    dbms_output.put_line(i*j);

11  end  loop;

12  end loop;

13  dbms_output.put_line('test');

14* end;

SQL> /

1

2

3

4

5

2

4

6

8

10

3

6

9

12

15

4

8

12

PL/SQL 过程已成功完成。


SQL> ed

已写入 file afiedt.buf

  1  declare

  2  i  int:=1;

  3  begin

  4  loop

  5  dbms_output.put_line(i);

  6  i:=i+1;

  7  if  i>10  then

  8  goto outofloop;

  9  end  if;

10  end loop;

11  dbms_output.put_line('this is a  test text');

12  <<outofloop>>

13  dbms_output.put_line('the last i is ' || i);

14* end;

SQL> /

1

2

3

4

5

6

7

8

9

10

the last i is 11

PL/SQL 过程已成功完成。

写一个PL/SQL  块 

想dept表中循环插入5条信息    每一条记录 的deptno值比表中最大的deptno增加1  

dname 分别为  "Test1" "Test2"  ....."Test5";

SQL> ed

已写入 file afiedt.buf

  1  declare

  2  mdeptno  dept.deptno%type;

  3  begin

  4  for  i  in  1..5  loop

  5  select  max(deptno) into mdeptno from  dept;

  6  insert  into  dept values((mdeptno+1),'Test ' || i,null );

  7  end  loop;

  8* end;

  9  /

PL/SQL 过程已成功完成。

SQL> rollback;

回退已完成。

SQL> select  *  from  dept;

    DEPTNO DNAME          LOC

---------- -------------- -------------

        10 ACCOUNTING    NEW YORK

        20 RESEARCH      DALLAS

        30 SALES          CHICAGO

        40 OPERATIONS    BOSTON


SQL> ed

已写入 file afiedt.buf

  1  declare

  2  type  num_typ  is  table  of  int  index  by    binary_integer;

  3  type    var_typ  is  table  of  varchar2(10)  index  by  binary_integer;

  4  /*

  5  这是下标的  写法

  6  */

  7  v_num  num_typ;

  8  v_var  var_typ;

  9  v_max  dept.deptno%type;

10  /*

11  这是给它赋值

12  */

13  begin

14  select max(deptno)  into  v_max  from  dept;

15  select  rownum,'test' || rownum

16  bulk  collect  into  v_num,v_var

17  from  dual

18  connect  by  rownum<=5;

19  forall i  in  v_num.first..v_num.last

20  insert  into  dept values((v_num(i)+v_max),v_var(i),null);

21  commit;

22* end;

SQL> /

PL/SQL 过程已成功完成。

然后查询  

SQL>

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空