zoukankan      html  css  js  c++  java
  • PLSQL(day05)

    PLSQL

    1.常用的访问数据库的相关技术

    1. plsql 过程化的sql
    2. proc/c++ 在c/c++语言中访问oracle数据库的技术
    3. ado/odbc vc中访问数据库的技术
    4. oci oracle底层提供的客户端的连接接口
    5. sql j/jdbc java访问数据库的技术
      2.PLSQL
      2.1 概念
      plsql(procedured language/sql)是在标准sql的基础上增加了过程化的处理形成的语言
      oracle客户端工具访问oracle服务器的操作语言
      是对sql的扩充
      2.2 特点
      结构化模块化编程
      良好的可移植性
      良好的可维护性
      提升系统性能
     不便于向异构数据库移植
    

    3.SQL语言的特点
    机器语言 汇编语言 高级语言 结构化语言
    只管做什么 不管怎么做
    没有过程和控制结构
    没有算法描述能力

    4.plsql扩充了sql

    1. 变量和数据类型
    2. 控制语句
    3. 过程和函数
    4. 对象类型和方法

    5.plsql的程序框架
    declare
    /* 声明区 声明变量、定义类型等 /
    -- 单行注释 '--'
    -- 多行注释 /
    内 容/
    -- 如果没有需要声明、定义的内容,声明区可以省略
    begin
    /
    执行区 执行sql或plsql语句 /
    exception
    /
    异常处理区 处理异常的区域 /
    /
    可省略 */
    end;
    / -- 表示plsql代码结束 必须独立占一行

    6.plsql的开发工具
    sqlplus 命令提示符的工具
    plsqldeveloper 图形化的开发工具

    begin
    dbms_output.put_line('Hello World!');
    end;
    /
    -- 打开输出功能
    set serveroutput on
    --调整字段占位长度
    set 字段名 for(format) a+字段长度
    或者
    set linesize + 字段长度
    7.标识符
    7.1 作用
    给变量、数据类型、游标、过程、函数、触发器、包等命名
    7.2 使用变量
    declare
    变量名 数据类型;
    变量名 数据类型 := 值;
    begin
    变量名 := 值;

    -- 声明两个变量,赋值并输出
    declare
         var_id number;
         var_name varchar2(20):='test';
    begin
         var_id:=1;
         dbms_output.put_line(var_id||','||var_name);
    end;
    /
    

    8.变量和数据类型
    8.1 数据类型
    1) 标量类型
    number binary_integer 数字类型
    char varchar2 字符串类型
    date 日期类型
    boolean 布尔类型
    2) 复合类型
    record
    table
    3) 参考类型 ref
    ref cursor(参考游标)
    4) 大类型
    BLOB 0-4g
    CLOB 0-4g
    BFILE

    8.2 变量的修饰符
    变量名 constant 数据类型;
    变量名 数据类型 not null;
    declare
    -- (1)
    -- var_id constant number;
    var_id constant number:=1;
    -- (3)
    -- var_name varchar(20) not null;
    var_name varchar(20) not null:='1';
    begin
    -- (2)
    -- var_id:=1;
    var_name:='test';
    dbms_output.put_line(var_id);
    dbms_output.put_line(var_name);
    end;
    /

    (1) 用constant修饰的变量必须初始化
    (2) 用constant修饰的变量不允许赋值
    (3) 用not null修饰的变量必须初始化
    
    任何类型的变量,在赋值前 初值都是null
    

    8.3 使用binary_integer和boolean定义变量
    true false null
    declare
    var_id binary_integer:=100;
    var_flag boolean;
    begin
    var_flag:=true;
    if var_flag then
    dbms_output.put_line(var_id);
    end if;
    end;
    /

    8.4 声明两个变量,类型分别和s_emp表中id、first_name相同,用来接收id=1的员工的id和first_name,并输出
    declare
    var_id number(7);
    var_name varchar2(25);
    begin
    var_id:=1;
    var_name:='Carmen';
    dbms_output.put_line(var_id||','||var_name);
    end;
    /

    获取表中字段的数据类型:表名.字段名%type
    使用select语句给变量赋值:
    select 字段列表 into 变量列表 from 表名 where 条件;
    注意:字段列表和变量列表的顺序、数量和数据类型要一致
    select语句有且只有一行结果

    declare
    var_id s_emp.id%type;
    var_name s_emp.first_name%type;
    begin
    select id,first_name into var_id,var_name from s_emp
    where id=1;
    dbms_output.put_line(var_id||','||var_name);
    end;
    /

    8.5 record类型 相当于C语言中的结构体
    8.5.1 定义record类型
    type 记录类型名 is record(
    字段名 类型,
    ...
    字段名 类型
    );
    8.5.2 定义record类型,有三个字段,类型分别和s_emp表中id,first_name,salary相同。声明该类型变量,用于接收id=2的员工的id,first_name和salary,并输出。
    declare
    -- 定义record类型
    type emprecord is record(
    id s_emp.id%type,
    name s_emp.first_name%type,
    sal number(11,2)
    );
    -- 声明record类型变量
    var_emp emprecord;
    var_emp2 emprecord;
    begin
    select id,first_name,salary into var_emp from s_emp
    where id=2;
    dbms_output.put_line(var_emp.id||','||var_emp.name||','
    ||var_emp.sal);
    var_emp2:=var_emp;
    dbms_output.put_line(var_emp2.id||','
    ||var_emp2.name||','
    ||var_emp2.sal);
    end;
    /

    -- 查询的字段的数量少于record类型的字段的数量
    declare
    -- 定义record类型
    type emprecord is record(
    id s_emp.id%type,
    name s_emp.first_name%type,
    sal number(11,2)
    );
    -- 声明record类型变量
    var_emp emprecord;
    begin
    select id,first_name into var_emp.id,var_emp.name
    from s_emp where id=2;
    dbms_output.put_line(var_emp.id||','||var_emp.name||','
    ||var_emp.sal);
    end;
    /

    -- 接收表中的全部字段,record类型?

    8.5.3 用于接收表中整行数据的类型
    表名%rowtype
    -- 查询s_emp表中 id=3的员工的全部信息,保存在变量中并输出
    declare
    var_emp s_emp%rowtype;
    begin
    select * into var_emp from s_emp where id=3;
    dbms_output.put_line(var_emp.id||','||
    var_emp.first_name||','||
    var_emp.title);
    end;
    /

    8.6 table类型 类似于C语言中的数组
    8.6.1 定义table类型的语法
    type table类型 is table of 元素的数据类型
    index by binary_integer;
    8.6.2 定义一个table类型,声明变量,保存多个数字
    declare
    /* 定义table类型 /
    type numstable is table of number
    index by binary_integer;
    /
    声明table类型的变量 */
    var_nums numstable;
    begin
    var_nums(3):=100;
    var_nums(7):=200;
    var_nums(1):=300;
    dbms_output.put_line(var_nums(3));
    -- dbms_output.put_line(var_nums(2));
    end;

    8.6.3 下标连续时,table类型变量的访问
      declare
           /* 定义table类型 */
           type numstable is table of number
           index by binary_integer;
           /* 声明table类型的变量 */
           var_nums numstable;
           /* 声明变量 表示下标 */
           var_i binary_integer;
       begin
           var_nums(3):=100;
           var_nums(5):=200;
           var_nums(4):=300;
           var_i:=3;
           dbms_output.put_line(var_nums(var_i));
           var_i:=var_i + 1;
           dbms_output.put_line(var_nums(var_i));
           var_i:=var_i + 1;
           dbms_output.put_line(var_nums(var_i));
           -- var_i:=var_i + 1;
       end; 
       /
    

    8.6.4 下标不连续时,对table类型变量的遍历
    first() -- 获取第一个元素的下标
    next(n) -- 获取下标为n的元素的下一个元素的下标
    last() -- 获取最后一个元素的下标

    declare
           /* 定义table类型 */
           type numstable is table of number
           index by binary_integer;
           /* 声明table类型的变量 */
           var_nums numstable;
           /* 声明变量 表示下标 */
           var_i binary_integer;
       begin
           var_nums(3):=100;
           var_nums(7):=200;
           var_nums(4):=300;
           var_i:=var_nums.first();
           dbms_output.put_line(var_nums(var_i));
           var_i:=var_nums.next(var_i);
           dbms_output.put_line(var_nums(var_i));
           var_i:=var_nums.next(var_i);
           dbms_output.put_line(var_nums(var_i));
           -- var_i:=var_nums.next(var_i);
       end; 
    

    8.6.5 定义table类型变量,保存s_emp表中id为1,3,7的员工的信息,并输出
    declare
    /* 定义table类型 /
    type empstable is table of s_emp%rowtype
    index by binary_integer;
    /
    声明table类型变量 /
    var_emps empstable;
    /
    声明变量 保存下标 */
    var_i binary_integer;
    begin
    select * into var_emps(1) from s_emp where id=1;
    select * into var_emps(3) from s_emp where id=3;
    select * into var_emps(7) from s_emp where id=7;
    var_i:=var_emps.first();
    dbms_output.put_line(var_emps(var_i).id||','||
    var_emps(var_i).first_name||','||
    var_emps(var_i).salary);
    var_i:=var_emps.next(var_i);
    dbms_output.put_line(var_emps(var_i).id||','||
    var_emps(var_i).first_name||','||
    var_emps(var_i).salary);
    var_i:=var_emps.next(var_i);
    dbms_output.put_line(var_emps(var_i).id||','||
    var_emps(var_i).first_name||','||
    var_emps(var_i).salary);
    var_i:=var_emps.next(var_i);
    end;

    8.6. 变量的作用域

    declare
       -- 全局
       var_a number:=1;
    begin
       declare
          -- 局部
          var_b number:=2;
       begin
          dbms_output.put_line(var_a);
          dbms_output.put_line(var_b);
       end; 
       dbms_output.put_line(var_a);
       -- dbms_output.put_line(var_b);
    end; 
    局部既可以访问局部变量,也可以访问全局变量
    全局 只可以访问全局变量
    
    局部变量和全局变量重名时,局部变量会覆盖同名的全局变量
    -- 局部访问同名的全局变量:
    使用标签
    定义标签:     <<标签名>>
    使用标签:     标签名.变量名
    
    <<g>>
    declare
       -- 全局
       var_a number:=1;
    begin
       declare
          -- 局部
          var_a number:=2;
       begin
          dbms_output.put_line(g.var_a);
       end; 
       dbms_output.put_line(var_a);
    end; 
    
    1. 控制语句
      9.1 if语句
      9.1.1 语法

      1. 简单if语句
        if 条件 then
        操作
        end if;
      2. if...else语句
        if 条件 then
        操作1
        else
        操作2
        end if;
      3. 多分支if
        if 条件1 then
        操作1
        elsif 条件2 then
        操作2
        ....
        else
        操作n
        end if;
      4. 嵌入if
        if 条件1 then
        if 条件2 then
        操作1
        else
        操作2
        end if;
        else
        if 条件3 then
        操作3
        else
        操作4
        end if;
        end if;

      9.1.2 练习:声明三个数字类型变量并赋值,输出最大值
      -- 方法一:
      declare
      var_a number:=1;
      var_b number:=200;
      var_c number:=100;
      begin
      if var_a > var_b then
      if var_a > var_c then
      dbms_output.put_line(var_a);
      else
      dbms_output.put_line(var_c);
      end if;
      else
      if var_b > var_c then
      dbms_output.put_line(var_b);
      else
      dbms_output.put_line(var_c);
      end if;
      end if;
      end;
      /

      -- 方法二:
      declare
      var_a number:=&var_a;// 后面这'&'是输入相当于c语言里的scanf
      var_b number:=&var_b;
      var_c number:=&var_c;
      var_temp number;
      begin
      var_temp:=var_a;
      if var_b > var_temp then
      var_temp:=var_b;
      end if;
      if var_c >var_temp then
      var_temp:=var_c;
      end if;
      dbms_output.put_line(var_temp);
      end;

      9.1.3 NULL的运算特点
      declare
      var_a number;
      var_b number;
      begin
      if var_a > var_b then
      dbms_output.put_line('a>b');
      elsif var_a < var_b then
      dbms_output.put_line('a<b');
      elsif var_a = var_b then
      dbms_output.put_line('a=b');
      elsif var_a is null and var_b is null then
      dbms_output.put_line(
      'var_a is null and var_b is null');
      end if;
      end;
      /

    9.2 循环语句
    循环变量初始化 循环条件 循环操作 条件的更新

     9.2.1 简单循环
       1) 语法
           loop
             -- 循环操作
           end loop;
       2) 结束循环的方式
          -- 方式一:
          if 退出循环的条件 then
                 exit;
          end if;
          -- 方式二:
          exit when 退出循环的条件;
        3) 使用简单循环输出1..10
           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;
           /
           -- 使用if退出循环
           declare
              var_i number:=10;
           begin
              loop
                 dbms_output.put_line(var_i);
                 if var_i=1 then
                      dbms_output.put_line('loop over!');
                      exit;
                 end if;
                 var_i:=var_i-1;
              end loop;
           end;
           /
    
    9.2.2 while循环
      1) 语法
        while 条件 loop
            -- 循环操作
         end loop;
      2) 使用while循环输出1..10
        declare
            var_i number:=1;
        begin
            while var_i<=10 loop
                dbms_output.put_line(var_i);
                var_i:=var_i+1;
            end loop;
        end;
    
        -- 练习:从1..100累加,输出和大于2000时对应的数字
        declare
            var_i number:=1;
            var_sum number:=0;
        begin
            while var_i<=100 loop
                 var_sum:=var_sum + var_i;
                 if var_sum >=2000 then
                    dbms_output.put_line(var_i);
                    exit;
                 end  if;
                 var_i := var_i + 1;
             end loop;
        end;
    
    
     9.2.3 for 循环   
        智能循环
        1) 语法
            for 循环变量 in 区间 loop
                 -- 循环操作
            end loop;
        2) 使用for 循环输出1..10
    
        begin
           for var_i in 1..10 loop
                 dbms_output.put_line(var_i);
           end loop;
        end;
    
         -- 练习 使用for循环输出10..1 
         begin
           for var_i in 10..1 loop
                 dbms_output.put_line(var_i);
           end loop;
         end;
         -- 上边代码循环一次也不执行
        
        使用 reverse 实现倒序输出
        begin
           for var_i in reverse 1..10 loop
                 dbms_output.put_line(var_i);
           end loop;
         end;
         
         -- 使用退出循环的方式  提前结束循环
         begin
           for var_i in 1..10 loop
                 dbms_output.put_line(var_i);
                 if var_i=5 then
                     -- var_i:=11; 错误
                 end if;
           end loop;
         end;
    
         a.循环变量不需要声明
         b.区间必须是从小到大  使用reverse实现反转循环
         c.循环变量不允许赋值
    

    9.3 跳转语句 goto
    9.3.1 语法
    <<标签名>>
    -- 这里必须有语句
    NULL; -- 空语句

     goto 标签名;
    

    9.3.2 使用goto退出嵌套循环
    begin
    for var_i in 1..3 loop
    for var_j in 1..5 loop
    dbms_output.put_line(var_j);
    if var_j=3 then
    goto outer;
    end if;
    end loop;
    end loop;
    <>
    NULL;
    end;

    9.3.3 使用if..exit方式退出循环
    begin
    <> //提到前面来比较好,能够一眼被一眼的看出来
    for var_i in 1..3 loop
    for var_j in 1..5 loop
    dbms_output.put_line(var_j);
    if var_j=3 then
    exit outer;
    end if;
    end loop;
    end loop;
    dbms_output.put_line('loop over');
    end;

    1. plsql中使用sql语句
    1. select语句
      select语句要和into 配合使用
      select 字段列表 into 变量列表 from 表名 where 条件;
    2. dml语句
      tcl语句
      可以直接在plsql中使用
    3. ddl语句
      不能直接在plsql中使用 需要用动态sql实现

    11.动态sql
    11.1 概念
    把一条字符串对应的sql语句,当成真正的sql语句去执行
    11.2 案例: 创建一张表
    /* 错误:ddl语句不能直接在plsql中使用 */
    begin
    create table testdsql_zsm_00(id number);
    end;
    -- 在plsql中可以使用函数
    declare
    sqlstr varchar2(100);
    begin
    sqlstr:='create table testdsql_zsm_00(id number)';
    sqlstr:=substr(sqlstr,1,length(sqlstr)-1)
    ||',name varchar2(20))';
    -- dbms_output.put_line(sqlstr);
    execute immediate sqlstr;
    end;

    11.3 DML语句的动态sql
    1) 直接在plsql中使用dml和tcl语句
    begin
    insert into testdsql_zsm_00 values(1,'test1');
    commit;
    end;
    2) 常规字符串的拼接
    declare
    sqlstr varchar2(100);
    begin
    sqlstr:= 'insert into testdsql_zsm_00 values(2,''test2'')';
    execute immediate sqlstr;
    commit;
    end;
    3)带有变量的字符串的拼接
    declare
    var_id number:=3;
    var_name varchar2(20):='test3';
    sqlstr varchar2(100);
    begin
    sqlstr:='insert into testdsql_zsm_00 values('||var_id||
    ','''||var_name||''')';
    -- dbms_output.put_line(sqlstr);
    execute immediate sqlstr;
    commit;
    end;

    1. 使用占位符 配合using解决字符串拼接的问题
      占位符: :占位符名
      execute immediate sqlstr using 变量列表;
      declare
      var_id number:=4;
      var_name varchar2(20):='test4';
      sqlstr varchar2(100);
      begin
      sqlstr:='insert into testdsql_zsm_00 values(:b0,:b1)'; //:b0 :b1 就是占位符
      execute immediate sqlstr using var_id,var_name;
      commit;
      end;

    11.4 select语句动态sql
    必须是普通的select语句(不带into)
    select语句有且只有一行结果

     declare
        sqlstr varchar2(100);
        var_name s_emp.first_name%type;
     begin
        sqlstr:='select first_name from s_emp where id=1';
        execute immediate sqlstr into var_name;
        dbms_output.put_line(var_name);
     end;
    

    总结:
    1.变量和类型
    定义和使用record和table类型
    type 类型名 is record(
    字段 类型,
    ....
    字段 类型
    );

    type 类型名 is table of 元素类型 index by binary_integer;

    表名.字段%type
    表名%rowtype

    2.控制语句
    分支:if
    循环:简单循环、while循环、for循环
    跳转语句:goto
    结束循环的两种方式:
    exit when 退出循环的条件;

        if 退出循环的条件 then
            exit;
        end if;
    

    3.动态sql
    sqlstr varchar2(200):='';
    execute immediate sqlstr;

    'insert into 表名 values(:b0,:b1,....)'
    execute immediate sqlstr using 变量1,变量2,....;


    练习:
    1.定义record类型,声明变量,保存s_dept表中id=31的部门的
    信息

    1. 使用动态sql语句,删除testdsql_zsm_00表中指定id 的信息
  • 相关阅读:
    客户细分那点事_实践1
    和各种人去交流_好玩的事
    客户细分那点事_理论篇
    模型持久化
    天赋是积累出来的——转载自周鸿祎博客
    Pytorch——torch.nn.Sequential()详解
    第2章 Python序列
    Pytorch将数据打包
    线性回归的从零开始实现
    plt.scatter 各参数详解
  • 原文地址:https://www.cnblogs.com/Kernel001/p/7684510.html
Copyright © 2011-2022 走看看