首页 > 数据库 >oracle PL/SQL基础介绍

oracle PL/SQL基础介绍

时间:2024-01-25 11:24:25浏览次数:33  
标签:sal -- 游标 emp SQL oracle PL

1.PL/SQL简介

PL/SQL语言(Procedural Language/SQL,过程化SQL语言)是Oracle推出的过程化的SQL编程语言,使用PL/SQL可以为SQL语言引入结构化的程序处理能力,例如可以在PL/SQL中定义常量、变量、游标、存储过程等,可以使用条件、循环等流程控制语句。

PL/SQL的这种特性使得开发人员可以在数据库中添加业务逻辑,并且由于业务逻辑与数据均位于数据库服务器端,比客户端编写的业务逻辑能提供更好的性能。

PL/SQL是一种块结构的语言,它将一组语句放在一个块中,一次性发送给服务器,PL/SQL引擎分析收到的PL/SQL语句块中的内容,把其中的过程控制语句由PL/SQL引擎自身去执行,把PL/SQL块中的SQL语句交给服务器的SQL语句执行器执行。

PL/SQL块发送给服务器后,先被编译然后执行,对于有名称的PL/SQL块(如存储过程、函数、触发器、程序包)可以单独编译,永久的存储在数据库中,随时准备执行。

两个注意点:

1.在 END; 结束符的下一行开头加“/”作为结束标志。

2.运行    SET SERVEROUTPUT ON;   语句。激活dbms_output包。 

2.PL/SQL程序结构:(仅展示代码部分)

PL/SQL程序结构_月应是绝色306的博客-CSDN博客icon-default.png?t=M85Bhttps://blog.csdn.net/qq_62687015/article/details/128119296?spm=1001.2014.3001.5501

  1. --变量的定义和初始化。
  2. SET SERVEROUTPUT ON;
  3. DECLARE --声明部分标识
  4. v_job VARCHAR2(9);
  5. v_count BINARY_INTEGER DEFAULT 0;
  6. v_total_sal NUMBER(9,2):=0;
  7. v_date DATE:=SYSDATE;
  8. c_tax_rate CONSTANT NUMBER(3,2):=8.25;
  9. v_valid BOOLEAN NOT NULL:=TRUE;
  10. BEGIN
  11. v_job:='MANAGER'; --在程序中赋值
  12. DBMS_OUTPUT.PUT_LINE(v_job); --输出变量v_job的值
  13. DBMS_OUTPUT.PUT_LINE(v_count); --输出变量v_count的值
  14. DBMS_OUTPUT.PUT_LINE(v_date); --输出变量v_date的值
  15. DBMS_OUTPUT.PUT_LINE(c_tax_rate); --输出变量c_tax_rate的值
  16. END;
  17. --使用SELECT INTO语句赋值变量
  18. SET SERVEROUTPUT ON;
  19. DECLARE --声明部分标识
  20. v_job VARCHAR2(9);
  21. v_count BINARY_INTEGER DEFAULT 0;
  22. v_total_sal NUMBER(9,2):=0;
  23. v_date DATE:=SYSDATE;
  24. c_tax_rate CONSTANT NUMBER(3,2):=8.25;
  25. v_valid BOOLEAN NOT NULL:=TRUE;
  26. BEGIN
  27. SELECT 'MANAGER' INTO v_job FROM dual;
  28. DBMS_OUTPUT.PUT_LINE(v_job); --输出变量v_job的值
  29. END;
  30. --根据职员表emp计算7788号职员的奖金。奖金的计算方法是:职员的工资(sal) *15%。
  31. DECLARE
  32. bonus_rate CONSTANT NUMBER(2,2) :=0.15;
  33. bonus NUMBER(7,2);
  34. emp_id NUMBER(4) := 7788;
  35. BEGIN
  36. SELECT sal * bonus_rate INTO bonus FROM emp
  37. WHERE empno= emp_id;
  38. DBMS_OUTPUT.PUT_LINE ( 'Employee: ' || TO_CHAR(emp_id)|| ' Bonus: ' || TO_CHAR(bonus) || ' Bonus Rate: ' || TO_CHAR(bonus_rate));
  39. END;
  40. --程序输出结果为:
  41. --Employee: 7788 Bonus: 450 Bonus Rate: .15
  1. --根据表中字段定义变量。
  2. DECLARE
  3. v_ename emp.ename%TYPE;--根据字段定义变量
  4. BEGIN
  5. SELECT ename INTO v_ename FROM emp
  6. WHERE empno=7788;
  7. DBMS_OUTPUT.PUT_LINE(v_ename); --输出变量的值
  8. END;

3. PL/SQL控制结构

oracle选择结构和循环结构_月应是绝色306的博客-CSDN博客icon-default.png?t=M85Bhttps://blog.csdn.net/qq_62687015/article/details/128120847?spm=1001.2014.3001.5501

  1. --判断emp表中记录是否超过20条,10-20之间,或者10条以下。
  2. DECLARE
  3. --声明变量接受emp表中的记录数
  4. V_COUNT NUMBER;
  5. BEGIN
  6. --查询emp表中的记录数赋值给变量
  7. SELECT COUNT(*) INTO V_COUNT FROM EMP;
  8. --判断打印
  9. IF V_COUNT > 20 THEN
  10. DBMS_OUTPUT.PUT_LINE('EMP表中的记录数超过了20条为:' || V_COUNT || '条。');
  11. ELSIF V_COUNT >= 10 THEN
  12. DBMS_OUTPUT.PUT_LINE('EMP表中的记录数在10~20条之间为:' || V_COUNT || '条。');
  13. ELSE
  14. DBMS_OUTPUT.PUT_LINE('EMP表中的记录数在10条以下为:' || V_COUNT || '条。');
  15. END IF;
  16. END;

 

 

 

4.游标 

游标:是系统开设的一个数据缓冲区,存放SQL语句的执行结果。  

作用:用户可通过游标获取记录,并赋给变量。

当对数据库的查询操作返回一组结果集时,存入游标,以后通过对游标的操作来获取结果集中的数据信息。

游标分:显式游标和隐式游标。当查询语句返回多条记录时,必须显式地定义游标以处理每一行。其他的SQL语句(更新操作或查询操作只返回一条记录)都使用隐式游标。

 

游标是用于临时存储一个查询返回的多行数据,通过遍历游标,可以逐行访问处理该结果集的数据。 

游标的使用方式:声明--->打开--->读取--->关闭

 

  1. 游标的定义:
  2. --CURSOR <游标名> IS <SQL语句>;
  3. --例:
  4. CURSOR c_emp IS SELECT * FROM emp WHERE dno=3;
  5. --当需要操作结果集时,须完成:打开游标、使用FETCH语句将游标里的数据取出以及关闭游标操作。
  6. --游标声明:
  7. CURSOR 游标名 IS 查询语句;
  8. --游标的打开:
  9. OPEN 游标名;
  10. --游标的取值:
  11. FETCH 游标名 INTO 变量列表;
  12. --游标的关闭:
  13. CLOSE 游标名;
  1. --使用游标查询emp表中所有员工的姓名和工资,并将其依次打印出来。:
  2. DECLARE
  3. CURSOR c_emp IS --声明游标
  4. SELECT ename, sal FROM emp; --声明变量用来接受游标中的元素
  5. v_ename emp.ename%TYPE;
  6. v_sal emp.sal%TYPE;
  7. BEGIN
  8. OPEN c_emp; --打开游标
  9. LOOP --遍历游标中的值
  10. FETCH c_emp into v_ename, v_sal ; --通过FETCH语句获取游标中的值并赋值 EXIT WHEN c_emp%NOTFOUND; --判断是否有值,有值打印,没有则退出循环
  11. DBMS_OUTPUT.PUT_LINE('姓名:' || v_ename || ',薪水:' || v_sal)
  12. END LOOP;
  13. CLOSE c_emp; --关闭游标
  14. END;
  15. --使用游标查询并打印某部门的员工的姓名和薪资,部门编号为运行时手动输入。
  16. DECLARE
  17. CURSOR c_emp(v_empno emp.empno%TYPE) IS
  18. SELECT ename, sal FROM emp WHERE empno = v_empno;
  19. v_ename emp.ename%TYPE;
  20. v_sal emp.sal%TYPE;
  21. BEGIN
  22. OPEN c_emp(10); --打开游标
  23. LOOP --遍历游标中的值
  24. FETCH c_emp INTO v_ename, v_sal ; --通过FETCH语句获取游标中的值并赋值
  25. EXIT WHEN c_emp%NOTFOUND; --判断是否有值,有值打印,没有则退出循环
  26. DBMS_OUTPUT.PUT_LINE('姓名:' || v_ename || ',薪水:' || v_sal)
  27. END LOOP;
  28. CLOSE c_emp; --关闭游标
  29. END;

带锁游标: PL/SQL提供了一种加锁后删除或更新游标中刚取出那条记录的方法。

要想操纵数据库中的数据,在定义游标的查询语句时,必须加上FOR UPDATE子句,表示要先对表加锁;然后在UPDATE或DELETE语句中加上WHERE CURRENT OF子句,指定从游标工作区中取出的当前行需要被更新或删除。当会话打开一个带FOR UPDATE子句的游标时,在游标区中的所有行拥有一个行级排他锁,其他对话只能查询,不能更新或删除。

实例:为emp表的员工增加10%的工资,总额限制在90万元以内。

5.存储过程与存储函数: 

PLSQL编程——存储过程_月应是绝色306的博客-CSDN博客icon-default.png?t=M85Bhttps://blog.csdn.net/qq_62687015/article/details/128124551?spm=1001.2014.3001.5501Oracle 函数_月应是绝色306的博客-CSDN博客icon-default.png?t=M85Bhttps://blog.csdn.net/qq_62687015/article/details/128154882?spm=1001.2014.3001.5501

  1. 查询并打印某个员工的姓名和薪水(有参)
  2. --创建存储过程
  3. CREATE OR REPLACE PROCEDURE P_QUERYNAMEANDSAL(i_empno IN emp.empno%TYPE) IS --声明变量接受查询结果
  4. v_ename emp.ename%TYPE;
  5. v_sal emp.sal%TYPE;
  6. BEGIN
  7. SELECT ename, sal INTO v_ename, v_sal from emp WHERE empno = i_empno; --根据用户传递的员工号查询姓名和薪水
  8. DBMS_OUTPUT.PUT_LINE('姓名:' || v_ename || ',薪水:' || v_sal); --打印结果
  9. END;
  10. --调用存储过程
  11. call P_QUERYNAMEANDSAL(7839)
  12. --输入员工号查询某个员工信息,将薪水作为返回值输出,给调用的程序使用(带有输出参数)
  13. --创建存储过程
  14. CREATE OR REPLACE PROCEDURE P_QUERYSAL_OUT(i_empno IN emp.empno%TYPE,o_sal OUT emp.sal%TYPE) IS
  15. BEGIN
  16. SELECT sal INTO o_sal FROM emp WHERE empno = i_empno;
  17. END;
  18. --调用存储过程
  19. DECLARE
  20. v_sal emp.sal%TYPE; --声明一个变量接受存储过程的输出参数
  21. BEGIN
  22. P_QUERYSAL_OUT(7839, v_sal); --注意参数的顺序
  23. DBMS_OUTPUT.PUT_LINE(v_sal);
  24. END;

 

6.触发器

  1. --在 emp表上创建一个触发器,该触发器是一个行级触发器。
  2. --当对 emp表的某职员sal工资列修改后,会引发该触发器并在审计表e_audit中写一条记录。
  3. --(1) 首先创建存放审计记录的表e_audit。
  4. CREATE TABLE e_audit
  5. (audit_id NUMBER(4),up_date DATE,new_sal NUMBER(7,2),
  6. old_sal NUMBER(7,2) );
  7. --(2) 再创建触发器audit_sal。
  8. CREATE OR REPLACE TRIGGER audit_sal
  9. AFTER UPDATE OF sal ON emp
  10. FOR EACH ROW
  11. BEGIN
  12. INSERT INTO e_audit VALUES( :OLD.empno, SYSDATE,:NEW.sal,:OLD.sal);
  13. -- 在行触发器中,被修改记录的每列都有两个相关名称,对应旧值和新值。:OLD.<属性名>和:NEW<属性名>
  14. END;

 

  1. --操作相关表,使得某部门职工的薪水增加15%。
  2. --给指定部门的员工加薪,首先要把该部门的员工选出来,再对这些员工的薪水进行改动。
  3. --这里用存储过程表示,将要加薪的部门作为参数:
  4. CREATE OR REPLACE PROCEDURE add_sal (deptname varchar2)
  5. AS
  6. BEGIN
  7. UPDATE emp
  8. SET emp.salary=emp.salary*1.15
  9. WHERE emp.eno IN
  10. (SELECT eno
  11. FROM dept
  12. WHERE dname= deptname);
  13. END ;
  14. --利用触发器建立追踪
  15. --通过对emp表的salary属性创建一个触发器,来监视其更新并进行记录,以追踪薪水变动情况:
  16. CREATE OR REPLACE TRIGGER salary_change  
  17. BEFORE DELETE OR INSERT OR UPDATE ON emp  --触发事件
  18. FOR EACH ROW      -- 每更新一行都需要调用此触发器
  19. DECLARE --只有触发器的声明需要DECLARE,过程和函数都不要
  20. salary1 NUMBER;
  21. BEGIN --:new与:old分别代表该行在修改前、改后的记录
  22. salary1=:new.salary - old.salary;
  23. DBMS_OUTPUT.PUT_LINE('old salary is:'|| :old.salary);
  24. DBMS_OUTPUT.PUT_LINE('new salary is:'|| :new.salary);
  25. DBMS_OUTPUT.PUT_LINE('add is:'||to_char(salary1));
  26. END ;

 

标签:sal,--,游标,emp,SQL,oracle,PL
From: https://www.cnblogs.com/lrzy/p/17986756

相关文章

  • 【sqlsever】具体案例理解PARTITION BY
    当使用PARTITIONBY时,它通常是与窗口函数一同使用的。下面将提供一个简单的例子,使用一个包含以下列的表:+---------+---------+---------+|column1|column2|column3|+---------+---------+---------+|A|1|10||A|2|20|......
  • RuoYi-Cloud-Plus
    一、官网dromara/RuoYi-Cloud-Plus二、Mac本地接入1、创建网段在Mac上:替换所有网络模式为自己定义的网段(或注释网断设置) network_mode:"mynet":::info网段设定可参考Docker网络模式--network_mode:::2、启动基础容器修改minio映射路径-v/home/minio/data:/data......
  • MyBatis手写SQL批量操作
    一、查询List<ArticleAccumulatedIncomeDTO>batchAccumulatedIncome(List<Long>ids);<selectid="batchAccumulatedIncome"resultMap="ArticleSumIncome">selectarticle_id,sum(income)asaccumulated_incomefromwalle......
  • Completions接入
    一、文档https://platform.openai.com/docs/api-reference/completions二、调用curlhttps://api.openai.com/v1/completions\-H"Content-Type:application/json"\-H"Authorization:Bearer$OPENAI_API_KEY"\-d'{"model&q......
  • MSSQL中添加链接数据库
     ----添加mssqlwinddb--以下添加链接数据库脚本:WINDDB210是别名,SQLOLEDB是指链接SQLSERVER数据库,xxx.xxx.xxx.xxx是远程数据库地址,execmaster.dbo.sp_addlinkedserver'WINDDB210','','SQLOLEDB','xxx.xxx.xxx.xxx'--以下对添加链接数据库的登录用户:WINDDB210是别名,us......
  • MySQL如何快速禁用账户登入 & 如何复制/复用账户密码【转】
    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。作者:叶金荣文章来源:GreatSQL社区原创如何快速临时禁止某账户登入角色ROLES管理需要先激活关于授权的其他几点补充如何复制/复用账户密码1.快......
  • Spring的JdbcTemplate使用教程
    什么是JdbcTemplate?Spring框架对JDBC进行封装,使用JdbcTemplate方便实现对数据库操作。准备工作引入jdbcTemplate的相关依赖:案例实操创建jdbc.properties文件,配置数据库信息jdbc.driver=com.mysql.cj.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/dbtest1?serv......
  • Supplier 惰性调用和 Future#get 同步等待调用结合
    ......
  • SQL入门
    SQL入门基础结构primarykey(主键)橙色foreignkey(外键)绿色创建资料库CREATEDATABASE`sql_tutorial`;--创建资料库SHOWDATABASES;--查看资料库DROPDATABASE`sql_tutorial`;--删除资料库创建表格--数据类型INT--整数DECIMAL(3,2)--有小数......
  • Mysql报:ERROR 145 (HY000) at line 1: Table './mysq1/proc' is marked as crashed an
    版权声明:原创作品,谢绝转载!否则将追究法律责任。—————作者:kirin先看报错mysq1:[Marning]Usingapasswordonthecommandlineinterfacecanbeinsecure.ERROR145(HY000)atline1:Table'./mysq1/proc'ismarkedascrashedandshouldberepaired1、截图如......