PL/SQL块结构

DECLARE
  --声明部分 
BEGIN
  --执行部分,必须
EXCEPTION
  --异常处理部分,可选
END;

–定义一个PL/SQL代码块,计算俩个整数的和与这俩个整数的差的商

DECLARE
  A INT := 100;
  B INT := 200;
  C NUMBER;
BEGIN
  C := (A + B) / (A - B);
  DBMS_OUTPUT.PUT_LINE(C);
END;

数据类型与定义变量和常量

基本数据类型
–数值类型:
–NUMBER -整数、浮点数
–BINARY_INTEGER PLS_INTEGER -整数

–字符类型:
–VARCHAR2 -可变长度字符串
–CHAR -指定长度字符串
–LONG -可变长度字符串 最大长度32767字节
–NCHAR NVARCHAR2 -这俩种数据类型的长度要根据各国字符集来确定

–日期类型:
–DATE -7个字节 分别存储 世纪、年、月、日、小时、分钟、秒

–布尔类型
–BOOLEAN -值为 TRUE、FALSE、NULL

特殊数据类型
–%TYPE -用于声明一个与指定列名称相同的数据类型 如:var_job emp.job%type;

  • RECORD -记录类型
--示例:
DECLARE
  TYPE EMP_TYPE IS RECORD --声明RECORD类型EMP_TYPE
  (
    VAR_ENAME VARCHAR2(20),
    VAR_JOB   VARCHAR2(20),
    VAR_SAL   NUMBER);
  EMPINFO EMP_TYPE; --定义变量
BEGIN
  SELECT ENAME, JOB, SAL INTO EMPINFO FROM EMP WHERE EMPNO = 7369;
  DBMS_OUTPUT.PUT_LINE('雇员' || EMPINFO.VAR_ENAME || '的职务是' ||
                       EMPINFO.VAR_JOB || '、工资是' || EMPINFO.VAR_SAL);
END;
  • %ROWTYPE类型 记录一行数据类型 如:rowVar_name emp%rowtype;
--示例:
DECLARE
  ROWVAR_EMP EMP%ROWTYPE;
BEGIN
  SELECT * INTO ROWVAR_EMP FROM EMP WHERE EMPNO = 7369;
  DBMS_OUTPUT.PUT_LINE('雇员' || ROWVAR_EMP.ENAME || '的编号是' ||
                       ROWVAR_EMP.EMPNO || ',职务是' || ROWVAR_EMP.JOB);
END;

—–定义变量和常量
–定义变量 如:var_ename varchar2(50) := ‘XX’;

–定义常量 如:con_mgr constant integer := 233;

流程控制语句

  • 选择语句

if…then
定义俩个字符串变量,然后赋值,接着使用if…then比较俩个字符串长度,输出结果

DECLARE
  VAR_NAME1 VARCHAR2(20);
  VAR_NAME2 VARCHAR2(20);
BEGIN
  VAR_NAME1 := 'zhangsan';
  VAR_NAME2 := 'lisi';
  IF LENGTH(VAR_NAME1) > LENGTH(VAR_NAME2) THEN
    DBMS_OUTPUT.PUT_LINE('字符串' || VAR_NAME1 || '的长度比字符串' || VAR_NAME2 ||
                         '的长度长');
  END IF;
END;

if…then…else
使用该语句实现当年龄大于等于18就成年,否则未成年

DECLARE
  VAR_AGE INT := 18;
BEGIN
  IF VAR_AGE >= 18 THEN
    DBMS_OUTPUT.PUT_LINE(VAR_AGE || '已成年');
  ELSE
    DBMS_OUTPUT.PUT_LINE(VAR_AGE || '未成年');
  END IF;
END;

if…then…elsif
使用该语句判断月份属于哪个季节

DECLARE
  VAR_MONTH INT := 5;
BEGIN
  IF VAR_MONTH >= 0 AND VAR_MONTH <= 3 THEN
    DBMS_OUTPUT.PUT_LINE(VAR_MONTH || '是春季');
  ELSIF VAR_MONTH >= 4 AND VAR_MONTH <= 6 THEN
    DBMS_OUTPUT.PUT_LINE(VAR_MONTH || '是夏季');
  ELSIF VAR_MONTH >= 7 AND VAR_MONTH <= 9 THEN
    DBMS_OUTPUT.PUT_LINE(VAR_MONTH || '是秋季');
  ELSE
    DBMS_OUTPUT.PUT_LINE(VAR_MONTH || '是冬季');
  END IF;
END;

case语句
使用该语句判断月份属于哪个季节

DECLARE
  VAR_MONTH  INT := 5;
  VAR_RESULT VARCHAR2(50);
BEGIN
  CASE
    WHEN (VAR_MONTH >= 0 AND VAR_MONTH <= 3) THEN
      VAR_RESULT := VAR_MONTH || '是春季';
    WHEN (VAR_MONTH >= 4 AND VAR_MONTH <= 6) THEN
      VAR_RESULT := VAR_MONTH || '是夏季';
    WHEN (VAR_MONTH >= 7 AND VAR_MONTH <= 9) THEN
      VAR_RESULT := VAR_MONTH || '是秋季';
    ELSE
      VAR_RESULT := VAR_MONTH || '是冬季';
  END CASE;
  DBMS_OUTPUT.PUT_LINE(VAR_RESULT);
END;
  • 循环语句
    loop语句
    loop语句会先执行一次循环体,然后再判断”exit when”关键字后面的条件表达式值是true还是false,
    如果是true,则程序会退出循环体,否则程序将再次执行循环体,因此循环体至少执行一次。
    求1+2+3+…+100
DECLARE
  VAR_SUM INT := 0;
  VAR_I   INT := 0;
BEGIN
  LOOP
    VAR_I   := VAR_I + 1;
    VAR_SUM := VAR_SUM + VAR_I;
    EXIT WHEN VAR_I = 100;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE('和为:' || VAR_SUM);
END;

while语句
while语句根据它的条件表达式的值执行零次或多次循环体,在执行循环体之前,
首先要判断条件表达式的值是否为true,若为true,则程序执行循环体,
否则退出while循环,然后继续执行while语句后面的代码
求1+2+3+…+100

DECLARE
  VAR_SUM INT := 0;
  VAR_I   INT := 1;
BEGIN
  WHILE VAR_I <= 100 LOOP
    VAR_SUM := VAR_SUM + VAR_I;
    VAR_I   := VAR_I + 1;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE('和为:' || VAR_SUM);
END;

for语句
for语句是一个可预置循环次数的循环控制语句,它有一个循环计数器,通常是一个整形变量,
通过这个计数器来控制循环体执行次数,可以从小到大,也可以从大到小。
求1+3+5+…+99

DECLARE
  VAR_SUM INT := 0;
BEGIN
  FOR I IN REVERSE 1..100 LOOP
    IF MOD(i,2) = 1 THEN
      VAR_SUM := VAR_SUM + I;
    END IF;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE('和为:' || VAR_SUM);
END;

顺序控制

–goto语句:表示无条件跳转到指定的标号去
–null:表示不执行任何操作,在PL/SQL中,不执行操作不可以空着,需要使用null语句来占位

--计算1+2+3...+N,当结果大于100时退出并输出N的值
DECLARE
  V_SUM NUMBER := 0;
  V_N   NUMBER := 1;
BEGIN
  LOOP
    V_SUM := V_SUM + V_N;
    IF V_SUM > 100 THEN
      GOTO LABELOFFLOOP;--满足条件跳转到labeloffloop标签处
    ELSE
      NULL;--不做任何事必须用NULL语句占位
    END IF;
    V_N := V_N + 1;
  END LOOP;
  <<LABELOFFLOOP>>
  DBMS_OUTPUT.PUT_LINE('N:' || V_N);
END;