PL/SQL编程

SQL与PL/SQL
SQL语言只是访问、操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发。PL /SQL是一种高级数据库程序设计语言,该语言专门用于在各种环境下对ORACLE数据库进行访问。由于该语言集成于数据库服务器中,所以PL/SQL代码可以对数据进行快速高效的处理。
PL/SQL是 Procedure Language & Structured Query Language 的缩写。
PL/SQL的优点或特征
(1) 有利于客户/服务器环境应用的运行
对于客户/服务器环境来说,真正的瓶颈是网络上。无论网络多快,只要客户端与服务器进行大量的数据交换。应用运行的效率自然就回受到影响。如果使用PL/SQL进行编程,将这种具有大量数据处理的应用放在服务器端来执行。自然就省去了数据在网上的传输时间。
(2) 适合于客户环境
PL/SQL由于分为数据库PL/SQL部分和工具PL/SQL。对于客户端来说,PL/SQL可以嵌套到相应的工具中,客户端程序可以执行本地包含PL/SQL部分,也可以向服务发SQL命令或激活服务器端的PL/SQL程序运行。
(3) 过程化
PL/SQL是Oracle在标准SQL上的过程性扩展,不仅允许在PL/SQL程序内嵌入SQL语句,而且允许使用各种类型的条件分支语句和循环语句,可以多个应用程序之间共享其解决方案。
(4) 模块化
PL/SQL程序结构是一种描述性很强、界限分明的块结构、嵌套块结构,被分成单独的过程、函数、触发器,且可以把它们组合为程序包,提高程序的模块化能力。
(5) 运行错误的可处理性
使用PL/SQL提供的异常处理(EXCEPTION),开发人员可集中处理各种ORACLE错误和PL/SQL错误,或处理系统错误与自定义错误,以增强应用程序的健壮性。
(6) 提供大量内置程序包
ORACLE提供了大量的内置程序包。通过这些程序包能够实现DBS的一些低层操作、高级功能,不论对DBA还是应用开发人员都具有重要作用。

PL/SQL块

PL/SQL程序由三个块组成,即声明部分、执行部分、异常处理部分。
PL/SQL块的结构如下:

DECLARE
–声明部分: 在此声明PL/SQL用到的变量,类型及游标,以及局部的存储过程和函数
BEGIN
– 执行部分: 过程及SQL 语句 , 即程序的主要部分
EXCEPTION
– 异常处理部分
END;

标识符
标识符名不能超过30字符;

1.不能用保留字
2.第一个字符必须是字母
3.变量名最多包含30个字符
4.不要与数据库的表或者列同名
5.每一行只能声明一个变量

PL/SQL 变量类型

基本类型 7种

1.binary_integer 整数,主要用来计数(数组下标、循环i)而不是用来表示字段类型 4个字节

2.number 数字类型 //number(7,2) 一共7位,小数点后两位,其余五位

3.char 定长字符串 sql 最长2000 pl/sql 最长32767

4.varchar2 变长字符串 sql 最长4000 pl/sql 最长32767

5.long 长字符串,最长2GB

6.date 日期

7.boolean 布尔类型,可以取值true、false和 null值。

举例:

DECLARE 
      v_binary_integer BINARY_INTEGER :=0;
      v_number NUMBER(7,2):=255.567;
      v_date DATE :=SYSDATE;
      v_pi CONSTANT NUMBER(3,2) :=3.14;

      v_valid BOOLEAN ;

      v_name VARCHAR(20) NOT NULL :='MyName';
BEGIN
      --v_binary_integer
      dbms_output.put_line('v_binary_integer:'||(v_binary_integer+1));
      --v_number
      dbms_output.put_line('v_number:'||(v_number));
      --v_date
       dbms_output.put_line('v_date:'||(v_date));
      --v_pi
      ---
      --v_pi:=3.24;
       dbms_output.put_line('v_pi:'||(v_pi));

      --v_valid 布尔类型有三个值true false null不能直接打印
      --dbms_output.put_line('v_valid:'||(v_valid));
        IF(v_valid=TRUE)THEN
                dbms_output.put_line('v_valid:true');
        ELSIF(v_valid=FALSE)THEN
                dbms_output.put_line('v_valid:false');
        ELSE
                dbms_output.put_line('v_valid:null');
        END IF;

      --v_name
      dbms_output.put_line('v_name:'||(v_name||':Waleee'));

END;

复合类型有四种
(1) 字段类型 %type,好处:便于维护

declare
    --和emp表的empno字段的类型是一样的
    v_empno2 emp.empno%type;
    v_empno3 v_empno2%type;
begin
    dbms_output.put_line('Test');
end;

(2).table 相当于java里的数组 自定义类型

DECLARE 
 --int[]
 TYPE type_table_emp_empno IS TABLE OF emp.empno%TYPE INDEX BY BINARY_INTEGER;--定义一个数组类型
 --arr[] 
 v_arr type_table_emp_empno;

 BEGIN
     v_arr(1):=4789;
     v_arr(0):=1789;
     v_arr(-1):=3789; 
     dbms_output.put_line(v_arr(-1));
 END;

(3)record 相当于java里的类 自定义类型

 DECLARE
  TYPE type_record_dept IS RECORD(
       m_deptno dept.deptno%TYPE,
       m_dname dept.dname%TYPE,
       m_loc dept.loc%TYPE

  );--声明了一个新的类型

  trd type_record_dept; 
  BEGIN
      trd.m_deptno:=66;
      trd.m_dname:='waleee';
      trd.m_loc:='beijing';

       dbms_output.put_line(trd.m_deptno||  trd.m_dname || trd.m_loc);
  END;

(4)rowtype 记录类型 行类型

DECLARE
 v_emptype emp%ROWTYPE;
BEGIN
 v_emptype.empno:=34;
 dbms_output.put_line(v_emptype.empno||v_emptype.ename);
END;

pl/sql中6类SQL语句都可以放

(1) pl/sql中 select语句的要求:

1.返回必须有且只有一条记录,因为不返回记录没有用处,返回很多时变量装不了。
2.select 语句必须带into

举例

declare
    v_ename emp.ename%type;
    v_sal emp.sal%type;
begin
    select ename,sal into v_ename,v_sal from emp where empno=7369;
    dbms_output.put_line(v_ename||'  '||v_sal);
end;

(2) 放DML、TPL语句

declare
    v_deptno dept.deptno%type:=50;
    v_dname dept.dname%type:='aaaa';
    v_loc dept.loc%type:='bj';
begin
   insert into dept2 values(v_deptno,v_dname,v_loc);
   commit;
end

(3) 放DCL和DDL语句,必须要加execute immediate,如:

begin
    execute immediate 'grant dba to huanghuai';
end;


begin
    execute immediate 'revoke dba from huanghuai';
end;

控制语句
(1) if elsif else

需求:取出7369的薪水,如果<1200,则输出low,如果<2000则输出middle,否则high

declare
    v_sal emp.sal%type;
begin
    select sal into v_sal from emp where empno=7369;
    if(v_sal<1200) then
    dbms_output.put_line('low');
    elsif(v_sal<2000) then
    dbms_output.put_line('middle');
    else
    dbms_output.put_line('high');
    end if;
end;

(2) switch

DECLARE
        v_val NUMBER(1):=3;
 BEGIN    
       CASE(v_val)
               WHEN 1 THEN    DBMS_OUTPUT.put_line('one');
               WHEN 2 THEN    DBMS_OUTPUT.put_line('two');
               ELSE
                    DBMS_OUTPUT.put_line('滚');
       END CASE;
 END;

循环
需求:打印1..10
(1).for()

BEGIN

  FOR i IN  1..10 LOOP
      dbms_output.put_line(i);
  END LOOP;
  dbms_output.put_line('----------------------------');
  --REVERSE 表示倒序输出,从10输出到1
  FOR k IN REVERSE 1..10 LOOP
      dbms_output.put_line(k);
  END LOOP;
END;

(2).while()

DECLARE
  i BINARY_INTEGER:=1;
BEGIN
  WHILE(i<=10) LOOP
      dbms_output.put_line(i); 
      i:=i+1;       
  END LOOP;
END;

(3).do while()

DECLARE
    i BINARY_INTEGER:=1;
BEGIN
    LOOP
       dbms_output.put_line(i);
       i:=i+1;
      EXIT WHEN(i>10);
    END LOOP;
END;

预定义的异常处理

预定义说明的部分 ORACLE 异常错误

错误号异常错误信息名称说明
ORA-0001Dup_val_on_index违反了唯一性限制
ORA-1403No_data_foundSELECT INTO没有找到数据
ORA-1422Too_many_rowsSELECT INTO 返回多行
ORA-1476Zero-divide试图被零除

错误记录

-------------记录错误的方法

 CREATE TABLE errorlog(
        ID NUMBER PRIMARY KEY,
        username    VARCHAR2(20),
        errorcode   NUMBER,
        errmsg      VARCHAR2(1024),
        errdate     DATE      

 );


 CREATE SEQUENCE seq_errorlog MINVALUE 0 START WITH 0 INCREMENT BY 1;

 DECLARE
        v_errcode NUMBER;
        v_errmsg  VARCHAR2(1024);

 BEGIN
        dbms_output.put_line(2/0);
 EXCEPTION
        WHEN OTHERS THEN
        ROLLBACK;
        v_errcode:=SQLCODE;--出错代码
        v_errmsg:=SQLERRM;--出错信息
        INSERT INTO errorlog VALUES(seq_errorlog.nextval,USER,v_errcode,v_errmsg,SYSDATE);
        COMMIT;
 END;

 SELECT * FROM errorlog

 --问题 11:接受 2 个数相除,并显示结果,如果除数为 0,则显示错误提示;
 DECLARE
       a NUMBER;
       b NUMBER;
 BEGIN
       a:=&a;
       b:=&b;

       dbms_output.put_line(a||'/'||b||'='||a/b);

 EXCEPTION
       WHEN zero_divide THEN
             dbms_output.put_line('伙计,除数不能为0');
 END;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值