Oracle基础学习笔记(二)-基于马士兵Oracle视频

2024-06-08 18:08

本文主要是介绍Oracle基础学习笔记(二)-基于马士兵Oracle视频,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

041. PL_SQL PL/SQL PLSQL

--PL/SQL块包含三部分:声明部分(可选)、执行部分(必选)、异常处理部分(可选)。

--set serveroutput on; --打开控制台输出

--PL/SQL中的select语句,必须和 into 关键字一起使用,而且必须且只能返回一个值;

--PL/SQL中,sql%rowcount 表示执行的sql语句影响了多少行数据,select语句始终为1;insert、update、delete语句为实际影响的行数;

格式如下:

declare --声明变量

  ...

begin --PL/SQL开始

  ...

exception --捕获异常

  when others then

  ...

end--PL/SQL结束

--例子

declare

  v_num number := 0;

  v_name varchar2(10);

begin

  v_name := 'zhangsan';

  v_num := 2/v_num;

  dbms_output.put_line(v_name);

  dbms_output.put_line(v_num);

exception

  when others then

  dbms_output.put_line('error');

end;

--变量声明的规则:

1.变量名称不能使用保留字;

2.第一个字符必须是字母;

3.变量名最多包含30个字符;

4.不要与数据库的表或者列同名;

5.每一行只能声明一个变量;

6.开发过程中,推荐的变量命名规则如下:

  定义变量时,使用 v_ 作为前缀,如 v_name,v_job;

  定义常量时,使用 c_ 作为前缀,如 c_rate;

  定义游标时,使用 _cursor 作为后缀,如 emp_cursor;

  定义例外时,使用 e_ 作为前缀,如 e_integer_error;

  

--大小写规则:为了提高程序的可读性和性能,Oracle建议的大小写编码如下:

--SQL 关键字采用大写,如 SELECT UPDATE FROM WHERE AND;

--PL/SQL 关键字采用大写,如 DECLARE BEGIN END;

--数据类型采用大写,如 INT VARCHAR2 DATE;

--标示符 和参数 采用小写,如 v_name;

--数据库对象和字段采用小写,如 emp,sal;

--常用变量类型

1binary_integer: 整数,主要用来计数而不是用来表示字段类型;

2number: 数字类型;

3char: 定长字符长类型;

4varchar2: 变长字符串;

5date:日期;

6long: 长字符串,最长2GB;

7boolean :布尔类型,可以取值为true,false和null值;(boolean类型变量声明时,需要赋初值,不然默认为null)

--变量声明,使用%type属性

declare

  v_empno number(4);

  v_empno2 emp.empno%type;

  v_empno3 v_empno2%type;

begin

  dbms_output.put_line('test');

end;

--table变量类型(数组)

declare

  type type_table_emp_empno is table of emp.empno%type index by binary_integer;

  v_empnos type_table_emp_empno;

begin

  v_empnos(0) := 7369;

  v_empnos(2) := 7839;

  v_empnos(-1) := 9999;

  dbms_output.put_line(v_empnos(-1));

end;

--record变量类型(近似java中的类)

declare

  type type_record_dept is record (

    deptno dept.deptno%type,

    dname dept.dname%type,

    loc dept.loc%type

  );

  v_temp type_record_dept;

begin

  v_temp.deptno := 50;

  v_temp.dname := 'zhangsan';

  v_temp.loc := 'beijing';

  dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname);

end;

--使用%rowtype声明record变量

declare

  v_temp dept%rowtype;

begin

    v_temp.deptno := 50;

    v_temp.dname := 'zhangsan';

    v_temp.loc := 'beijing';

   dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname);

end;

--PL_SQL语句中执行select语句,必须有返回结果,且只有一条返回结果!

--如果select语句中没有游标,就必须加上into关键字;

如:

declare

  v_ename emp.ename%type;

  v_sal emp.sal%type;

begin

  select ename, sal into v_ename, v_sal   -- 将 ename 和 sal 值放到变量 v_ename 和 v_sal 中

    from emp 

   where empno = 7369;

  dbms_output.put_line(v_ename || ' ' || v_sal);

end;

declare

  v_emp emp%rowtype;

begin

  select * into v_emp from emp where empno = 7369;

  dbms_output.put_line(v_emp.ename);

end;

--PL_SQL中执行DDL语句,必须在前面加 execute immediate '...',而且要将sql语句放在单引号内部;

如:

begin

  execute immediate 'create table T (name varchar2(20))';

end;

PL_SQL 中的条件分支语句:if...elsif...else...end if-- 注意是 elsif 而不是 elseif

declare

  v_sal emp.sal%type;

begin

  select sal into v_sal from emp where empno = 7369;

  if(v_sal<2500then

    update emp set(sal = v_sal*2where empno = 7369;

    elsif(v_sal>2500then

    update emp set(sal = v_sal/2where empno = 7369;

  else -- else后面没有then

    dbms_output.put_line(v_sal);

    end if;   --end if 后面必须要有;号

end;

PL_SQL中执行循环语句:

declare

   i binary_integer := 1;

begin

  loop

    dbms_output.put_line(i);

    i := i + 1;

    exit when (i >= 11);

  end loop;

end;

-- 相当于java中的do...while循环

declare

  j binary_integer := 1;

begin

  while j < 11 loop

    j := j + 1;

  end loop;

end;

-- 相当于java中while循环

begin

  for k in 1..10 loop

    dbms_output.put_line(k);

  end loop;

end;

-- 顺序执行从一到十, 相当于java中的for循环

begin 

  for k in reverse 1..10 loop

    dbms_output.put_line(k);

  end loop;

end;

-- 逆序执行从十到一, 相当于java中的for循环

--错误处理:

declare

  v_temp number(4);

begin

  select empno into v_temp from emp where deptno = 10;

exception

  when no_data_found then -- no_data_found是Oracle提供的一种异常类型,相当于java中具体的异常类

    dbms_output.put_line('没有数据');

  when too_many_rows then -- too_many_rows是Oracle提供的一种异常类型,相当于java中具体的异常类

    dbms_output.put_line('太多记录了');

  when others then

    dbms_output.put_line('error');

end;

其实我们可以把数据库中执行操作时产生的异常的相关信息放在一张表中,以便以后查询,具体步骤如下:

1->创建一张表存放错误的表:

create table errorlog(

  id number primary key,

  errorcode number,

  errormsg varchar2(1024);

  errdate date

);

2->创建一个序列以用来给errorlog表的id赋值:

create sequence seq_errorlog_id start with 1 increment 1;

3->写一个PL_SQL语句来记录发生的错误信息:

declare

  v_deptno dept.deptno%type := 10;

  v_errcode number;

  v_errmsg varchar2(1024);

begin

  delete from dept where deptno = v_deptno;

  commit;

exception

  when others then

  rollback;

  v_errcode := SQLCODE;        --SQLCODE是系统中出现异常后的异常代码是一个数字类型,它是一个关键字

  v_errmsg := SQLERRM;         --SQLERRM是系统中出现异常后的异常信息是一个字符串类型,它是一个关键字

  insert into errorlog values (seq_errorlog_id.nextval, v_errcoe, v_errmsg, to_char(sysdate,'YYYY-MM-DD HH24-MI-SS'));

  commit;

end;

042SQLCODE SQLERRM

Oracle内置函数SQLCODE和SQLERRM, 用在OTHERS处理器中,分别用来返回Oracle的错误代码和错误消息.

SQLCODE返回Oracle错误的序号,而SQLERRM返回的是相应的错误消息,错误消息首先显示的是错误代码。

一个错误消息最多只能包含512个字节的错误代码。

如果没有异常被触发,则SQLCODE返回0,SQLERRM返回“ORA-0000normal, successful completion”。

043. 游标 cursor

和java中的迭代器Itaroter的意思相似、它起初指向一个子查询所查出的结果集的第一条记录上

它有四个属性:

1found 能找到记录返回true,没找到返回false;

2notfound 没找到记录返回true,找到了返回false;

3isopen 代表游标是否打开;

4rowcount 指的是当前已经 fetch 到了多少条记录

格式如下:

declare

  cursor c is select * from emp; -- 将一个游标指向子查询所查出结果集的第一个记录上

  v_emp c%rowtype;  -- 意思是声明一个变量,它的类型和游标c所指向的子查询

begin

  open c; -- 将游标打开

  fetch c into v_emp; -- 将游标c所指向的记录取出来存储到变量v_emp中

  dbms_output.put_line(v_emp.name);

    close c; -- 关闭游标c

end;

利用游标(cursor)来执行循环:

-- do..while类型的循环:

declare

  cursor c is select * from emp;

  v_emp c%rowtype;

begin

  open c;

  loop

    fetch c into v_emp;

    dbms_output.put_line(v_emp.ename);

    exit when (c%notfound);

  end loop;                             

  close c;

end;

-- while类型的循环:

declare

  cursor c is select * from emp;

  v_emp c%rowtype;

begin

  open c;

  fetch c into v_emp;

  while (c%foundloop

    dbms_output.put_line(v_emp.ename);

    fetch c into v_emp;

  end loop;

  close c;

end;

-- for循环类型的循环,

-- 这种循环不需要我们去open 游标,不需要我们手动的去close游标,

-- 也不需要我们主动的去fetch,也不需要我们主动的去创建一个变量v_emp

-- for循环自动帮我们创建以上这些东西。

declare

  cursor c is select * from emp;

begin

  for v_emp in c loop

    dbms_output.put_line(v_emp.ename);

  end loop;

end;

-- 带参数的游标(非重点)

declare

  cursor c(v_deptno emp.deptno%type,v_job emp.job%type)

  is select ename, sal from emp where deptno = v_deptno and job = v_job;

begin

  for v_temp in c(30'clerk'loop

    dbms_output.put_line(v_emp.ename);

  end loop;

end;

-- 可更新的游标:

declare

  cursor c is select * from emp for update-- 可更新的游标,只要在子查询后加上 for update 就行

begin

  for v_temp in c loop

    if(v_temp.sal<2000then

      update emp set sal = sal*2 where current of c; -- current of c 指的是当前游标所指的这条记录、

    elsif(v_temp.sal = 5000then  -- PL_SQL中比较两个值的大小使用“=”而不是双等号,另外PL_SQL中的赋值号是:=而不是=;

      delete from emp where current of c;

    end if ;

  end loop;

   commit;

end;

044procedure 存储过程

--存储过程其实是一个带有名称的PL/SQL语句块;

格式如下:

create or replace procedure p (String a,Date b)

is   --存储过程就是比PL/SQL多了这以上两行语句,底下的都跟PL_SQL一样

cursor c is select * from emp for update;

begin

  for v_emp in c loop

    if(v_emp.deptno = 10 ) then

      update emp set sal = sal + 10 where current of c;

    elsif(v_emp.deptno =20then

      update emp set sal = sal + 20 where current of c;

    else 

      update emp set sal = sal + 50 where current of c;

    end if;

  end loop;

  commit;

end;

存储过程的执行有两种方式:

1exec p;-- 其中p为存储过程名称

2begin

    p;

   end;     

-- 带参数的存储过程:

create or replace precedure p (

  v_a in number,

  v_b in number,

  v_ret out number,

  v_temp in out number )

is

begin

  if (v_a > v_b) then

    v_ret := v_a;

  else

    v_ret := v_b;

  end if;

  v_temp := v_temp + 1;

end;

-- 参数类型中的in是指传入参数,out是指传出参数;

-- 因为存储过程没有返回值,故用传出参数来获取结果,它在存储过程内部赋值;

-- in和out共同修饰的参数叫传入传出参数,它既可被赋值也可使用它的值;

如何调用这个存储过程?:

declare

  v_a number := 3;

  v_b number := 4;

  v_ret number;     --v_ret不赋值,是因为它是传出参数,是用来存储值的,

  v_temp number := 5;   --既可以赋值,也可不赋值

begin

  p(v_a,v_b,v_ret,v_temp);

  dbms_output.put_line(v_ret);

    dbms_output.put_line(v_temp);

end;

--编写存储过程出现错误代码,编译时只提示编译性错误,不会指出错误的详细信息,可使用命令show erro;来显示出错误的位置。

045function 函数 

--函数和存储过程一样,只是函数有返回值,而存储过程没有返回值;

--和Oracle内置函数用法相同;

create or replace function sal_tax(v_sal number)

return number;  -- 声明函数有返回值,且返回值类型是number

is

begin

  if(v_sal < 2000then

    return 0.10;

  elsif(v_sal < 2750then

    return 0.15;

  else

    return 0.20;

  end if;

end;

046trigger 触发器

--触发器是指执行某种操作之前或之后自动触发执行某种动作的sql语句;

--定义触发器时,必须要指定触发事件和触发操作;

--常用的触发事件包括INSERT、UPDATE、DELETE语句,触发操作实际是一个PL/SQL块;

--触发器不能单独执行,必须依附在表中;

--比如银行的存取款,在用户存取款后必须要把这些操作信息记录下来,以便查询.

demo:

create table emp_log(

   uname varchar2(20),

   action varchar2(10),

   atime date

);

create or replace trigger trig after insert or update or delete on emp for each row 

-- 关键字有两个before和after分别表示在执行某种操作之前或之后

-- for each row 表示所作的操作在数据库表中、每更新一行,触发一次触发器

begin

  if inserting then

    insert into emp_log values (USER'insert'sysdate);

  elsif updating then

    insert into emp_log values (USER'update'sysdate);

  elsif deleting then

    insert into emp_log values (USER'delete'sysdate);

  end if;

end;

--不提倡使用

create or replace trigger trig after update on dept for each row

begin

  update emp2 set deptno = :NEW.deptno where deptno = :OLD.deptno;

end;

047. 包 包体 Package Package Body

--Oracle的包用于逻辑组合相关的过程和函数,由包声明和包体两部分组成;

--包声明用于定义公用的常量、变量、过程和函数;包声明只有函数和存储过程的声明,没有具体实现;

--包体用于实现包规范中声明的函数和存储过程;

CREATE PACKAGE emp_pkg IS

  FUNCTION annual_income(name varchar2RETURN NUMBER;

  PROCEDURE update_sal(name varchar2,new_sal NUMBER);

END;

CREATE PACKAGE BODY emp_pkg IS

  FUNCTION annual_income(name varchar2RETURN NUMBER

  IS 

  annual_sal NUMBER(7,2);

  BEGIN

    SELECT sal*12 INTO annual_sal

      FROM emp

     WHERE enmae = name;

     RETURN annual_sal;

  END;

  

  PROCEDURE update_sal(name varchar2, new_sal NUMBER)

  IS 

  BEGIN

    UPDATE emp SET sal = new_sal

     WHERE enmae = name;

  END;

END;

----------------------

--树状结构的存储与展现

drop table article;

create table article

(

id number primary key,

cont varchar2(4000),

pid number,

isleaf number(1), --0代表非叶子节点,1代表叶子节点

alevel number(2)

)

-------------

insert into article values (1'蚂蚁大战大象'000);

insert into article values (2'大象被打趴下了'101);

insert into article values (3'蚂蚁也不好过'212);

insert into article values (4'瞎说'202);

insert into article values (5'没有瞎说'413);

insert into article values (6'怎么可能'101);

insert into article values (7'怎么没可能'612);

insert into article values (8'可能性是很大的'612);

insert into article values (9'大象进医院了'202);

insert into article values (10'护士是蚂蚁'913);

commit;

---------

蚂蚁大战大象

   大象被打趴下了

      蚂蚁也不好过

      瞎说

         没有瞎说

      大象进医院了

         护士是蚂蚁

   怎么可能

         怎么不可能

         可能性是很大的

--------------------------

create or replace procedure p (v_pid article.pid%type, v_level binary_integeris

  cursor c is select * from article where pid = v_pid;

  v_preStr varchar2(1024) := '';

begin

  for i in 1..v_level loop

    v_preStr := v_preStr || '****';

  end loop;

  for v_article in c loop

    dbms_output.put_line(v_preStr || v_article.cont);

  if (v_article.isleaf = 0)

then

    p (v_article.id, v_level + 1);

  end if;

  end loop;

end;

这篇关于Oracle基础学习笔记(二)-基于马士兵Oracle视频的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1042922

相关文章

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

C#基础之委托详解(Delegate)

《C#基础之委托详解(Delegate)》:本文主要介绍C#基础之委托(Delegate),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 委托定义2. 委托实例化3. 多播委托(Multicast Delegates)4. 委托的用途事件处理回调函数LINQ

Oracle存储过程里操作BLOB的字节数据的办法

《Oracle存储过程里操作BLOB的字节数据的办法》该篇文章介绍了如何在Oracle存储过程中操作BLOB的字节数据,作者研究了如何获取BLOB的字节长度、如何使用DBMS_LOB包进行BLOB操作... 目录一、缘由二、办法2.1 基本操作2.2 DBMS_LOB包2.3 字节级操作与RAW数据类型2.

查看Oracle数据库中UNDO表空间的使用情况(最新推荐)

《查看Oracle数据库中UNDO表空间的使用情况(最新推荐)》Oracle数据库中查看UNDO表空间使用情况的4种方法:DBA_TABLESPACES和DBA_DATA_FILES提供基本信息,V$... 目录1. 通过 DBjavascriptA_TABLESPACES 和 DBA_DATA_FILES

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Oracle登录时忘记用户名或密码该如何解决

《Oracle登录时忘记用户名或密码该如何解决》:本文主要介绍如何在Oracle12c中忘记用户名和密码时找回或重置用户账户信息,文中通过代码介绍的非常详细,对同样遇到这个问题的同学具有一定的参... 目录一、忘记账户:二、忘记密码:三、详细情况情况 1:1.1. 登录到数据库1.2. 查看当前用户信息1.

oracle DBMS_SQL.PARSE的使用方法和示例

《oracleDBMS_SQL.PARSE的使用方法和示例》DBMS_SQL是Oracle数据库中的一个强大包,用于动态构建和执行SQL语句,DBMS_SQL.PARSE过程解析SQL语句或PL/S... 目录语法示例注意事项DBMS_SQL 是 oracle 数据库中的一个强大包,它允许动态地构建和执行

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

PLsql Oracle 下载安装图文过程详解

《PLsqlOracle下载安装图文过程详解》PL/SQLDeveloper是一款用于开发Oracle数据库的集成开发环境,可以通过官网下载安装配置,并通过配置tnsnames.ora文件及环境变... 目录一、PL/SQL Developer 简介二、PL/SQL Developer 安装及配置详解1.下