PL SQL基础

以下是我学习过程中所做的笔记,整理出来希望可以帮助到刚入门的人

/*
PL/SQL程序的基本单元是块(BLOCK),块就是实现一定功能的
逻辑模块。一个PL/SQL程序由一个或多个块组成。块有固定的结
构,也可以嵌套。一个块可以包括三个部分,每个部分由一个关键字
标识。

块中各部分的作用解释如下:
(1) DECLARE:声明部分标志。
(2) BEGIN:可执行部分标志。
(3) EXCEPTION:异常处理部分标志。
(4) END;:程序结束标志。
*/

--要输出结果需要在SQL*Plus环境下执行一次以下的环境设置命令
-- SET SERVEROUTPUT ON

/*
1. SELECT 列名1,列名2... INTO 变量1,变量2... FROM 表名
WHERE 条件;

查询雇员编号为7788的雇员姓名和工资
*/
DECLARE --声明部分标识
  v_name VARCHAR2(10); --定义字符串 
  v_sal  number(5); --定义数据变量
BEGIN
  --可执行部分标识
  SELECT emp.ename, emp.sal
    INTO v_name, v_sal
    FROM SCOTT.EMP emp
   WHERE emp.empno = 7788;
   --输出雇员名和工资
   DBMS_OUTPUT.put_line('7788号雇员是:'||v_name||',工资为:'||to_char(v_sal));
END;--结束标识

--输出结果为:7788号雇员是:SCOTT,工资为:3000

--PL/SQL程序的可执行语句、SQL语句和END结束标识都要以分号结束


/*
  数据类型
  
  数据类型               子类型
  BINARY_INTEGER          NATURAL,POSITIVE
  NUMBER                  DEC,DECIMAL,DOUBLE,PRECISION,PLOAT,INTEGER,INT,NUMERIC,REAL,SMALLINT
  CHAR                    CHARACTER,STRING
  VARCHAR2                VARCHAR
  
  
  类型标识符                   说 明
  NUMBER                       数值型
  INT                          整数型
  BINARY_INTEGER               整数型,带符号
  CHAR                         定长字符型,最大32 767 个字符
  VARCHAR2                     变长字符型,最大32 767 个字符
  LONG                         变长字符型,最长2 GB
  DATE                         日期型,用于存储日期和时间
  BOOLEAN                      布尔型,用于存储逻辑值TRUE 和FALSE
  LOB                          大对象类型,用来存储非结构化数据,长度可达4 GB
*/

/*
2. 变量的定义和初始化
定义了6 个变量, 分别用“ :=” 赋值运算符或
DEFAULT 关键字对变量进行了初始化或赋值。其中:c_tax_rate为常
量,在数据类型前加了“CONSTANT” 关键字;v_valid变量在赋值运算
符前面加了关键字“NOT NULL”,强制不能为空。如果变量是布尔型,
它的值只能是“TRUE”、“FALSE”或“NULL”。变量v_valid
布尔变量的值只能取“TRUE”或“FALSE”
*/
DECLARE --声明部分标识
v_job varchar2(9);
v_count BINARY_INTEGER DEFAULT 0; --DEFAULT用来为变量赋初值
v_total_sal number(9,1) := 0; --∶=用来为变量赋初值
v_date date := sysdate + 7;
c_tax_rate constant number(3,2) := 8.25; --常量
v_valid boolean not null := true; --不能为空
BEGIN
  v_job := 'MANAGER';
  --在程序中赋值
  DBMS_OUTPUT.put_line(v_job);
  --输出变量v_job的值
  DBMS_OUTPUT.put_line(v_count);
  --输出变量v_count的值
  DBMS_OUTPUT.put_line(v_date);
  --输出变量v_date的值
  DBMS_OUTPUT.put_line(c_tax_rate);
  --输出变量c_tax_rate的值
  END;  
  /* 执行结果
  MANAGER
  0
  04-3月 -17
  8.25
  */
  
/*
 3.根据表的字段定义变量
 变量的声明可以根据数据库表的字段进行或根据已经定义的变量进行定义。方式是在表的字段名或已经定义的
 变量后加%TYPE,将其当作数据类型。
 变量名 表名.字段名%TYPE
*/

DECLARE 
v_ename scott.emp.ename%TYPE;--根据字段定义变量
BEGIN
  SELECT emp.ename
  INTO v_ename
  FROM scott.emp emp 
  where emp.empno = 7788;
  DBMS_OUTPUT.put_line(v_ename);
  --输出变量的值
  END;
  --输出结果为:SCOTT

/*
4. 结合变量的使用
结合变量在整个SQL*Plus下有效,使用结合变量可以在不同的程序之间传递信息
使用VARIABLE定义,使用PRING输出
*/
--STEP 1:在SQL*Plus里面创建结合变量g_ename;
--VARIABLE g_ename VARCHAR2(100)

--STEP 2:输入和执行以下程序
BEGIN
  :g_ename:=:g_ename||'Hello~~';
  DBMS_OUTPUT.PUT_LINE(:g_ename);
  END;

/*
5. 记录变量的定义
根据表或视图的一个记录中的所有字段定义变量,称为记录变量。
记录变量包含若干个字段,在结构上同表的一个记录相同,定义的方法是在表名后面加上%ROWTYPE
定义的方法:
记录变量名 表名%ROWTYPE
获取记录变量的字段的方法:
记录变量名.字段名
*/

DECLARE 
emp_record scott.emp%ROWTYPE; --定义记录变量
BEGIN
  SELECT * INTO emp_record
  FROM scott.emp
  where scott.emp.empno = 7788;
  DBMS_OUTPUT.put_line(emp_record.empno||'-'||emp_record.ename||'-'||emp_record.sal);
  end;

--输出结果:7788-SCOTT-3000

/*
6. TABLE类型变量
TABLE类型变量存储可变长度的一维数组数据,即数组中的数据动态的增长。
要定义TABLE变量,需要先定义TABLE数据类型。通过使用下标来引用TABLE变量的元素。
定义方法:
 TYPE 类型名 IS TABLE OF 数据类型[NOT NULL] INDEX BY BINARY_INTEGER
*/

DECLARE
TYPE type_table is TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;--类型说明
v_t type_table; --定义TABLE变量
BEGIN 
  v_t(1) := 'MONDAY';
  v_t(2) := 'TUESDAY';
  v_t(3) := 'WEDNESDAY';
  v_t(4) := 'THURSDAY';
  v_t(5) := 'FRIDAY';
DBMS_OUTPUT.put_line(v_t(3));
END;
--数据结果:WEDNESDAY

/*
运算符和函数
算数运算符:+、-、*、/、**(指数)
关系运算符:<、<=、>、>=、!=/<>
字符运算符:||
逻辑运算符:AND OR NOT
特殊运算符: IS NOLL、IS NOT NULL、LIKE、BETWEEN AND、IN(...)

对空值的算术和比较运算的结果都是空,但对空值可以进行连接运
NULL|| 'ABC' 的结果为'ABC'。
*/

/*
结构控制语句
IF 条件1 THEN
语句序列1;
[ELSIF 条件2 THEN
语句序列2;
ELSE
语句序列n;]
END IF;
其中:
条件部分是一个逻辑表达式,值只能是真、否或者空
IF-THEN-END IF
IF-THEN-ELSE-END IF
IF-THEN-ELSIF-ELSE-END IF
*/

-- IF_THEN-END IF
-- 如果温度大于30,则显示温度偏高
DECLARE
v_temprature number(5):=32;
v_result boolean:=false;
BEGIN
  v_result:=v_temprature > 30;
  IF v_result THEN
    DBMS_OUTPUT.PUT_LINE('温度'||v_temprature||'度,偏高');
    END IF;
 END;
--执行结果:温度32度,偏高

-- IF_THEN-ELSE-END IF
-- 根据性别,显示尊称。
DECLARE
v_sex varchar2(2);
v_titil varchar2(10);
BEGIN
  v_sex := '男';
  IF v_sex='男' THEN
    v_titil:='先生';
    ELSE
      v_titil:='女士';
      END IF;
      DBMS_OUTPUT.PUT_LINE(v_titil||'您好!');
END;
--输出结果:先生您好!

--IF-THEN-ELSIF-ELSE-END IF
--根据雇员工资分级显示税金
DECLARE
v_sal NUMBER(5);
v_tax NUMBER(5,2);
BEGIN
  SELECT emp.sal INTO v_sal
  FROM SCOTT.EMP
  WHERE SCOTT.EMP.EMPNO=7788;
  IF v_sal >= 3000 THEN
    v_tax:=v_sal*0.08;
    ELSIF v_sal >= 1500 THEN
     v_tax:=v_sal*0.06;
    ELSE
      v_tax:=v_sal*0.04;
      END IF;
      DBMS_OUTPUT.PUT_LINE('赢缴税金:'||v_tax);
      END;
--输出结果:赢缴税金:240

/*
选择结构
语法:
CASE 选择变量名
  WHEN 表达式 THEN
  语句序列1
  WHEN 表达式 THEN
  语句序列2
  WHEN 表达式 THEN
  语句序列n
  ELSE
    语句序列n+1
    END CASE;
*/

DECLARE
v_job varchar2(10);
BEGIN
  SELECT emp.job INTO v_job
  FROM SCOTT.EMP emp
  WHERE emp.empno=7839;
  CASE v_job
    WHEN 'PRESIDENT' THEN
    DBMS_OUTPUT.PUT_LINE('雇员职务:总裁');
     WHEN 'MANAGER' THEN
    DBMS_OUTPUT.PUT_LINE('雇员职务:总裁');
     WHEN 'SALESMAN' THEN
    DBMS_OUTPUT.PUT_LINE('雇员职务:总裁');
     WHEN 'ANALYST' THEN
    DBMS_OUTPUT.PUT_LINE('雇员职务:总裁');
     WHEN 'CLERK' THEN
    DBMS_OUTPUT.PUT_LINE('雇员职务:总裁');
    ELSE
      DBMS_OUTPUT.PUT_LINE('雇员职务:未知');
      END CASE;
      END;
 --输出结果:雇员职务:总裁
     
/*
表达式结构CASE语句
语法:
变量=CASE 选择变量名
WHEN 表达式1 THEN 值1
WHEN 表达式2 THEN 值2
WHEN 表达式n THEN 值n
ELSE值n+1
END;  
*/
DECLARE 
v_grade varchar2(10);
v_result varchar2(10);
BEGIN
  v_grade:='B';
  v_result:=CASE v_grade
  WHEN 'A' THEN '优' 
  WHEN 'B' THEN '良'
  WHEN 'C' THEN '中'     
  WHEN 'D' THEN '差'
    END;
    DBMS_OUTPUT.put_line('评价等级:'||V_result);        
    END;    
--输出结果:评价等级:良      
      
/*
搜索CASE结构
没有选择变量,直接判断条件表达式的值,根据条件表达式决定转向
CASE
  WHEN 表达式1  THEN
    语句序列1
  WHEN 表达式2 THEN
    语句序列2
*/      
 DECLARE 
  v_sal varchar2(5);
  begin
    select emp.sal into v_sal from scott.emp emp where emp.empno = 7788;
    case
      when v_sal >= 3000 then
         DBMS_OUTPUT.PUT_LINE('工资等级:高');
      when v_sal >= 1500 then
         DBMS_OUTPUT.PUT_LINE('工资等级:中');       
      else
        DBMS_OUTPUT.PUT_LINE('工资等级:低');
        end case;
        end;
 --输出结果:工资等级:高     
      

/*
 循环结构
 1. LOOP
 2. FOR LOOP
 3. WHILE LOOP
*/

/*
 LOOP  --循环起始标识
   语句1;
   语句2;
   EXIT[WHEN 条件];
   END LOOP;--循环结束标识
   该循环的作用是反复执行LOOP与END LOOP之间的语句
   EXIT用于在循环过程中退出循环,WHEN用于定义EXIT的退出条件。如果没有WHEN条件,遇到EXIT语句
   则无条件退出循环
   
   1²+3²+5²+...+15²的值
*/
DECLARE
v_total number(5):=0;
v_count number(5):=1;
begin
  loop
  v_total:=v_total+v_count**2;
  exit when v_count=15;--条件退出
  v_count := v_count+2;
  end loop;
  DBMS_OUTPUT.PUT_LINE(v_total);
  end;
--输出结果:680

--1*2*3*4*5
declare 
v_result number(5):=1;
v_count number(5):=1;
begin
  loop
    v_result := v_result * v_count;
    exit when v_count = 5;
    v_count := v_count + 1;
    end loop;
     DBMS_OUTPUT.PUT_LINE(v_result);
    end;
 --输出结果:120
  

/*
FOR LOOP 循环
  FOR循环是固定次数循环,格式如下
  FOR 控制变量in [REVERSE] 下限..上限
    LOOP
      语句1;
      语句2;
    END LOOP;
*/
declare 
begin
  for i in 1..10
    loop
      dbms_output.put_line(to_char(i)||rpad('*', i, '*'));
      end loop;
      end;

/*
输出结果为:
1*
2**
3***
4****
5*****
6******
7*******
8********
9*********
10**********
*/

/*
为以上程序加REVERSE关键字,观察执行结果。
输出一个空心三角
*/
declare 
BEGIN
  FOR I IN 1..9
    LOOP
      IF I=1 OR I=9 THEN
        DBMS_OUTPUT.PUT_LINE(to_char(I)||rpad('          ',12-I,'')||rpad('*',2*I-1,'*'));
      ELSE
        DBMS_OUTPUT.PUT_LINE(to_char(I)||rpad(' ',12-I,' ')||'*'||rpad('',I*2-3,' ')||'*');
        END IF;
        END LOOP;
        END;
        
 /*
 WHILE LOOP 循环
   WHILE循环是有条件循环,格式如下:
   WHILE 条件
     LOOP
       语句1:
       语句2:
     END LOOP;
 */    
  DECLARE 
  v_count number(2):=1;
  begin
    WHILE v_count<6 LOOP
      INSERT INTO SCOTT.EMP(EMPNO, ENAME) values(5000+v_count, '临时');
      v_count := v_count +1;
      end loop;
      end;      

/*
--执行结果
select * from scott.emp
1	5001	临时						
2	5002	临时						
3	5003	临时						
4	5004	临时						
5	5005	临时						
*/

/*
多重循环
使用二重循环求1!+2!+...+10!的值
*/
DECLARE
v_total number(8):=0;
v_ni number(8):=0;
J number(5);
begin
  for i in 1..10
    loop
      J:=1;
      v_ni:=1;
      while J<=I
        loop
        v_ni := v_ni * J;
        J := J+1;
        end loop;--内循环求n!
        v_total := v_total + v_ni;
end loop;
DBMS_OUTPUT.put_line(v_total);
end;
--执行结果:4037913

DECLARE 
v_empno number(5) := 7188;
v_num number(10):=0;
begin
  select count(*) into v_num from scott.emp emp where emp.empno = v_empno; 
  if v_num > 0 then
    DBMS_OUTPUT.put_line('已存在');
    else
      insert into scott.emp(empno, ename) values(v_empno, 'xxxx');
      COMMIT;
      DBMS_OUTPUT.put_line('插入成功');
    end if;
    end;
    
 select * from scott.emp
    
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值