Oracle day07 PL/SQL 火推

来源:互联网 发布:mac电脑怎部分怎么截图 编辑:程序博客网 时间:2024/06/02 04:43

PL/SQL

连接数据库的常见技术

JDBC    : Java访问数据库的技术
PL/SQL  : 过程化SQL语言, 是直接在数据库内部操作数据的一种语言
proc/c++: c和c++访问数据库的技术
ODBC    : 微软提供的访问数据库的技术
OCI     : Oracle 底层的连接 接口

1521端口号
简介

是一种程序语言 , 过程化SQL语言 . 

PL/SQL是对于SQL语句的扩展, 目前只有Oracle有 !

PL/SQL是对SQL(结构化查询语言)的过程扩展 !
不同的要学习的语法

PL/SQL
Java - JDBC
XML语法格式
HTML语法格式
CSS 
JS
JQUERY
JSON
Bootstrap
EasyUi
PL/SQL语法格式

class Demo{

        //成员位置   声明区


    public static void main(String[] args){
        System.out.println("哈哈哈");
        //执行区   

        //异常处理区
    }
}


1.  申明区 : 用来定义变量, 定义类型 , 如果没有申明的元素, 可以忽略不写

2.  执行区 : 用来执行PLSQL语句 / SQL语句

3.  异常处理区 : 一旦发生异常, 自动 执行的区域, 如果不需要处理异常 , 可以省略不写!

格式: 
    //这里其实可以写代码
declare
    /*申明区*/

    begin
        /*执行区*/
    exception
        /*异常处理区*/

end;[end是可以忽略的]
输出 hello PL/SQL

1.  想要控制台能输出文本 , 必须将数据库服务端的输出状态设置为打开 !

    写在程序的第一行(申明区之前)

    set serveroutput on;
    begin
        dbms_output.put_line('hello plsql');
    end;
    /
注释

--  单行注释

/**/多行注释
标识符

规则与Java基本相同

不能是PLSQL的关键字

长度最大限制为31个字符
变量

Java    : 数据类型 变量名 = 显式初始化值;

PL/SQL  : 变量名 数据类型(长度) := 初始化值;


PL/SQL中常见的数据类型: 

    1.  number  数字 (整型与浮点型)
    2.  binary_integer (整型)
    3.  char    字符串
    4.  varchar2    字符串 
    5.  date    日期
    6.  boolean 布尔

参考类型: ref

复合类型: record类型  table类型  cursor类型

大容量大数据类型    :BLOB CLOB  用来存储音视频 ,图片, 电子书等等 !

[id name content]

我们一般不使用上述的大容量类型存储音视频 !

我们一般存储的方式如下: 

    1.  将文件按照指定的目录结构, 存储到本地硬盘上!
    2.  将文件所在的路径字符串存储到数据库中
声明变量并打印:

定义一个number类型的变量, 初始化值为10 , 并打印

set serveroutput on;
declare
    var_i number := 10;
begin
    dbms_output.put_line(var_i);

end;
常量

格式: 

    变量名 constant 数据类型(长度) := 初始化值; 

常量在声明时, 必须赋值 , 否则无法使用 ,报如下错误:
PLS-00322: 常数 'VAR_I' 的声明必须包含初始赋值

set serveroutput on;
declare
    var_i constant number :=50;
begin
    dbms_output.put_line(var_i);
end;
/
非空变量

通过not null 修饰的变量, 必须赋值 ,否则报如下错误:
    PLS-00218: 声明为 NOT NULL 的变量必须有初始化赋值

格式: 变量名 数据类型(长度) not null := 初始化值;

set serveroutput on;
declare
    var_i number not null := 2000;
begin
    dbms_output.put_line(var_i);
end;
/
参考表格中的字段类型

因为PL/SQL毕竟是对数据库进行操作的一门语言 , 所以我们定义的变量,一般是用来对数据库中的数据 进行增删改差的.

所以我们在大部分情况下声明的变量的类型与长度 都 和数据库中某个表格中的字段一致 !

练习: 

    定义三个变量 , 名称分别为: id,salary,last_name , 并将其依次输出:

    -   id的数据类型, 与数据库中s_emp表格的id字段数据类型,长度一致
    -   salary的数据类型, 与数据库中s_emp表格的salary字段数据类型,长度一致
    -   last_name的数据类型, 与数据库中s_emp表格的last_name字段数据类型,长度一致


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

    set serveroutput on;

    declare
        var_id number(7) := 10001;
        var_salary number(11) := 88888;
        var_last_name varchar2(25) :='凯凯';
    begin
        dbms_output.put_line('员工的id:'||var_id||',姓名:'||var_last_name||', 月薪:'||var_salary);
    end;
    /
快速的引用表格字段的类型

格式: 变量名 表名.字段名%type := 初始化值;

练习: 

    定义三个变量 , 名称分别为: id,salary,last_name , 并将其依次输出:

    -   id的数据类型, 与数据库中s_emp表格的id字段数据类型,长度一致
    -   salary的数据类型, 与数据库中s_emp表格的salary字段数据类型,长度一致
    -   last_name的数据类型, 与数据库中s_emp表格的last_name字段数据类型,长度一致

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

    set serveroutput on;

    declare
        var_id s_emp.id%type := 10001;
        var_salary s_emp.salary%type := 88888;
        var_last_name s_emp.last_name%type :='凯凯';
    begin
        dbms_output.put_line('员工的id:'||var_id||',姓名:'||var_last_name||', 月薪:'||var_salary);
    end;
    /
record 类型

类似Java中的对象的模版 (Class) , 把多个不同的数据, 封装为一个自定义类型!

创建类型的语法格式: 

    创建类型的代码, 编写在申明区

    type 自定义类型名称 is record(
        字段变量名1 数据类型,
        字段变量名2 数据类型,
        ......
        字段变量名n 数据类型
    );

声明变量时的语法格式: 

    变量名 自定义类型名称 ;

操作record类型中封装的变量: 

    -   赋值      recode变量名.字段变量名 := 值;
    -   取值      recode变量名.字段变量名;


------------------------------------------------------------
Java的方式:

class 自定义类名称{
    数据类型 变量名1;
    数据类型 变量名2;
    ......
    数据类型 变量名n;
}
class Person{
    int age;
    String name;
}

自定义类名称 对象名;
Person p = new Person();
p.name = "张三";
System.out.println(p.name);

练习: 

定义一个record类型, 包含是s_emp表格中的字段: 

    id,salary,last_name

并声明变量, 给内部的id,salary,last_name分别赋值 ,并打印


set serveroutput on;
declare
    type myemp is record(
        id s_emp.id%type,
        last_name s_emp.last_name%type,
        salary s_emp.salary%type
    );

    var_emp1 myemp;
begin
    var_emp1.id := 10001;
    var_emp1.last_name := '凯凯';
    var_emp1.salary := 80;

    dbms_output.put_line('员工编号'||var_emp1.id||',员工姓名:'||var_emp1.last_name||',月薪:'||var_emp1.salary);
end;
/
从数据库 查询一行数据 赋值给 record

把从数据库中查询的一行数据, 赋值给一个record类型的变量 !

格式的要求:  select语句返回的列名与record封装的属性名, 必须完全一致 !

语法:

select 字段列表 into record变量名 from 表名 where 条件;


--  1   定义一个record类型, 包含s_emp表中的id,last_name,salary !

set serveroutput on;
declare
    type myemp is record(
        id s_emp.id%type,
        last_name s_emp.last_name%type,
        salary s_emp.salary%type
    );

    var_emp1 myemp;
begin

--  2   通过查询语句, 将一个查询语句的结果, 赋值给上面的record类型变量var_emp1

    select id,last_name,salary into var_emp1 from s_emp where id=1;

    dbms_output.put_line('员工id:'||var_emp1.id||', 员工姓名:'||var_emp1.last_name||', 员工月薪:'||var_emp1.salary);

end;
/
练习

1.  定义一个record类型, 包含s_dept表格中的所有字段 

    将 s_dept表格中的 id为50的部门信息, 赋值给这个record类型的变量 !

    set serveroutput on;

    declare
        type mydept is record(
            id s_dept.id%type,
            name s_dept.name%type,
            region_id s_dept.region_id%type
        );
        var_dept1 mydept;
    begin
        select * into var_dept1 from s_dept where id=50;
        dbms_output.put_line('编号为:'||var_dept1.id||'的部门名称为:'||var_dept1.name||',部门所在地区的编号为:'||var_dept1.region_id);
    end;
    /
引用表格的变量

声明表格行类型的record格式:   变量名 表名%rowtype;

    有时候我们需要定义一个与某表格字段列表完全一致的record类型的数据 , 
    但是表格的字段大多都很多, 编写起来很麻烦 . 那么就可以使用上述的方式定义: 


2.  定义一个record类型, 包含s_emp表格的所有字段 

    并将id为24的员工的所有信息 查询出来, 赋值给这个变量 ,输出他的id,last_name,dept_id

    我们可以在声明一个record类型的变量时, 直接引用一个表格的变量

    变量名 表名%rowtype;


    set serveroutput on;
    declare
        var_emp1 s_emp%rowtype;
    begin
        select * into var_emp1 from s_emp where id=24;
        dbms_output.put_line('员工的编号:'||var_emp1.id||',姓名:'||var_emp1.last_name||',他的部门编号为:'||var_emp1.dept_id||',他的薪资:'||var_emp1.salary);
    end;
    /
table类型

类似Java中学习的Map集合, 是一个键值对的容器 !

语法: 

1.  定义类型
    type 自定义类型名 is table of 存储的值类型 index by 键的类型;


2.  定义变量
    变量名 自定义类型名;

3.  访问变量中的键值对(get/set)

    -   获取
            变量名(key);   
    -   设置
            变量名(key) := 值;
练习

定义一个table类型的数据, 要求key为binary_integer, 值类型number ! 

要求向其中存储6个number类型的数据 , 然后依次取出打印!


set serveroutput on;

declare 
    type mytable is table of number index by binary_integer;
    var_mt mytable;
    var_index binary_integer :=0;
begin

    var_mt(0) := 1.123;
    var_mt(1) := 2.123;
    var_mt(2) := 3.123;
    var_mt(3) := 4.123;
    var_mt(4) := 5.123;
    var_mt(5) := 6.123;

    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;

end;
/
当key不连续时 , 怎么按照顺序取出数据(迭代)

例如: 

set serveroutput on;

declare 
    type mytable is table of number index by binary_integer;
    var_mt mytable;
    var_index binary_integer :=0;
begin

    var_mt(0) := 1.123;
    var_mt(-1) := 2.123;
    var_mt(2) := 3.123;
    var_mt(-3) := 4.123;
    var_mt(4) := 5.123;
    var_mt(-5) := 6.123;

    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_index+1;

end;
/
迭代方法

参考Java中的迭代思想, 来理解迭代方法

table变量.first(): 获取table变量存储的第一个元素 对应的key

table变量.next(参数1): 获取table变量的下一个元素的key
    参数1.    传入当前key, 获取当前key的下一个key

table变量.last()  :获取table变量的最后一个元素的key


set serveroutput on;

declare 
    type mytable is table of number index by binary_integer;
    var_mt mytable;
    var_index binary_integer :=0;
begin

    var_mt(-100) := 1.123;
    var_mt(-1) := 2.123;
    var_mt(2) := 3.123;
    var_mt(-3) := 4.123;
    var_mt(4) := 5.123;
    var_mt(-5) := 6.123;
    --  在迭代之前, 将key的初始值, 设置为table变量的第一个key
    var_index = var_mt.first();
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_mt.next(var_index);
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_mt.next(var_index);
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_mt.next(var_index);
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_mt.next(var_index);
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_mt.next(var_index);
    dbms_output.put_line(var_mt(var_index));        
    var_index := var_mt.next(var_index);


end;
/
变量作用域

当全局变量与局部变量产生名称的冲突时, 选择某一个变量使用

    冲突案例: 

    set serveroutput on;
    declare
        var_i number := 10;
    begin

            declare
                var_i number := 20;
            begin
                dbms_output.put_line(var_i);
            end;
    end;
    /

上述的操作,  我们输出的数据为20, 表示采用的是就近原则 !  我们想访问外部代码块的变量 , 可以通过给代码块添加标签来区分 !


    :

    set serveroutput on;
    <<heheda>>
    declare
        var_i number := 10;
    begin

            declare
                var_i number := 20;
            begin
                dbms_output.put_line(var_i);
                dbms_output.put_line(heheda.var_i);
            end;
    end;
    /
控制语句结构
IF语句
语法一:

Java:
    if(条件){
        //如果条件为true , 则这里执行
    }
---------------------------------------------
PL/SQL:

    if 条件 then
        --如果条件为true , 则这里执行
    end if;
语法二:

Java:
    if(条件){
        如果条件为true , 则这里执行
    }else{
        如果条件为false , 则这里执行
    }
---------------------------------------------
PL/SQL:

    if 条件 then
        --如果条件为true , 则这里执行
    else
        --如果条件为false , 则这里执行
    end if;
语法三:

Java:
    if(条件1){
        如果条件1为true , 则这里执行
    }else if(条件2){
        如果条件2为true , 则这里执行
    }
---------------------------------------------
PL/SQL:

    if 条件1 then
        --如果条件1为true , 则这里执行
    elsif 条件2 then
        --如果条件2为true , 则这里执行
    end if;
语法四:

Java:
    if(条件1){
        如果条件1为true , 则这里执行
    }else if(条件2){
        如果条件2为true , 则这里执行
    }else if(条件3){
        如果条件3为true , 则这里执行
    ......

    }else{
        如果上述条件都不为true , 则这里执行
    }
---------------------------------------------
PL/SQL:
    if 条件1 then
        如果条件1为true , 则这里执行
    elsif 条件2 then
        如果条件2为true , 则这里执行
    elsif 条件3 then
        如果条件3为true , 则这里执行
    ......

    else 
        如果上述条件都不为true , 则这里执行
    end if;
接收键盘输入的案例(IF案例)

在执行区 给变量赋值时使用: 

    格式: 变量名 :=&任意提示文本;

        --  注意: 接收用户输入的提示文本, 不需要添加单引号 !

1.  接收用户输入的两个数字 , 并输出最大的一个数字

    set serveroutput on;
    declare
        --声明两个变量, 用来准备接收用户的输入
        var_a number;
        var_b number;
    begin
        --接收用户输入, 并赋值给变量
        var_a := &请输入第一个数字;
        var_b := &请输入第二个数字;

        if var_a>var_b then
            dbms_output.put_line('您输入的最大数字:'||var_a);
        else
            dbms_output.put_line('您输入的最大数字:'||var_b);
        end if;

    end;
    /
循环
简单循环loop

语法: 

    loop
        循环体
        exit when 退出条件;--不写就是死循环
    end loop;

退出循环的特殊方式: 
    可退出任何循环: exit;

    大多时候应用在if语句中 例如:
    if 条件 then
        exit;--表示当条件满足时, 循环结束
    end if;
练习: 
    1.  通过循环 , 输出1-10 ;

    set serveroutput on;
    declare
        var_i number := 1;
    begin
        loop
            dbms_output.put_line(var_i);
            exit when var_i=10;
            var_i=var_i+1;
        end loop;
    end;
    /
    2.  通过循环 , 输出10-1 ;

    set serveroutput on;
    declare
        var_i number := 10;
    begin
        loop
            dbms_output.put_line(var_i);
            exit when var_i=1;
            var_i:=var_i-1;
        end loop;
    end;
    /
while循环

语法: 

    while 循环条件 loop
        循环体
    end loop;

定义: 与Java中的while循环一致!
练习: 
    1.  通过while循环 , 输出1-10 ;

    set serveroutput on;

    declare 
        var_i number :=1;
    begin
        while var_i!=11 loop
            dbms_output.put_line(var_i);
            var_i:=var_i+1;
        end loop;
    end;
    /
2.  通过while循环 , 输出10-1 ;

    set serveroutput on;

    declare 
        var_i number :=10;
    begin
        while var_i!=0 loop
            dbms_output.put_line(var_i);
            var_i:=var_i-1;
        end loop;
    end;
    /
for循环 (智能循环)

所谓的智能,指的是循环变量自动变化 !

循环变量在智能循环中由系统控制, 所以我们只能读取 , 不可写入 !

语法格式:

for 声明循环变量 in 循环变量初始值..循环变量最终值 loop
    循环体
end loop;

声明的循环变量 不需要设置类型, 默认整型 , 且初始化值必须比最终值小
练习: 
    1.  通过for循环 , 输出1-10 :

    set serveroutput on;
    begin
        for i in 1..10 loop
            dbms_output.put_line(i);
        end loop;
    end;
    /
2.  通过for循环 , 输出10-1 :

    set serveroutput on;
    begin
        for i in 1..10 loop
            dbms_output.put_line(11-i);
        end loop;
    end;
    /
反转for循环

与正常的for循环相反, 循环变量的初始值 大于 循环变量的最终值 ! (倒序循环)

语法格式: 

    for 声明循环变量 in reverse 循环变量最终值..循环变量初始值 loop

    end loop;
练习:

    --通过反转for循环 , 输出10-1 :

    set serveroutput on;
    begin
        for i in reverse 1..10 loop
            dbms_output.put_line(i);
        end loop;
    end;
    /
多重循环的退出问题

    练习: 
    外层循环10次 , 内层循环10次

    当外层循环变量等于6 , 内层循环变量等于6 , 退出外层循环

    set serveroutput on;
    declare
        var_i number :=0;
        var_j number :=0;
    begin
        while var_i<10 loop
            var_j:=0;       
            while var_j<10 loop
                dbms_output.put_line('i='||var_i||'--->j='||var_j);
                    if var_i=6 and var_j=6 then
                        exit;
                    end if;

                var_j:=var_j+1;
            end loop;
            var_i:=var_i+1;
        end loop;
    end;


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

    上述代码 只是退出了内层循环 , 我们的需求是退出外层的循环 ,需要通过标签来实现

    set serveroutput on;
    declare
        var_i number :=0;
        var_j number :=0;
    begin
        <<heheda>>
        while var_i<10 loop
            var_j:=0;       
            while var_j<10 loop
                dbms_output.put_line('i='||var_i||'--->j='||var_j);
                    if var_i=6 and var_j=6 then
                        exit heheda;
                    end if;

                var_j:=var_j+1;
            end loop;
            var_i:=var_i+1;
        end loop;
    end;
GOTO语句
原创粉丝点击