返回顶部
首页 > 资讯 > 操作系统 >【PLSQL】PLSQL基础
  • 191
分享到

【PLSQL】PLSQL基础

学习笔记oracle 2023-08-30 10:08:28 191人浏览 安东尼
摘要

文章目录 一:记录类型1.语法2.代码实例 二:字符转换三:%TYPE和%ROWTYPE1.%TYPE2.%ROWTYPE 四:循环1.LOOP2.WHILE(推荐)3.数字式循环 五:游标1.游标定义及读取2.游标属性

一:记录类型

1.语法

TYPE record_type IS RECORD(column1 type,colunm2 type,… …Variable_name record_type;

2.代码实例

declare  type test_rec is record(    --test_rec记录类型       l_name varchar2(30),       d_id number(4));  v_emp test_rec;   --v_emp变量名begin   v_emp.l_name := '张三';  v_emp.d_id := 1234;  dbms_output.put_line(v_emp.l_name || ',' || v_emp.d_id);end;

可以使用SELECT语句对记录变量进行赋值,只要保证记录字段与查询结果列表中的字段相匹配即可.

create table cux.employee(last_name varchar2(20),department_id number(4));insert into cux.employee values('李四',1235,234);declare  type test_rec is record(    --test_rec记录类型       l_name varchar2(30),       d_id number(4));  v_emp test_rec;   --v_emp变量名begin   select last_name, department_id into v_emp  from cux.employee  where employee_id = 234;    dbms_output.put_line(v_emp.l_name || ', ' || v_emp.d_id);end;

二:字符转换

在这里插入图片描述

三:%TYPE和%ROWTYPE

1.%TYPE

定义一个变量,其数据类型与已经定义的某个数据变量的类型相同,或者与数据库表的某个列的数据类型相同,这时可以使用%TYPE

使用%TYPE的优点:

  • 所引用的数据库列的数据类型不必知道;
  • 所引用的数据库列的数据类型可以实时改变.
declare  type test_rec is record(       l_name cux.employee.last_name%type,       d_id cux.employee.department_id%type);  v_emp test_rec;begin  select last_name,  department_id into v_emp  from cux.employee where employee_id = 234;  dbms_output.put_line(v_emp.l_name || ', ' || v_emp.d_id);end;

2.%ROWTYPE

在这里插入图片描述

四:循环

1.LOOP

LOOP要执行的语句;EXIT WHEN<条件语句>;  --条件满足,退出END LOOPdeclare  int NUMBER(2) := 0;begin  LOOP    int := int + 1;    dbms_output.put_line('int的当前值为:' || int);    EXIT WHEN int = 10;  END LOOP;END;

2.WHILE(推荐)

WHILE<布尔表达式> LOOP要执行的语句;END LOOP;DECLARE  x NUMBER(2) := 0;BEGIN  WHILE x < 10 LOOP    x := x + 1;    dbms_output.put_line('x的当前值为:' || x);  END LOOP;END;

3.数字式循环

FOR 循环计数器 IN[REVERSE] 下限 .. 上限 LOOP要执行的语句END LOOP;

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

begin  FOR i in reverse 2 .. 10 LOOP    DBMS_OUTPUT.PUT_LINE('i的值为' || i);  END LOOP;end;

五:游标

1.游标定义及读取

--游标FOR读取declare   cursor c_emp(dep_id number default 1236) is          select last_name,employee_id epid         from cux.employee         where department_id = dep_id;begin  for v_emp in c_emp loop    DBMS_OUTPUT.PUT_LINE(v_emp.last_name || ', ' || v_emp.epid);  end loop;end;

2.游标属性

  • %FOUND:布尔类型属性,当最近一次读记录时成功返回,则值为TRUE;
  • %NOTFOUND:布尔类型属性,与%FOUND相反;
  • %ISOPEN:布尔型属性,当游标已打开时返回TRUE;
  • %ROWCOUNT:数字型属性,返回已从游标中读取的记录数。

3.NO_DATA_FOUND和%NOTFOUND的区别

SELECT … INTO 语句触发NO_DATA_FOUND;

当一个显示游标的WHERE子句未找到时触发%NOTFOUND;当UPATE或DELETE语句的WHERE子句未找到时触发sql%NOTFOUND;在提取循环中要用%NOTFOUND或%FOUND来确定循环退出条件,不要用NO_DATA_FOUND。

六:异常错误

在这里插入图片描述

1.异常处理

EXCEPTioN WHEN first_exception THEN WHEN second_exception THEN WHEN OTHERS THEN END;

异常处理可以按照任意次序排列,但OTHERS必须放在最后。

declare   -- Local variables here  v_empid cux.employee.employee_id%type := &v_empid;  v_sal cux.employee.salary%type;begin  -- Test statements here  select salary into v_sal  from cux.employee  where employee_id = v_empid  for update;  if v_sal <= 3000 then     update cux.employee set salary = salary+1000    where employee_id = v_empid;    DBMS_OUTPUT.PUT_LINE('编号为:'|| v_empid || '工资已更新');  else     DBMS_OUTPUT.PUT_LINE('编号为:'|| v_empid || '工资不需更新');  end if;exception  WHEN NO_DATA_FOUND THEN    DBMS_OUTPUT.PUT_LINE('编号为:'|| v_empid || '员工不存在');  WHEN TOO_MANY_ROWS THEN    DBMS_OUTPUT.PUT_LINE('数据行数太多,请使用游标');  WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('其他错误');end;

2.非预定义异常处理

  1. 在PL/SQL块定义部分定义异常情况 <异常情况> EXCEPTION

  2. 将其定义好的异常情况,与标准的oracle错误联系起来,使用PRAGMA EXCEPTION_INIT语句;

    PRAGMA EXCEPTION(<异常情况>,<错误代码>);

  3. 在PL/SQL异常情况处理部分对异常情况做出相应处理。

3.用户自定义的异常处理

用户定义的异常错误是通过显式使用RaiSE语句来触发。当引发一个异常错误时,控制就转向到EXCEPTION块异常错误部分,执行错误处理代码。

步骤:

  1. 在PL/SQL块的定义部分定义异常情况;

  2. <异常情况> EXCEPTION

    RAISE<异常情况>;

在PL/SQL块的异常情况处理部分对异常情况做出相应处理。

七:存储过程或函数

把PL/SQL程序存储在数据库中,并可以在任何地方来运行它。过程和函数的唯一区别是函数总向调用者返回数据,而过程则不返回数据。

1.函数

IN参数标记表示传递给函数的值在该函数执行中不改变;OUT标记表示一个值在函数中进行计算并通过该参数传递给调用语句;IN OUT标记表示传递给函数的值可以变化并传递给调用语句。若省略标记,则参数隐含为IN。因为函数需要一个返回值,所以RETURN包含返回结果的数据类型。

create or replace function get_salary(       dep_id cux.employee.department_id%type (default 1235),       emp_count out number)       return number       is       v_sum number;begin  select sum(salary), count(*) into v_sum, emp_count  from cux.employee  where department_id = dep_id;    return v_sum;exception  when no_data_found then     DBMS_OUTPUT.PUT_LINE('查询的数据不存在');  when others then     DBMS_OUTPUT.PUT_LINE(sqlcode || '--' || sqlerrm);    end;

函数调用过程:

位置表示法;

declare  v_num number;  v_sum number;begin  v_sum := get_salary(1237,  v_num);    DBMS_OUTPUT.PUT_LINE('1237号部门的工资总和:' || v_sum || ' 人数:' || v_num);end;

名称表示法

形式参数必须和函数定义时声明的形式参数名称相同,顺序可以任意排列。

 v_sum := get_salary(dep_id => 1237, emp_count => v_num);

混合表示法

使用位置表示法所传递的参数必须放在名称表示法所传递的参数前面。也就是说,无论函数具有多少个参数,只要其中有一个参数使用名称表示法,其后所有的参数都必须使用名称表示法。

 v_sum := get_salary(1237, emp_count => v_num);

八:包

1.包的创建

create or replace package demo_pack is  -- Author  : 11313321  -- Created : 2023/8/22 8:45:06  -- Purpose : 练习测试    -- Public type declarations  EmpRec cux.employee%ROWTYPE;  -- Public function and procedure declarations  function add_emp(    last_name VARCHAR2, dept_id number, emp_id NUMBER, salary number)    return number;  function remove_emp(emp_id number)    return number;  procedure query_empl(emp_id number);end demo_pack;

包主体的创建方法,它实现上面所声明的包定义:

create or replace package body demo_pack is  function add_emp(last_name VARCHAR2, dept_id number, emp_id NUMBER, salary number)    return number    is    empno_remaining exception;    pragma exception_init(empno_remaining, -1);  begin    insert into cux.employee values(last_name, dept_id, emp_id, salary,TO_DATE('2023,5,20','yyyy-mm-dd'));    if sql%found then       return 1;    end if;  exception    when empno_remaining then        return 0;    when others then        return -1;  end add_emp;  function remove_emp(emp_id number)    return number    is  begin    delete from cux.employee where employee_id = emp_id;    if sql%found then       return 1;    else      return 0;    end if;  exception    when others then      return -1;  end remove_emp;    procedure query_empl(emp_id number)    is  begin    select * into EmpRec from cux.employee where employee_id = emp_id;  exception    when no_data_found then      DBMS_OUTPUT.PUT_LINE('数据库中没有该员工');    when too_many_rows then      DBMS_OUTPUT.PUT_LINE('程序运行错误!请使用游标');    when others then      DBMS_OUTPUT.PUT_LINE(sqlcode || '--' || sqlerrm);  end query_empl;  begin  -- Initialization  null;end demo_pack;

2.包的调用

对包内共有元素的调用格式为:报名.元素名称

declare  var number;begin  var := demo_pack.add_emp('老马', 1476, 789, 3800);  if var=-1 then    DBMS_OUTPUT.PUT_LINE(sqlcode || '--' || sqlerrm);  elsif var=0 then    DBMS_OUTPUT.PUT_LINE('该记录已存在');  else     DBMS_OUTPUT.PUT_LINE('添加记录成功');    demo_pack.query_empl(789);    DBMS_OUTPUT.PUT_LINE(demo_pack.EmpRec.employee_id||'--'||       demo_pack.EmpRec.last_name||'--'||demo_pack.EmpRec.department_id);    var := demo_pack.remove_emp(788);    if var=-1 then      DBMS_OUTPUT.PUT_LINE(sqlcode || '--' || sqlerrm);    elsif var=0 then      DBMS_OUTPUT.PUT_LINE('该记录不存在');    else      DBMS_OUTPUT.PUT_LINE('删除记录成功');    end if;  end if;end;

九:触发器

1.触发器的组成

  • 触发事件:在何种情况下触发TRIGGER,例如:INSERT,UPDATE,DELETE
  • 触发时间:触发之前(BEFORE)、之后(AFTER)
  • 触发器本身:触发之后的目的和意图
  • 触发频率:语句级(STATEMENT)触发器和行级(ROW)触发器。
    • 语句级:当触发某事件时,该触发器只执行一次
    • 行级:当某事件发生时,对受到该操作影响的每一行数据,触发器都单独执行一次。
    • 行触发器和语句触发器的区别表现在:行触发器要求当一 个 DML 语句操做影响数据库中的多行数据时,对于其中的每个数据行,只要它们符合触发约束条件,均激 活一次触发器;而语句触发器将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。

2.语法

CREATE [OR REPLACE] TRIGGER trigger_name{BEFORE | AFTER}{INSERT|DELETE|UPDATE[OF column[,column...]]}ON [schema.] table_name[FOR EACH ROW][WHEN condition]trigger body;

FOR EACH ROW选项说明触发器为多行触发器。当省略FOR EACH ROW选项时,BEFORE和AFTER触发器为语句触发器,而INSTEAD OF触发器则为行触发器。

3.触发器的限制

  • 触发器体内的SELECT语句只能为SELECT…INTO…结构,或者为定义游标所使用的SELECT语句。
  • 触发器中不能使用数据库事务控制语句COMMIT;ROLLBACK;SAVEPOINT语句。
  • 由触发器所调用的过程或函数也不能使用数据库事务控制语句。

当触发器被触发时,要使用被插入、更新或删除的记录中的列值,有时要使用操作前、后列的值

  • :NEW 修饰符访问操作完成后列的值
  • :OLD 修饰符访问操作完成前列的值

4.实例

--创建表create table cux.emp_his asselect * from cux.employeewhere 1 = 2;--创建触发器create or replace trigger del_emp_trigger       before delete on cux.employee for each rowbegin  insert into cux.emp_his(last_name, department_id, employee_id, salary)  values(:old.last_name, :old.department_id, :old.employee_id, :old.salary);end;

5.创建替代(INSTEAD OF)触发器

CREATE [OR REPLACE] TRIGGER trigger_nameINSTEAD OF{INSERT | DELETE | UPDATE [OF column [, column …]]}ON [schema.] view_name[FOR EACH ROW ][WHEN condition]trigger_body;

INSTEAD OF用于对视图的DML触发。

来源地址:https://blog.csdn.net/weixin_45750572/article/details/132499397

--结束END--

本文标题: 【PLSQL】PLSQL基础

本文链接: https://lsjlt.com/news/382598.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 【PLSQL】PLSQL基础
    文章目录 一:记录类型1.语法2.代码实例 二:字符转换三:%TYPE和%ROWTYPE1.%TYPE2.%ROWTYPE 四:循环1.LOOP2.WHILE(推荐)3.数字式循环 五:游标1.游标定义及读取2.游标属性...
    99+
    2023-08-30
    学习 笔记 oracle
  • PLSQL基本语法的使用
    这篇文章主要介绍“PLSQL基本语法的使用”,在日常操作中,相信很多人在PLSQL基本语法的使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PLSQL基本语法的使用”的疑惑...
    99+
    2024-04-02
  • plsqL复习
    下单超过4次的女顾客的查询语句:SELECT c.customer_id, COUNT(o.order_id) AS orders_ct  FROM customers c  J...
    99+
    2024-04-02
  • PLSQL集合
    PLSQL集合索引表(或者叫做关联数组,associative array )嵌套表(nested table)变长数组(varray)二维数组(多层集合)索引表---创建索引表类型的语法如下所示:&nbs...
    99+
    2024-04-02
  • PLSQL乱码
    1...
    99+
    2024-04-02
  • PLSQL下ORA-00904:
    plsql下查看执行计划报错:ORA-00904:"OTHER_XML":标识符无效 解决办法:1.报错的用户登录到sqlplus,执行以下命令: sql> drop table...
    99+
    2024-04-02
  • 使用plsql编程
    第七章  使用PL/SQL编程 初识PL/SQL(Procedure Language & Structured Query Language) PL/SQL是Oracle在标准SQL语言上的过程性扩展,允许嵌入SQL语句,定义变...
    99+
    2021-11-12
    使用plsql编程
  • plsql字段约束
    第五章  字段约束   初识约束   约束是数据库用来确保数据满足业务规则的手段,对数据做的条件限制。   约束的类型 1. 主键约束(PRIMARY KEY) 2. 唯一性约束(UNIQUE) 3. 非空约束(NOT NULL)...
    99+
    2019-09-05
    plsql字段约束
  • plsql项目案例
    第六章  项目案例1   需求:        1. 建立一个银行账户的表bank_account,具备以下字段和约束            2. 完成该表基本CRUD        3. 模拟转账流程        4. 模拟异...
    99+
    2022-02-18
    plsql项目案例
  • plsql储存过程
    第九章  存储过程   初识存储过程   存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后调用不需要再次编译,用户通过指定存储过程的名字并给出...
    99+
    2015-05-06
    plsql储存过程
  • plsql 调用方法
    CREATE OR REPLACE FUNCTION c_to_f (degree NUMBER) RETURN NUMBER IS buffer NUMBER; BEGIN buffer := (degree * 9/...
    99+
    2022-04-15
    plsql 调用方法
  • PLSQL错误总结
    "" is null为true,""和null是同一个东西。 神经病写法:无论vc_itemids是null还是"",or后面的那一句都为false,判空只能使用is null 或者 is not null。下面的vc_itemi...
    99+
    2016-06-19
    PLSQL错误总结
  • Oracle系列:(28)PLSQL
    准备篇col empno for 9999;col ename for a10;col job for a10;col mgr for 9999;col hiredate for a12;col sal f...
    99+
    2024-04-02
  • plsql中文乱码
    首先,通过 select userenv('language') from dual;SIMPLIFIED CHINESE_CHINA.WE8MSWIN1252查询oracle服务器端的...
    99+
    2024-04-02
  • 如何安装PLSQL
    如何安装PLSQL?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、准备工作1、安装的PLSQL版本为12.0.7,建议安装64位。2、下载P...
    99+
    2024-04-02
  • mysql有没有plsql
    本篇内容主要讲解“mysql有没有plsql”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mysql有没有plsql”吧! mysq...
    99+
    2023-04-14
    mysql plsql
  • PLSQL Developer安装详细步骤及 plsql Developer 14注册码
    目录一、PL/SQL官网下载二、PL/SQL工具安装三、pl/sqlzhongwen四、验证是否成功补充:PL/SQLplsqlDeveloper14最新版注册码(亲测可用)激活成功...
    99+
    2024-04-02
  • Oracle/PLSQL的EXISTS使用
    下面的testa表没有数据,dept表有数据。直接select,有数据就会有结果集。        plsql的exists用于判断子查询是否有结果集返回,“exists (子查询)”子查询只要结果集有数据,则exis...
    99+
    2018-02-04
    Oracle/PLSQL的EXISTS使用
  • win7下安装PLSQL Developer
    昨晚电脑中毒,系统重做,所有的东西都要重装,现在要装PLSQL Developer ,忘记之前是怎么装了,参考了网上的资料,重新安装也简单的做个记录;一、安装ORACLE软件11.2.3database,C...
    99+
    2024-04-02
  • plsql中else的用法
    pl/sql 中 else 子句在 if-then-else 语句中指定条件为假时的替代执行路径,语法为:if condition then 代码块 1 else 代码块 2 end i...
    99+
    2024-05-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作