oracle笔记pl/sql流程控制

本文深入探讨了PL/SQL中的流程控制语句,包括条件判断(IF-ELSE)、CASE语句、循环(LOOP、WHILE、FOR)的使用方法,并通过实例展示了如何在PL/SQL中进行复杂的逻辑判断和循环操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*

pl/sql流程控制

*/

/*
查询出 150号 员工的工资, 若其工资大于或等于 10000 则打印 'salary >= 10000'; 
若在 5000 到 10000 之间, 则打印 '5000<= salary < 10000'; 否则打印 'salary < 5000'
*/
DECLARE
v_salary employees.salary%TYPE;
BEGIN
  SELECT salary INTO v_salary FROM employees WHERE employee_id = 150;
  dbms_output.put_line('150号员工的薪水为' || v_salary);
  IF v_salary >= 10000 THEN dbms_output.put_line('salary >= 10000');
  ELSIF v_salary >= 5000 THEN dbms_output.put_line('5000<= salary < 10000');
  ELSE dbms_output.put_line('salary < 5000');
  END IF; --END IF;相当于java中的结束大括号,pl/sql中使用END IF关键字充当结束大括号
END;

--
DECLARE
v_salary employees.salary%TYPE;
v_employee_id employees.employee_id%TYPE;
BEGIN
  v_employee_id := 150; --给v_employee_id变量赋值
  SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id变量
  dbms_output.put_line(v_employee_id || '号员工的薪水=' || v_salary);
  IF v_salary >= 10000 THEN dbms_output.put_line('salary >= 10000');
  ELSIF v_salary >= 5000 THEN dbms_output.put_line('5000<= salary < 10000');
  ELSE dbms_output.put_line('salary < 5000');
  END IF; --END IF;相当于java中的结束大括号,pl/sql中使用END IF关键字充当结束大括号
END;


--另外一种写法
DECLARE
v_salary employees.salary%TYPE;
v_employee_id employees.employee_id%TYPE;
v_temp VARCHAR2(50);
BEGIN
  v_employee_id := 150; --给v_employee_id变量赋值
  SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id变量
  dbms_output.put_line(v_employee_id || '号员工的薪水=' || v_salary);
  IF v_salary >= 10000 THEN v_temp := 'salary >= 10000';
  ELSIF v_salary >= 5000 THEN v_temp := '5000<= salary < 10000';
  ELSE  v_temp := 'salary < 5000';
  END IF; --END IF;相当于java中的结束大括号,pl/sql中使用END IF关键字充当结束大括号
  dbms_output.put_line('薪水=' || v_salary || ',' || v_temp);
END;

--改成case的写法
/*
--以下这种写法是错误的,会报错
DECLARE
v_salary employees.salary%TYPE;
v_employee_id employees.employee_id%TYPE;
v_temp VARCHAR2(50);
BEGIN
  v_employee_id := 150; --给v_employee_id变量赋值
  SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id变量
  dbms_output.put_line(v_employee_id || '号员工的薪水=' || v_salary);
  v_temp :=
  CASE v_salary WHEN v_salary >= 10000 THEN  'salary >= 10000'
                WHEN v_salary >= 5000 THEN '5000<= salary < 10000'
  ELSE  'salary < 5000'
  END;
  dbms_output.put_line('薪水=' || v_salary || ',' || v_temp);             
END;

*/

--以下写法正确
DECLARE
v_salary employees.salary%TYPE;
v_employee_id employees.employee_id%TYPE;
v_temp VARCHAR2(50);
BEGIN
  v_employee_id := 150; --给v_employee_id变量赋值
  SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id变量
  dbms_output.put_line(v_employee_id || '号员工的薪水=' || v_salary);
  v_temp :=
  CASE WHEN v_salary >= 10000 THEN  'salary >= 10000'
                WHEN v_salary >= 5000 THEN '5000<= salary < 10000'
  ELSE  'salary < 5000'
  END;
  dbms_output.put_line('薪水=' || v_salary || ',' || v_temp);             
END;

/*

--以下这种写法是错误的,会报错
DECLARE
v_salary employees.salary%TYPE;
v_employee_id employees.employee_id%TYPE;
v_temp VARCHAR2(50);
BEGIN
  v_employee_id := 150; --给v_employee_id变量赋值
  SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id变量
  dbms_output.put_line(v_employee_id || '号员工的薪水=' || v_salary);
  
  (CASE WHEN v_salary >= 10000 THEN  v_temp := 'salary >= 10000'
                WHEN v_salary >= 5000 THEN v_temp := '5000<= salary < 10000'
  ELSE v_temp := 'salary < 5000'
  END);
  dbms_output.put_line('薪水=' || v_salary || ',' || v_temp);             
END;

--以下这种写法是错误的,会报错
DECLARE
v_salary employees.salary%TYPE;
v_employee_id employees.employee_id%TYPE;
v_temp VARCHAR2(50);
BEGIN
  v_employee_id := 150; --给v_employee_id变量赋值
  SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id变量
  dbms_output.put_line(v_employee_id || '号员工的薪水=' || v_salary);
  
  CASE WHEN v_salary >= 10000 THEN  v_temp := 'salary >= 10000'
                WHEN v_salary >= 5000 THEN v_temp := '5000<= salary < 10000'
  ELSE v_temp := 'salary < 5000'
  END;
  dbms_output.put_line('薪水=' || v_salary || ',' || v_temp);             
END;

*/

--以下写法正确
DECLARE
v_salary employees.salary%TYPE;
v_employee_id employees.employee_id%TYPE;
v_temp VARCHAR2(50);
BEGIN
  v_employee_id := 150; --给v_employee_id变量赋值
  SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id变量
  dbms_output.put_line(v_employee_id || '号员工的薪水=' || v_salary);
  v_temp :=
  (CASE WHEN v_salary >= 10000 THEN  'salary >= 10000'
                WHEN v_salary >= 5000 THEN '5000<= salary < 10000'
  ELSE  'salary < 5000'
  END);
  dbms_output.put_line('薪水=' || v_salary || ',' || v_temp);             
END;

--
DECLARE
v_salary employees.salary%TYPE;
v_employee_id employees.employee_id%TYPE;
v_temp VARCHAR2(50);
BEGIN
  v_employee_id := 150; --给v_employee_id变量赋值
  SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id变量
  dbms_output.put_line(v_employee_id || '号员工的薪水=' || v_salary);
  v_temp :=
  CASE trunc(v_salary / 5000) 
    WHEN 0 THEN  'salary < 5000'
    WHEN 1 THEN '5000<= salary < 10000'
    ELSE 'salary >= 10000'
  END;
  dbms_output.put_line('薪水=' || v_salary || ',' || v_temp);             
END;

--
DECLARE
v_salary employees.salary%TYPE;
v_employee_id employees.employee_id%TYPE;
v_temp VARCHAR2(50);
BEGIN
  v_employee_id := 150; --给v_employee_id变量赋值
  SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id变量
  dbms_output.put_line(v_employee_id || '号员工的薪水=' || v_salary);
  v_temp :=
  CASE WHEN v_salary >= 10000 THEN 'salary >= 10000'
                WHEN v_salary >= 5000 THEN '5000<= salary < 10000'
  ELSE 'salary < 5000'
  END;
  dbms_output.put_line('薪水=' || v_salary || ',' || v_temp);             
END;

--
DECLARE
v_salary employees.salary%TYPE;
v_employee_id employees.employee_id%TYPE;
v_temp VARCHAR2(50);
BEGIN
  v_employee_id := 150; --给v_employee_id变量赋值
  SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id变量
  dbms_output.put_line(v_employee_id || '号员工的薪水=' || v_salary);
  v_temp :=
  (CASE WHEN v_salary >= 10000 THEN 'salary >= 10000'
                WHEN v_salary >= 5000 THEN '5000<= salary < 10000'
  ELSE 'salary < 5000'
  END);
  dbms_output.put_line('薪水=' || v_salary || ',' || v_temp);             
END;




/*

以前的知识回顾

*/
--以下这2种写法都可以
--
SELECT (CASE department_id WHEN 80 THEN '80号部门' WHEN 90 THEN '90号部门' END) FROM employees
--
SELECT (CASE WHEN department_id = 80 THEN '80号部门' WHEN department_id = 90 THEN '90号部门' END) FROM employees

--
SELECT job_id FROM employees

/*

回顾知识点 CASE... WHEN... THEN... WHEN... THEN... ELSE... END

*/

--以下写法正确
SELECT (CASE job_id WHEN 'IT_PROG' THEN 'IT岗位' WHEN 'SA_REP' THEN '销售岗位' END) FROM employees

--以下写法错误,会报错
SELECT (CASE salary WHEN salary >= 5000  THEN '薪水大于5000' WHEN salary < 5000 THEN '薪水小于5000' END) FROM employees

--以下写法正确
SELECT (CASE WHEN salary >= 5000  THEN '薪水大于5000' WHEN salary < 5000 THEN '薪水小于5000' END) FROM employees

--以下写法错误
SELECT (CASE WHEN salary >= 5000  THEN salary = 10 WHEN salary < 5000 THEN salary = 20 END) FROM employees

--以下写法正确
SELECT (CASE salary WHEN 24000  THEN '薪水等于24000' WHEN 8000 THEN '薪水等于8000' END) FROM employees


--以下写法正确
SELECT (CASE salary WHEN 24000  THEN '薪水等于24000' WHEN 8000 THEN '薪水等于8000' ELSE 'hello world' END) FROM employees

--以下写法正确
SELECT salary, (CASE salary WHEN 24000  THEN salary + 10 WHEN 8000 THEN salary + 20 ELSE salary + 30 END) FROM employees

--以下写法错误,会报错
SELECT salary, (CASE salary WHEN 24000  THEN salary = salary + 10 WHEN 8000 THEN salary = salary + 20 ELSE salary = salary + 30 END) FROM employees

--以下写法错误,会报错
SELECT salary, (CASE salary WHEN 24000  THEN salary = 10 WHEN 8000 THEN salary = 20 ELSE salary = 30 END) FROM employees

SELECT * FROM employees


-----------------------------------------
/*
查询出 122 号员工的 JOB_ID, 若其值为 'IT_PROG', 则打印 'GRADE: A'; 
'AC_MGT', 打印 'GRADE B', 
'AC_ACCOUNT', 打印 'GRADE C'; 
否则打印 'GRADE D'
*/
--使用if ELSIF 
DECLARE 
v_job_id employees.job_id%TYPE;
v_grade VARCHAR2(50);
BEGIN
  SELECT job_id INTO v_job_id FROM employees WHERE employee_id = 122;
  IF v_job_id = 'IT_PROG' THEN v_grade := 'GRADE: A';
  ELSIF v_job_id = 'AC_MGT' THEN v_grade := 'GRADE: B';
  ELSIF v_job_id = 'AC_ACCOUNT' THEN v_grade := 'GRADE: C';
  ELSE v_grade := 'GRADE: D';
  END IF;
  dbms_output.put_line(v_job_id || ' ,grade = ' || v_grade);
END;

--使用CASE WHEN THEN
DECLARE 
v_job_id employees.job_id%TYPE;
v_grade VARCHAR2(50);
BEGIN
 SELECT job_id INTO v_job_id FROM employees WHERE employee_id = 122;
 v_grade := 
 CASE v_job_id 
   WHEN 'IT_PROG' THEN 'A'
   WHEN 'AC_MGT' THEN 'B'
   WHEN 'AC_ACCOUNT' THEN 'C'
   ELSE 'D'
 END;
 dbms_output.put_line(v_job_id || ' , ' || v_grade);
END;
 
 
/*

循环知识点

*/  

--使用循环打印数字1-100
-- 1初始化条件  2循环体  3循环条件  4迭代条件 
DECLARE
--1
v_number NUMBER(6) := 1;--定义一个变量并赋值 (:=是赋值符号)
BEGIN
  LOOP 
    --2
    dbms_output.put_line('数字' || v_number);
    --3
  EXIT WHEN v_number > 100;
  --4
  v_number := v_number + 1;
  END LOOP;
END;

--
DECLARE
v_number NUMBER(6) := 1;
BEGIN
  LOOP 
    dbms_output.put_line('数字' || v_number);
  EXIT WHEN v_number >= 100;
  v_number := v_number + 1; -- 可以放在这里
  END LOOP;
END;

--以下这样写也可以
DECLARE
v_number NUMBER(6) := 1;
BEGIN
  LOOP 
    dbms_output.put_line('数字' || v_number);
    v_number := v_number + 1; --也可以放在这里
  EXIT WHEN v_number >= 100;
  END LOOP;
  
END;

--
DECLARE
v_number NUMBER(6) := 1;
BEGIN
  LOOP 
    dbms_output.put_line('数字' || v_number);
    v_number := v_number + 1; --
  EXIT WHEN v_number > 100;
  END LOOP;
  
END;

--
DECLARE
v_number NUMBER(6) := 1;
BEGIN
  LOOP 
    dbms_output.put_line('数字' || v_number);
    v_number := v_number + 1; --
  EXIT WHEN v_number > 100;
  END LOOP;
  
END;


--第二种循环方式 while
DECLARE
v_number NUMBER(6) := 1;
BEGIN
 WHILE v_number <= 100 LOOP
   dbms_output.put_line('数字' || v_number);
   v_number := v_number + 1;
   END LOOP;
END;

/*
每循环一次,循环变量自动加1;使用关键字REVERSE,循环变量自动减1。
跟在IN REVERSE 后面的数字必须是从小到大的顺序,而且必须是整数,
不能是变量或表达式。可以使用EXIT 退出循环
*/

--第三种循环方式 for循环
BEGIN
  FOR mynumber IN 1..100 LOOP
   dbms_output.put_line('数字' || mynumber); 
   END LOOP;
END;

--使用REVERSE(反转)关键字
BEGIN
  FOR mynumber IN REVERSE 1..100 LOOP
   dbms_output.put_line('数字' || mynumber);
   END LOOP;
END;

--null语句
/*
NULL:在PL/SQL 程序中,可以用 null 语句来说明“不用做任何事情”的意思,相当于一个占位符,可以使某些语句变得有意义,提高程序的可读性
*/
--从employees表中查数据,如果薪水大于20000,则打印'土豪,我们做个朋友吧',如果薪水小于20000,不做任何处理
DECLARE v_salary employees.salary%Type ; 
BEGIN 
SELECT salary INTO v_salary FROM employees WHERE employee_id = 100; 
IF v_salary > 20000 THEN dbms_output.put_line('土豪,我们做个朋友吧');
ELSE NULL; --null语句
END IF; 
END;

--
SELECT SQRT(2), SQRT(3), SQRT(4), SQRT(16), SQRT(9), SQRT(36) FROM dual;
SELECT MOD(4, 2), MOD(36, 4), MOD(25, 6) FROM dual;
--

/*

输出2-100之间的质数 (java的面试中很多时候都会考这道题目,不光可以考察多层嵌套循环,还可以考察break、sqrt()函数、
小算法、条件判断结构、效率性能等等知识点,而且题目还不算太大太难,所以大家最好要会写)

*/
--使用while写法
DECLARE
  V_I    NUMBER(5) := 2;
  V_J    NUMBER(5) := 2;
  V_FLAG NUMBER(1) := 1;
BEGIN
  WHILE V_I <= 100 LOOP
    WHILE V_J <= SQRT(V_I) LOOP
      IF MOD(V_I, V_J) = 0 THEN
        V_FLAG := 0;
      END IF;
      V_J := V_J + 1;
    END LOOP;
    IF V_FLAG = 1 THEN
      DBMS_OUTPUT.PUT_LINE('质数' || V_I);
    END IF;
    V_I    := V_I + 1;
    V_FLAG := 1;
   -- V_J    := 2; --这行代码注释掉就无法求出正确的质数
   V_J    := 2;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE('内层循环的V_J=' || V_J);
END;

--使用for循环的写法,如下
DECLARE
  V_FLAG NUMBER(1) := 1;
  V_COUNT NUMBER(10) := 0;
BEGIN
  FOR i IN 2..100 LOOP
    
   FOR j IN 2..sqrt(i) LOOP 
     IF(MOD(i, j) = 0) THEN V_FLAG := 0;
     END IF;
     END LOOP;
     IF(V_FLAG = 1) THEN dbms_output.put_line('质数' || i);
     V_COUNT := V_COUNT + 1; --统计有几个质数
     END IF;
     V_FLAG := 1;
   END LOOP;
   dbms_output.put_line('共有' || V_COUNT || '个质数');
END;

--改进上面的代码,使效率更高
DECLARE
  V_FLAG NUMBER(1) := 1;
  V_COUNT NUMBER(10) := 0;
BEGIN
  FOR i IN 2..100 LOOP
    
   FOR j IN 2..sqrt(i) LOOP 
     IF(MOD(i, j) = 0) THEN V_FLAG := 0;
     --PL/SQL中GOTO语句是无条件跳转到指定的标号去的意思
     GOTO LABEL; --(这里使用GOTO提高了效率性能)
     END IF;
     END LOOP;
     <<LABEL>>
     IF(V_FLAG = 1) THEN dbms_output.put_line('质数' || i);
     V_COUNT := V_COUNT + 1; --统计有几个质数
     END IF;
     V_FLAG := 1;
   END LOOP;
   dbms_output.put_line('共有' || V_COUNT || '个质数');
END;

--使用 goto
--打印1——100的自然数,当打印到50时,跳出循环,输出“打印结束”
--方式1
DECLARE
v_number NUMBER(5) := 100; --赋值
BEGIN
  FOR mynumber IN 1.. v_number LOOP
    IF mynumber = 50 THEN GOTO LABEL;
    END IF;
    dbms_output.put_line('自然数' || mynumber);
  END LOOP;
  <<LABEL>>
  dbms_output.put_line('打印结束');
END;

--
BEGIN
  FOR I IN 1 .. 100 LOOP
    DBMS_OUTPUT.PUT_LINE(I);
    IF (I = 50) THEN
      GOTO LABEL;
    END IF;
  END LOOP;

  <<LABEL>>
  DBMS_OUTPUT.PUT_LINE('打印结束');

END;

--方式2(使用exit关键字)
DECLARE
v_number NUMBER(5) := 100; --赋值
BEGIN
  FOR mynumber IN 1.. v_number LOOP
    IF mynumber = 50 THEN dbms_output.put_line('打印结束'); 
      EXIT; --使用exit关键字
    END IF;
    dbms_output.put_line('自然数' || mynumber);
  END LOOP;
END;

--(使用exit关键字)
DECLARE
v_number NUMBER(5) := 100; --赋值
BEGIN
  FOR mynumber IN 1.. v_number LOOP
    IF mynumber = 50 THEN EXIT; --使用exit关键字 
    END IF;
    dbms_output.put_line('自然数' || mynumber);
  END LOOP;
  dbms_output.put_line('打印结束');
END;

 

基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你类似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
MPU6050是一款广泛应用在无人机、机器人和运动设备中的六轴姿态传感器,它集成了三轴陀螺仪和三轴加速度计。这款传感器能够实时监测并提供设备的角速度和线性加速度数据,对于理解物体的动态运动状态至关重要。在Arduino平台上,通过特定的库文件可以方便地与MPU6050进行通信,获取并解析传感器数据。 `MPU6050.cpp`和`MPU6050.h`是Arduino库的关键组成部分。`MPU6050.h`是头文件,包含了定义传感器接口和函数声明。它定义了类`MPU6050`,该类包含了初始化传感器、读取数据等方法。例如,`begin()`函数用于设置传感器的工作模式和I2C地址,`getAcceleration()`和`getGyroscope()`则分别用于获取加速度和角速度数据。 在Arduino项目中,首先需要包含`MPU6050.h`头文件,然后创建`MPU6050`对象,并调用`begin()`函数初始化传感器。之后,可以通过循环调用`getAcceleration()`和`getGyroscope()`来不断更新传感器读数。为了处理这些原始数据,通常还需要进行校准和滤波,以消除噪声和漂移。 I2C通信协议是MPU6050与Arduino交互的基础,它是一种低引脚数的串行通信协议,允许多个设备共享一对数据线。Arduino板上的Wire库提供了I2C通信的底层支持,使得用户无需深入了解通信细节,就能方便地与MPU6050交互。 MPU6050传感器的数据包括加速度(X、Y、Z轴)和角速度(同样为X、Y、Z轴)。加速度数据可以用来计算物体的静态位置和动态运动,而角速度数据则能反映物体转动的速度。结合这两个数据,可以进一步计算出物体的姿态(如角度和角速度变化)。 在嵌入式开发领域,特别是使用STM32微控制器时,也可以找到类似的库来驱动MPU6050。STM32通常具有更强大的处理能力和更多的GPIO口,可以实现更复杂的控制算法。然而,基本的传感器操作流程和数据处理原理与Arduino平台相似。 在实际应用中,除了基本的传感器读取,还可能涉及到温度补偿、低功耗模式设置、DMP(数字运动处理器)功能的利用等高级特性。DMP可以帮助处理传感器数据,实现更高级的运动估计,减轻主控制器的计算负担。 MPU6050是一个强大的六轴传感器,广泛应用于各种需要实时运动追踪的项目中。通过 Arduino 或 STM32 的库文件,开发者可以轻松地与传感器交互,获取并处理数据,实现各种创新应用。博客和其他开源资源是学习和解决问题的重要途径,通过这些资源,开发者可以获得关于MPU6050的详细信息和实践指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值