PL(Procedural Language)过程化的编程语言,是在SQL的基础上增加的部分,如:变量的使用、流程控制等,

重点学习Oracle和MySQL创建存储过程及流程控制的异同。

一、存储过程的创建、调用:

语法:
CREATE OR REPLACE PROCEDURE <存储过程名> [(参数名称 参数的传递方向 数据类型)]
{AS|IS}
BEGIN
   DECLARE <变量名> 数据类型 := 初始值;
    变量名 := 值;
  BEGIN
    --存储过程体。
  END;
END;

说明:
 1、若没有参数就不能加小括号,MySQL都需要加
 2、参数的传递方向放再第二个位置,MySQL放在第一个位置。
3、存储过程定义部分结束后添加AS或IS,MySQL不需要。
4、当使用DECLARE定义完变量后需要再添加BEGIN END 包裹存储过程体的内容
5、调用存储过程使用“EXECUTE 存储过程名称();”或者将存储过程包裹在BEGIN END之间执行。


-- 实现加法运算的存储过程
CREATE OR REPLACE PROCEDURE proc_add(num1 NUMBER,num2 NUMBER)
AS 
BEGIN
  DECLARE 
  resault1 NUMBER(10,2) := 0;
  BEGIN
    resault1 := num1 + num2;
    dbms_output.put_line('结果为:' || resault1);
  END;
END; 


-- 若使用了dbms_output.put_line()输出,需要先打开显示开关才能查看结果
SET SERVEROUTPUT ON;
-- 调用
EXECUTE proc_add(10.5,20);
/*或者下面的方式*/
BEGIN
  proc_add(10.5,20);
END;

2.  流程控制之IF语句:

IF <条件表达式1> THEN
  #语句块1
[ELSIF <条件表达式2>THEN
  #语句块2
  END IF;
。。。。。。。]
END IF;

案例:
-- 案例描述:用户输入“课程编号”,查询对应编号的课程名称
CREATE OR REPLACE PROCEDURE proc_selectsubjec(id NUMBER)
AS 
BEGIN
  DECLARE
    subjectName VARCHAR2(20);
  BEGIN
      IF id = 1 THEN
        SELECT subject_name INTO subjectName FROM tb_subject WHERE subject_id = 1;
         dbms_output.put_line('结果为:' || subjectName);
      ELSIF id = 2 THEN
        SELECT subject_name INTO subjectName FROM tb_subject WHERE subject_id = 2;
        dbms_output.put_line('结果为:' || subjectName);
      ELSIF id = 3 THEN
        SELECT subject_name INTO subjectName FROM tb_subject WHERE subject_id = 3;
        dbms_output.put_line('结果为:' || subjectName);
      ELSE
         dbms_output.put_line( '您的输入有误!');
      END IF;
  END;
END;

-- 调用
EXECUTE proc_selectsubjec(3);

3.  流程控制之CASE语句: 

CASE <常量>
WHEN 值1 THEN
   #语句块1
WHEN 值2 THEN
  #语句块3
[ELSE #语句块N]
END CASE;

-- 输入编号,查看课程名称
CREATE OR REPLACE PROCEDURE proc_selectsubjec_case(id NUMBER)
AS 
BEGIN
  DECLARE
    subjectName VARCHAR2(20);
  BEGIN
      CASE(id)
        WHEN 1 THEN
          SELECT subject_name INTO subjectName FROM tb_subject WHERE subject_id = 1;
           dbms_output.put_line('结果为:' || subjectName);
        WHEN  2 THEN
          SELECT subject_name INTO subjectName FROM tb_subject WHERE subject_id = 2;
          dbms_output.put_line('结果为:' || subjectName);
        WHEN 3 THEN
          SELECT subject_name INTO subjectName FROM tb_subject WHERE subject_id = 3;
          dbms_output.put_line('结果为:' || subjectName);
        ELSE
           dbms_output.put_line( '您的输入有误!');
        END CASE;
  END;
END;

-- 调用
EXECUTE proc_selectsubjec(3);

4.  流程控制之LOOP语句结合IF语句:

语法:
LOOP
 IF<条件表达式1> THEN
   EXIT;
 END IF;
  编写循环体中的代码块,需要手动更新条件。
END LOOP

举例: 
-- 循环输出指定次数的提示信息。
CREATE OR REPLACE PROCEDURE proc_loopif(maxNums IN  NUMBER)
AS
BEGIN
  DECLARE 
    nums NUMBER(20) := 1;
  BEGIN
    LOOP 
      IF nums > maxNums THEN
         EXIT;
      END IF;
       dbms_output.put_line( '第'||nums||'次输出');
       nums := nums + 1;
     END LOOP;
  END;
END;

-- 调用
EXECUTE proc_loopif(10);

 5. 流程控制之LOOP语句结合WHEN语句:

语法:
LOOP
  EXIT WHEN <条件表达式>;
   编写循环体中的代码块,需要手动更新条件。
END LOOP;
举例: 
-- 循环输出指定次数的提示信息。
CREATE OR REPLACE PROCEDURE proc_loopwhen(maxNums IN  NUMBER)
AS
BEGIN
  DECLARE 
    nums NUMBER(20) := 1;
  BEGIN
   LOOP 
      EXIT WHEN nums> maxNums;
       dbms_output.put_line( '第'||nums||'次输出');
       nums := nums + 1;
     END LOOP;
  END;
END;

-- 调用
EXECUTE proc_loopwhen(10);

6.  流程控制之LOOP语句结合WHILE语句: 

语法:
WHILE <条件表达式>
LOOP
   编写循环体中的代码块,需要手动更新条件。
END LOOP;
举例: 
-- 循环输出指定次数的提示信息。
CREATE OR REPLACE PROCEDURE proc_loopwhile(maxNums IN  NUMBER)
AS
BEGIN
  DECLARE 
    nums NUMBER(20) := 1;
  BEGIN
   WHILE nums <= maxNums
   LOOP 
     dbms_output.put_line( '第'||nums||'次输出');
       nums := nums + 1;
     END LOOP;
  END;
END;

-- 调用
EXECUTE proc_loopwhile(10);

7.  流程控制之LOOP语句结合FOR语句:

/*
语法:
FOR 循环变量 IN 循环起始值..循环的终止值
LOOP
   编写循环体中的代码块,需要手动更新条件。
END LOOP;
*/
-- 循环输出指定次数的提示信息。
CREATE OR REPLACE PROCEDURE proc_loopfor(maxNums IN  NUMBER)
AS
BEGIN
   FOR nums IN 1..maxNums
   LOOP 
     dbms_output.put_line( '第'||nums||'次输出');
   END LOOP;
END;

-- 调用
EXECUTE proc_loopfor(10);

二、   批量插入记录:字段值采用随机生成

以tb_student为例,完成批量插入记录

CREATE OR REPLACE PROCEDURE proc_batchinsertstudent(recordNums IN NUMBER)
AS
BEGIN
  DECLARE 
    nos NUMBER(10) := 11;
    mobile CHAR(11);
  BEGIN
    FOR nums IN 1..recordNums
    LOOP 
      mobile := '1' || substr(dbms_random.value(),3,10);
      INSERT INTO TB_STUDENT VALUES(
        's' || nos, /*STUDENT_NO*/
        dbms_random.string('A',6), /*LOGIN_PWD*/
        sys_guid(), /*STUDENT_NAME*/
        substr('男女',CEIL(dbms_random.value(0,2)),1), /*SEX*/
        CEIL(dbms_random.value(0,5)), /*GRADE_ID*/
        mobile , /*PHONE*/
        substr('批量插入记录字段值这里面的值采用随机截取',CEIL(dbms_random.value(1,84)),ROUND(dbms_random.value(5,10))), /*ADDRESS*/ 
        to_date(to_char(to_date('1990-01-01','yyyy-mm-dd'),'J') + TRUNC(dbms_random.value(0,366)),'J'), /*日期*/
        mobile || '@qq.com' /*电子邮箱*/
      );
      nos := nos + 1;
    END LOOP;
  END;
END;


-- 调用
EXECUTE proc_batchinsertstudent(1000);

select * from tb_student ORDER BY STUDENT_NO;

DELETE FROM tb_student where STUDENT_NO > 's10';