zoukankan      html  css  js  c++  java
  • Oracle视图和PL SQL编程.

    Oracle中的视图

    Oracle数据库中视图是数据库中特有的对象。视图主要用于数据查询,它不会存储数据(物化视图除外)。这是视图和数据表的重要区别。

    视图的数据来源于一个或等多个表中的数据,可以利用视图进行查询、插入、更新和删除数据,操作视图就是间接操作数据库表。

    通常情况下,视图主要用于查询,不提倡通过视图而更新与视图相关的表,因为视图中的数据只是一个或多个表中的局部数据。

    关系视图

    关系视图是四种视图中比较简单和常用的视图。可以将关系视图看做对简单或复杂查询的定义。它的输出可以看作一个虚拟的表,该表的数据是由其它基础数据表提供的。由于关系视图并不存储真正的数据,因此占用数据库资源也较少

    create or replace view view_name AS select or其他视图......

    create or replace view view_communic_address AS select email,address,tel from students;

    select * from view_communic_address --查询视图

    提示:视图中的数据来源于实际的物理表,修改视图中的数据实际就是更改视图数据的来源表,在通常情况下不提倡通过视图修改数据;

    只读关系视图

    只读视图单一提供数据的查询

    create or replace view vw_employees AS

    select employee_id,employee_name,employee_position,employee_age

    from employees

    with read only;

    Drop View 视图名称;--删除视图对象

    内嵌视图

    内嵌视图是非存在于Oracle数据库中的对象,它只是查询过程中生成的结果数据集;内嵌视图通常以子查询的方式出现在SQL操作中。

    内嵌视图通常对于数据库的开销有更大的优势,可以适当使用。

    内嵌视图的创建不使用create关键字创建,通常在查询语句中创建内嵌视图,在执行完sql操作后,内嵌视图自动销毁。

    物化视图

    物化视图也叫快照,物化视图和表一样生成物理文件并占用磁盘空间,对于数据库及磁盘空间都有一定的开销维护,在物化视图上可以像普通表一样创建索引。

    Create materializedview 视图名称AS Select * from 表名

    PL/SQL编程

    PL/SQL是过程化SQL语言(Procedural Language/SQL)

    PL/SQL是对SQL语句的扩展,增加了编程语言的特点,所以PL/SQL就是把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能,在定义复杂业务的函数、过程及建立触发器时使用。

    PL/SQL中通常只能使用数据DML(数据操纵)语音和DCL(数据控制)语言,诸如:insertupdateselect intodeletecommitrollbacksavepoint。不允许使用DDL(数据定义)语言 createdropalter......

    PL/SQL块的组成结构

    DECLARE --声明单元(可选)

    变量1 类型[(长度)];

    变量2 类型[(长度)];

    BEGIN --执行单元(必须)

    数据处理语句;

    exception --异常处理单元(可选)

    异常处理语句;

    END;

    声明单元

    PLSQL使用DDECLARE关键字声明变量定义,此单元必须在PLSQL的最前面。

    通常变量名称可以包括字母、下划线、数字、#$

    变量名称不能超过30个字符

    l 第一个字符必须是字母

    l 不区分大小写

    l 不能使用任何关键字

     

    declare

    name varchar(24);--声明变量

    age int:=25;--声明变量并赋默认值

    address String(64);--声明编程类型变量

     

    PL SQL编程变量类型

    char定长字符类型,包括子类characterstringrowidNchar最长限制在2000个字符

    varchar2可变字符类型,包括子类varcharstringnvarchar2最长限制在4000个字符

    number(p,s) 值类型,包括子类intintegersmallintdecdouble

    date 日期型

    boolean 布尔类型

    %type 复合类型变量

    %rowtype 行符合类型变量

     

    %rowtype自定义符合类型

    %rowtype%type类型的扩展,可存储查询返回数表的一个未知列数量及类型的功能,使用更加方便

    declare

    R_var student% rowtype;

    begin

    select * into R_var from students where id=stu001;

    dbms_output.put_line(R_var.name);

    end;

     

    PL SQL逻辑控制语句

    IF Else基本逻辑语句if可以单独使用,Else必须结合if使用

    Elsif 等价于javaelse if语句

    Case when 类似于JavaSwitch Case

     

    if 布尔表达式 then 满足if执行的语句;

    elsif 布尔表达式 then 满足if执行的语句;

    else对应else执行的语句;

    end if;

    case

    when布尔表达式then执行语句;

    when布尔表达式then执行语句;

    else 执行语句;

    end case

     

    loop循环

    loop

    [业务处理语句;] [exit;]--退出循环

    endloop;

    while循环

    while布尔表达式loop

    [业务处理语句;] [循环变量更新;]

    endloop;

    for循环

    for in1..5 loop

    [业务处理语句;]

    endloop

     

    -- 创建关系视图
    
    create or replace view view_emp_tab_salary AS 
    select e.NAME,s.grantdate,s.should,s.actual from emp_tab e inner join salary s
    on e.ID = s.emp_id;
    
    select * from view_emp_tab_salary; --查询视图
    update view_emp_tab_salary SET NAME='任我行' WHERE NAME='张敏'; --不允许修改
    update view_emp_tab_salary SET should=should+50 WHERE NAME='任我行'; --不允许修改
    select * from salary;
    
    --创建只读关系视图
    
    create view view_dep_emp as
    select d.id,d.NAME dname,e.NAME ename from dep_table d inner join emp_tab e
    on d.id = e.dep_id 
    with read only
    
    select * from view_dep_emp
    
    --更改只读视图的数据(会导致系统报错)
    update view_dep_emp set ename = '火云邪神' where ename = '张无忌';
    select * from emp_tab;
    
    -- PL SQL
    declare
    name string(64);
    age int:=17;--初始化默认值
    
    BEGIN
       NAME:='白无瑕';
       age:=age+1;
       dbms_output.put_line('此人的名字是 '||name);
    END;
    
    --使用自定义符合类型%rowtype映射数据行
    select * from emp_tab;
    
    DECLARE
    
     row_emp emp_tab%ROWTYPE;
     id_ STRING(64):='NO003';
    BEGIN
      select * into row_emp from emp_tab where id = id_;
      dbms_output.put_line(row_emp.ID);
      dbms_output.put_line(row_emp.NAME);
      dbms_output.put_line(row_emp.address);
      dbms_output.put_line(row_emp.age);
    END;
    
    -- if 逻辑判断语句
    
    declare
       age int:=16;
       message string(64):='是成年人';
       message2 string(31):='是未成年人';
    begin
       if age >= 18 then
              dbms_output.put_line(message);
          else
              dbms_output.put_line(message2);
       end if;
    end; 
    
    -- if elsif 语句
    declare
       score number :=-2;
    begin
        if (score >= 0 and score <= 100) then
          if score>=90 then
            dbms_output.put_line('优秀');
            elsif score >=80 then
            dbms_output.put_line('良好');
            elsif score >=70 then
            dbms_output.put_line('中等');
            elsif score >=60 then
            dbms_output.put_line('及格');
            else
            dbms_output.put_line('不及格');
          end if;
        else
          dbms_output.put_line('成绩非法必须在0-100之间');
        end if;
    end;
    
    --case when 分支语句
    declare
       score number :=70;
    begin
        if (score >= 0 and score <= 100) then
           case
               when score>=90 then
               dbms_output.put_line('优秀★★★★★');
               when score>=80 then
               dbms_output.put_line('良好★★★★');
               when score>=70 then
               dbms_output.put_line('中等★★★');
               when score>=90 then
               dbms_output.put_line('及格★★');
               else
               dbms_output.put_line('不及格★');
           end case;
        else
          dbms_output.put_line('成绩非法必须在0-100之间');
        end if;
    end;
    
    -- PL SQL 循环
    --基本loop 循环
    --判断及统计1到100之间有多少个能被3整除的数
    declare
        num int:=1;
      counts int:=0;
    BEGIN
      LOOP
        if (num>100)then
          exit;--退出循环
        end if;
        if(num MOD 3 = 0)THEN
               counts:=counts+1;
               dbms_output.put_line(num);
        END IF;
        num:=num+1;
      END LOOP;
      dbms_output.put_line('1到100之间能够被3整除的数一共有 '||to_char(counts));
    END;
    
    --使用while循环完成1到100之间累加和的计算
    
    declare
    num INT:=1;
    sums int:=0;
    BEGIN
      while(num <=100) LOOP
                sums:=sums+num;--计算累加和
                num:=num+1;
      END LOOP;
      dbms_output.put_line('1到100之间整数的累加和是:'||to_char(sums));
    END;  
    
    --使用for循环计算1到100之间的偶数和
    
    DECLARE
    num INT:=1;
    sums INT:=0;
    
    BEGIN
         FOR i IN 1..100 LOOP
           if(num MOD 2=0)THEN
             sums:=sums+num;--统计偶数的累加和
           END IF;
             num:=num+1;--变量自增
         END LOOP;
         dbms_output.put_line('1到100之间所有偶数的累加和是 '||to_char(sums));
    END;

     

    --1 使用SQL语句建立关系型视图,视图数据来源于department和emp表,包含部门名称,员工姓名,地址,电话和邮箱号码;
    
    create or replace view view_department_emp as
    select d.name 部门名称,e.name 员工姓名,e.address 地址,e.phone 电话,e.email 邮箱号码
    from dept d inner join emp e on d.id = e.depid
    
    select * from view_department_emp;
    
    /*2 连接department和emp表和sales表创建关系型只读视图,要求包含,部门名称,员工姓名,产品代码,
    销售数量,销售单价,销售日期并未视图创建列别名*/
    
    create view view_dept_emp_sales as
    select d.name 部门名称,e.name 员工姓名,s.id 产品代码,s.salquantity 销售数量,s.price 销售单价,
    to_char(s.saldate,'yyyy-MM-dd') 销售日期
    from (dept d inner join emp e on d.id = e.depid)inner join sales s on s.eid = e.id
    with read only
    
    select * from view_dept_emp_sales
    
    /*1 定义一段PL SQL 块,声明2个值类型变量,分别用来存储销售部和研发部们员工数量,
    利用sql查询获取销售部和研发部们的员工数量并储存在2个变量中,对人数进行比较,
    最后在输出窗口显示2个部门的人数差,必需是正数;*/
    select * from emp;
    select * from dept;
    
    declare
    sales_department number;
    develop_department number;
    results number;
    BEGIN
      select count(DEPID) into sales_department from emp where depid = 'NO300';
      select count(DEPID) into develop_department from emp where depid = 'NO200';
      dbms_output.put_line('销售部人数 '||sales_department);
      dbms_output.put_line('研发部人数 '||develop_department);
      select abs(sales_department-develop_department) into results from dual;
      dbms_output.put_line('部门人数差 '||results);
    END;
    
    /*2 定义一段PL SQL 块,声明类型为number类型的变量用来存储emp表的某个id值;
    声明定义一个自定义%type类型的变量及描述用来封装存储department表部门名称,
    emp表员工姓名,emp表员工地址,emp表员工生日, inner join 内连接查询emp 和
    department表,限制条件时emp表id等于以上number类型的变量值,查询储department表部门名称,
    emp表员工姓名,emp表员工地址,emp表员工生日字段为自定义%type类型进行赋值,在输出窗口输出
    4个字段的获取后信息。*/
    
    declare 
     zengyu varchar2(64):='671';
     row_emp emp%ROWTYPE;
    BEGIN
      select * into row_emp from emp where id = zengyu;
      dbms_output.put_line(row_emp.id);
      dbms_output.put_line(row_emp.name);
      dbms_output.put_line(row_emp.address);
      dbms_output.put_line(to_char(row_emp.birth,'yyyy-mm-dd'));
    END;
    
    --1 利用循环语句完成在输出窗口打印九九乘法表;
    declare
        num_i number:=1;
        num_j number:=1;
    begin
      FOR num_i IN 1..9 LOOP
        FOR num_j IN 1..9 LOOP
        dbms_output.put_line(num_i||'x'||num_j||'='||num_i*num_j);
        END LOOP;
      END LOOP;
    end;
    
    --pl sql输出不换行
    declare
    
    i number(8):=0;       -- 定义循环所需的初始值
    a varchar2(1000):=''; -- 定义一个空字符串
    
    begin                 -- 开启循环
    loop
    i:=i+1;               -- 改变循环变量的值
    exit when i>100;      -- 退出循环条件
    a:=a||i||' ';         -- 拼接字符串
    end loop;
    
    dbms_output.put_line(a); -- 输出结果
    end;
    
    
    --网上参考答案
    --1 利用循环语句完成在输出窗口打印九九乘法表;
    
    BEGIN
           FOR i IN 1..9 LOOP
               FOR j IN 1..9 LOOP
               IF (j<=i) THEN
                  dbms_output.put(to_char(j)||'*'||to_char(i)||'='||to_char(i*j)||' ');
               END IF;
               END LOOP;
               dbms_output.new_line();
           END LOOP;
    END;
    
    
    
    --2 运用pl/sql语句块打印6*4矩形
    DECLARE
           a INT := 6;
           b INT := 4;
    BEGIN
         FOR i IN 1..a LOOP
             FOR j IN 1..b LOOP
                 IF(i=1 OR i=a) THEN
                     dbms_output.put('*');
                 ELSIF(j=1 OR j=b) THEN
                     dbms_output.put('*');
                 ELSE
                     dbms_output.put(' ');
                 END IF;
             END LOOP;
             dbms_output.new_line();
         END LOOP;
    END;
    
    
    
     
    
    --3 利用循环分别计算1-100之内的能被7整除和能被3整除数的累加和,并比较二者之间的差,打印输出差的正数值。
    DECLARE
           sums7 INT := 0;
           sums3 INT := 0;
           num INT := 1;
           differences INT := 0;
    BEGIN
           WHILE(num<=100) LOOP
                IF(num MOD 3 = 0) THEN
                   sums3 := sums3+num;
                ELSIF(num MOD 7 = 0) THEN
                   sums7 := sums7+num;
                END IF;
                num := num + 1;
           END LOOP;
           dbms_output.put_line('能被3整除的数的累加和是 '||to_char(sums3));
           dbms_output.put_line('能被7整除的数的累加和是 '||to_char(sums7));
           differences := abs(sums3-sums7);
           dbms_output.put_line('两数之差是 '||to_char(differences));
    END;

     

  • 相关阅读:
    C++的几个晦涩特性
    高效学习的工具Mnemosyne
    允许OSQA上传任意类型的文件
    新一代J2ME终端标准MSAfor CLDC——解读JSR248
    JAVA实现简单的HTTP服务器
    什么是Web 2.0
    Java 手机与空间制图服务(WMS)应用集成
    广西移动SP结算工作管理流程
    2007年Enterprise 2.0的10大趋势
    移动虚拟专用网的发展与未来应用
  • 原文地址:https://www.cnblogs.com/zengyu1234/p/15345068.html
Copyright © 2011-2022 走看看