Oracle11G-SQL开发指南-11-PL/SQL编程

1.  块结构
    [DECLARE declaration_statements ]
    BEGIN
        executable_statements
    [EXCEPTION
        exception_handling_statements
    ]
    END;
   例1:
   DECLARE
     V_WIDTH  INTEGER;
     V_HEIGHT INTEGER := 3;
     V_ARE    INTEGER := 6;
   BEGIN
     V_WIDTH := V_ARE / V_HEIGHT;
     DBMS_OUTPUT.PUT_LINE('v_width=' || V_WIDTH);
   EXCEPTION
     WHEN ZERO_DIVIDE THEN
       DBMS_OUTPUT.PUT_LINE('报错了:Division by zero');
   END;


2.  变量和类型
    变量在DECLARE块中声明;
    声明时要同时包含名称和类型;
    v_id INTEGER;
    v_char VARCHAR2(50);
    v_type table_name.colmnt_name%TYPE;


3.  条件逻辑
    IF、THEN、ELSE、ELSEIF、ENDIF;


4.  循环
    a> 简单循环
        LOOP
            statements
        END LOOP;
结束循环要使用EXIT或EXIT WHEN语句
结束当前循环进行下一次循环可以使用CONTINUE或CONTINUE WHEN语句
    b> WHILE循环
        WHILE condition LOOP
   statements
END LOOP;


    c> FOR循环
        FOR loop_variable IN [REVERSE] lower_bound.. upper_bound LOOP
   statements
END LOOP;


5.  游标cursor
    a> 声明变量,用于存储记录的列值;
    b> 声明游标;
    c> 打开游标;
    d> 一次从游标中取出一个值来,并将列值存储在第1步声明的变量中,进行自定义的操作处理;
    e> 关闭游标;


6.  异常  exception 块中的内容
    EXCEPTION 
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('出现异常:Division by zero');
        ROLLBACK;
        RETURN;


7.  过程 : 一组SQL和pl/sql语句
    a> 创建过程
       CREATE [ OR REPLACE ] PROCEDURE pocedure_name
       [(parameter_name [IN | OUT | IN OUT ] type [, ...])]
       {IS | AS }
       BEGIN
         procedure_body
       END pocedure_name ;
    b> 调用过程:
       call pocedure_name (parameter_name => value);
    c> 获取过程信息 user_procedures 
    d> 删除过程  drop PROCEDURE pocedure_name ;
    e> 查看报错 show errors


8.  函数,与过程相似,就是多一个返回值
    a> 创建函数
       CREATE [ OR REPLACE ] FUNCTION function_name
       [(parameter_name [IN | OUT | IN OUT ] type [, ...])]
       RETURN type
       {IS | AS }
       BEGIN
         function_body
       END function_name ;
    b> 调用函数:与内置函数类似
    c> 获取函数信息 user_procedures 
    d> 删除过程  drop FUNCTION function_name ;


9.  包,把函数和过程组织在一起
    包由两部分组成:规范specification和包体body
    创建包规范:
    CREATE [OR REPLACE ] PACKAGE package_name
    {IS | AS}
        package_specification
    END package_name ;
    创建包体:
    CREATE [OR REPLACE ] PACKAGE BODY package_name
    {IS | AS}
        package_body
    END package_name;


10. 触发器
    CREATE [OR REPLACE] TRIGGER trigger_name
    {BEFORE | ALTER | INSTEAD OF | FOR } trigger_event
    ON table_name
    [FOR EACH ROW]
    [{FORWARD | REVERSE} CROSSEDITION ]
    [{FOLLOWS | PRECEDES} schema.other_trigger]
    [{ENABLE | DISABLE}]
    [WHEN trigger_condition ]
    BEGIN
        trigger_body;
    END trigger_name ;


创建时的is与as区别
是ORACLE为了方便而设置的同义词
在存储过程(PROCEDURE)和函数(FUNCTION)中没有区别;
在视图(VIEW)中只能用AS不能用IS;
在游标(CURSOR)中只能用IS不能用AS。


-------------------------------------------------------
-- 块  声明块,执行块,异常块 
  DECLARE
     V_WIDTH  INTEGER;
     V_HEIGHT INTEGER := 3;
     V_ARE    INTEGER := 6;
   BEGIN
     V_WIDTH := V_ARE / V_HEIGHT;
     DBMS_OUTPUT.PUT_LINE('v_width=' || V_WIDTH);
   EXCEPTION
     WHEN ZERO_DIVIDE THEN
       DBMS_OUTPUT.PUT_LINE('报错了:Division by zero');
     WHEN OTHERS THEN
       DBMS_OUTPUT.PUT_LINE('出现异常:Division by zero');
   END;


-------------------------------------------------------
 --简单循环 ,IF,EXIT WHEN
   DECLARE
      V_COUNT INTEGER := 0;
    BEGIN
      LOOP
        V_COUNT := V_COUNT + 1;
        IF V_COUNT = 3 THEN
          CONTINUE;
        END IF;
        DBMS_OUTPUT.PUT_LINE('当前值为:' || v_count);
        EXIT WHEN V_COUNT = 5;
      END LOOP;
    END;
-------------------------------------------------------
--简单循环,CONTINUE WHEN,EXIT WHEN
    DECLARE
      V_COUNT INTEGER := 0;
    BEGIN
      LOOP
        V_COUNT := V_COUNT + 1;
        CONTINUE WHEN v_count = 3 ;
        DBMS_OUTPUT.PUT_LINE('当前值为:' || v_count);
        EXIT WHEN V_COUNT = 5;
      END LOOP;
    END;
-------------------------------------------------------   
-- while 循环
    DECLARE
      V_COUNT INTEGER := 0;
    BEGIN
      WHILE V_COUNT < 6 LOOP
        V_COUNT := V_COUNT + 1;
        DBMS_OUTPUT.PUT_LINE('当前值为:' || V_COUNT);
      END LOOP;
    END;
-------------------------------------------------------
--for循环


    DECLARE
      V_COUNT INTEGER := 0;
    BEGIN
      FOR V_COUNT IN 1.. 6 LOOP      
        DBMS_OUTPUT.PUT_LINE('当前值为:' || V_COUNT);
      END LOOP;
    END;


-------------------------------------------------------
-- 游标示例1 完整过程
 
    DECLARE
      -- 1:声明变量
      V_PRODUCT_ID PRODUCTS.PRODUCT_ID%TYPE;
      V_NAME       PRODUCTS.NAME%TYPE;
      V_PRICE      PRODUCTS.PRICE%TYPE;
      -- 2:声明游标
      CURSOR V_PRODUCT_CURSOR IS
        SELECT PRODUCT_ID, NAME, PRICE FROM PRODUCTS ORDER BY PRODUCT_ID;
    
    BEGIN
      -- 3: 打开游标
      OPEN V_PRODUCT_CURSOR;
    
      LOOP
      -- 4: 从游标中取数据
        FETCH V_PRODUCT_CURSOR
          INTO V_PRODUCT_ID, V_NAME, V_PRICE;
        EXIT WHEN V_PRODUCT_CURSOR%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('id值为:' || V_PRODUCT_ID || 'name=:' || V_NAME);
      END LOOP;
      -- 5.关闭游标
      CLOSE V_PRODUCT_CURSOR;
    END;

-------------------------------------------------------
-- 游标示例2 : 结合for循环 不用显示打开和关闭游标
 
    DECLARE
      -- 1:声明变量
      -- 2:声明游标
      CURSOR V_PRODUCT_CURSOR IS
        SELECT PRODUCT_ID, NAME, PRICE FROM PRODUCTS ORDER BY PRODUCT_ID;
    
    BEGIN
      -- 3: 打开游标    
      FOR v_product IN V_PRODUCT_CURSOR LOOP
      -- 4: 从游标中取数据
        DBMS_OUTPUT.PUT_LINE('id值为:' ||v_product.PRODUCT_ID || 'name=:' || v_product.NAME);
      END LOOP;
      -- 5.关闭游标
    END;
 


-------------------------------------------------------
-- 游标示例3 :ref cursor游标 结合open-for语句 灵活使用游标
-- 动态关联结果集的临时对象。即在运行的时候动态决定执行查询。
    
    DECLARE
      -- 1:声明变量
      -- 2:声明游标
      TYPE T_PRODUCT_CURSOR IS REF CURSOR RETURN PRODUCTS%ROWTYPE;
      V_PRODUCT_CURSOR T_PRODUCT_CURSOR;
      V_PRODUCT        PRODUCTS%ROWTYPE;
    
    BEGIN
      -- 3: 打开游标    
      OPEN V_PRODUCT_CURSOR FOR
        SELECT * FROM PRODUCTS WHERE PRODUCT_ID < 5;
      LOOP
        FETCH V_PRODUCT_CURSOR INTO V_PRODUCT;
        EXIT WHEN V_PRODUCT_CURSOR%NOTFOUND;
        -- 4: 从游标中取数据
        DBMS_OUTPUT.PUT_LINE('id值为:'|| V_PRODUCT.PRODUCT_ID || 'name=:'||V_PRODUCT.NAME);
      END LOOP;
      -- 5.关闭游标
      CLOSE V_PRODUCT_CURSOR;
    END;


-------------------------------------------------------
-- 游标示例4  无约束游标


    DECLARE
      TYPE T_CURSOR IS REF CURSOR;  --先定义动态游标
      V_CURSOR   T_CURSOR;
      V_PRODUCT  PRODUCTS%ROWTYPE;
      V_CUSTOMER CUSTOMERS%ROWTYPE;
      
    BEGIN
      OPEN V_CURSOR FOR
        SELECT * FROM PRODUCTS WHERE PRODUCT_ID < 5 ;
      LOOP
        FETCH V_CURSOR  INTO V_PRODUCT;   -- 第一次动态使用
        EXIT WHEN V_CURSOR%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('id值为:' || V_PRODUCT.PRODUCT_ID || 'name=:' || V_PRODUCT.NAME);
      END LOOP;


      OPEN V_CURSOR FOR
        SELECT * FROM CUSTOMERS WHERE CUSTOMER_ID <3 ;
      LOOP
        FETCH V_CURSOR INTO V_CUSTOMER;  -- 第二次动态使用
        EXIT WHEN V_CURSOR%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('id值为:' || V_CUSTOMER.customer_ID || 'name=:' || V_CUSTOMER.first_name);
      END LOOP;
      EXCEPTION 
        WHEN OTHERS THEN
         DBMS_OUTPUT.PUT_LINE('出现异常:Division by zero');
      
      CLOSE V_CURSOR;
    END;
        
-------------------------------------------------------
-- 过程


CREATE OR REPLACE PROCEDURE update_product_price(
  p_product_id IN products.product_id%TYPE,
  p_factor     IN NUMBER
) AS
  v_product_count INTEGER;
BEGIN
  -- count the number of products with the
  -- supplied product_id (will be 1 if the product exists)
  SELECT COUNT(*)
  INTO v_product_count
  FROM products
  WHERE product_id = p_product_id;


  -- if the product exists (v_product_count = 1) then
  -- update that product's price
  IF v_product_count = 1 THEN
    UPDATE products
    SET price = price * p_factor
    WHERE product_id = p_product_id;
    COMMIT;
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
END update_product_price;

-------------------------------------------------------
-- 函数1
CREATE OR REPLACE FUNCTION circle_area (
  p_radius IN NUMBER
) RETURN NUMBER AS
  v_pi   NUMBER := 3.1415926;
  v_area NUMBER;
BEGIN
  -- circle area is pi multiplied by the radius squared
  v_area := v_pi * POWER(p_radius, 2);
  RETURN v_area;
END circle_area;


-- 函数2
CREATE OR REPLACE FUNCTION average_product_price (
  p_product_type_id IN INTEGER
) RETURN NUMBER AS
  v_average_product_price NUMBER;
BEGIN
  SELECT AVG(price)
  INTO v_average_product_price
  FROM products
  WHERE product_type_id = p_product_type_id;
  RETURN v_average_product_price;
END average_product_price;


-------------------------------------------------------
-- 包
CREATE OR REPLACE PACKAGE product_package AS
  TYPE t_ref_cursor IS REF CURSOR;
  FUNCTION get_products_ref_cursor RETURN t_ref_cursor;
  PROCEDURE update_product_price (
    p_product_id IN products.product_id%TYPE,
    p_factor     IN NUMBER
  );
END product_package;


-------------------------------------------------------
-- 触发器
CREATE OR REPLACE TRIGGER before_product_price_update
BEFORE UPDATE OF price
ON products
FOR EACH ROW 
when (new.price < old.price * 0.75)
BEGIN
  dbms_output.put_line('product_id = ' || :old.product_id);
  dbms_output.put_line('Old price = ' || :old.price);
  dbms_output.put_line('New price = ' || :new.price);
  dbms_output.put_line('The price reduction is more than 25%');


  -- insert row into the product_price_audit table
  INSERT INTO product_price_audit (
    product_id, old_price, new_price
  ) VALUES (
    :old.product_id, :old.price, :new.price
  );
END before_product_price_update;



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容简介   本书是专门为oracle应用开发人员提供的sqlpl/sql编程指南。通过学习本书,读者不仅可以掌握oracle常用工具oracle universal installer、net comfiguration assistant、sql developer、sql*plus的作用及使用方法,而且可以掌握sql语句和pl/sql的各种基础知识和高级特征(记录类型、集合类型、对象类型、大对象类型)。   除了为读者提供编sql语句和开发pl/sql块的方法外,本书还为应用开发人员提供了一些常用的pl/sql系统包。通过使用这些pl/sql系统包,应用开发人员可以开发出功能更强大的数据库应用程序。本书不仅适合sqlpl/sql初学者,也适合于有经验的oracle应用开发人员。 前言 第一部分 sqlpl/sql相关工具  第1章 在windows 平台上安装oracle database 11g  第2章 配置网络服务名  第3章 使用sql database  第4章 使用sql*plus 第二部分 sql  第5章 sqlpl/sql综述  第6章 简单查询  第7章 sql单行函数  第8章 操纵数据  第9章 复杂查询  第10章 管理常用对象 第三部分 pl/sql  第11pl/sql基础  第12章 访问oracle  第13章 编控制结构  第14章 使用复合数据类型  第15章 使用游标  第16章 异常处理 . 第17章 本地动态sql  第18章 pl/sql过程  第19章 pl/sql函数  第20章 pl/sql包  第21章 触发器  第22章 使用对象类型 第四部分 pl/sql系统包  第23章 使用大对象  第24章 读os文件  第25章 开发多媒体应用  第26章 开发web应用  第27章 dbms_sq动态sql  第28章 管理统计  第29章 使用数据库资源管理器  第30章 数据加密和解密  第31章 使用调度程序  第32章 使用flashback  第33章 使用重定义联机表  第34章 修正损坏块  第35章 使用日里民挖掘  第36章 使用管道  第37章 使用精细访问控制  第38章 使用精细审计  第39章 使用预警事件  第40章 转换rowid  第41章 其他常用包 习题答案
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值