oracle-02plsql

Love The Way You Lie 2022-04-08 14:41 250阅读 0赞

pl/sql编程——过程、函数、包

1.注释

单行注释 —

select * from emp where empno=7788; —取得员工信息

多行注释 /*…*/来划分

2.标志符号的命名规范

1).当定义变量时,建议用v_作为前缀v_sal

2).当定义常量时,建议用c_作为前缀c_rate

3).当定义游标时,建议用_cursor作为后缀emp_cursor

4).当定义例外时,建议用e_作为前缀e_error

3.块结构示意图

pl/sql块由三个部分构成:定义部分,执行部分,例外处理部分。

如下所示:

declare

/*定义部分——定义常量、变量、游标、例外、复杂数据类型*/

begin

/*执行部分——要执行的pl/sql语句和sql语句*/

exception

/*例外处理部分——处理运行的各种错误*/

end;

定义部分是从declare开始的,该部分是可选的;

执行部分是从begin开始的,该部分是必须的,至少要写null,不能不写;

例外处理部分是从exception开始的,该部分是可选的。

& 表示要接收从控制台输入的变量。

4.过程

过程用于执行特定的操作,当建立过程时,既可以指定输入参数(in),也可以指定输出参数(out),

通过在过程中使用输入参数,可以将数据传递到执行部分;

通过使用输出参数,可以将执行部分的数据传递到应用环境。

在sqlplus中可以使用create procedure命令来建立过程。

--只有输入参数的存储过程

create or replace procedure proc01(eno number) —in 输入参数 out输出参数

as

begin

update emp set sal = sal+500 where empno = eno;

—-select sal into money from emp where empno=eno;

end proc01;

在oracle中调用存储过程:

第一种:call proc01(7654);

第二种:在plsql块中调用

SQL> begin

3 proc01(7654);

5 end;

6 /

--既有输入又有输出参数的存储过程

  1. create or replace procedure proc02(eno in number,money out number) is
  2. begin
  3. update emp set sal=sal+1000 where empno=eno;
  4. select sal into money from emp where empno=eno;
  5. commit;
  6. exception
  7. rollback;
  8. end proc02;

在oracle中调用存储过程:

SQL> set serveroutput on;

SQL> declare money number;

2 begin

3 proc02(7654,money);

4 dbms_output.put_line(money);

5 end;

6 /

5.JAVA中调用存储过程

  1. Java代码
  1. CallableStatement cs = con.prepareCall(“{call emp_pro(?,?)}“);

  2. //4.给?赋值

  3. cs.setString(1,”SMITH”);

  4. cs.setInt(2,10);

  5. //5.执行

  6. cs.execute();

6.函数

函数用于返回特定的数据,当建立函数时,在函数头部必须包含return子句。

而在函数体内必须包含return语句返回的数据。我们可以使用create function来建立函数,实际案例:

Sql代码

  1. —编写函数 返回指定人员的年薪

  2. create function annual_income(name varchar2)

  3. return number is

  4. annual_salary number(7, 2);

  5. begin

  6. select sal*12 + nvl(comm, 0) into annual_salary from emp where ename = name;

  7. return annual_salary;

  8. end;

在sqlplus中调用函数

Sql代码

  1. SQL> var income number

  2. SQL> call annual_incomec(‘scott’) into :income; —注意:和income之间不能有空白

  3. SQL> print income

同样我们可以在java程序中调用该函数 select annual_income(‘SCOTT’) from dual;

7.包

包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成。

1).我们可以使用create package命令来创建包。

Sql代码

  1. —使用create package命令创建包

  2. create package pkg_sal is

  3. procedure update_sal(name varchar2, new_sal number);

  4. function annual_income(name varchar2) return number;

  5. end;

包的规范只包含了过程和函数的说明,但是没有过程和函数的实现代码。包体用于实现包规范中的过程和函数。

2).建立包体可以使用create package body命令

Sql代码

  1. —使用create package body创建包体

    create or replace package body pkg_sal is

    1. procedure update_sal(name varchar2, new_sal number) is
    2. begin
    3. update emp set sal = new_sal where ename = name;
    4. end;

    function annual_income(name varchar2) return number is

    1. income number(7, 2);
    2. begin
    3. select sal*12 + nvl(comm, 0) into income from emp where ename = name;
    4. return income;
    5. end;

    end;

3).如何调用包的过程或是函数

当调用包的过程或是函数时,在过程和函数前需要带有包名,如果要访问其它方案的包,还需要在包名前加方案名。

Example

Creating a Package: Example

  1. CREATE OR REPLACE PACKAGE emp_mgmt AS
  2. FUNCTION hire (last_name VARCHAR2, job_id VARCHAR2,
  3. manager_id NUMBER, salary NUMBER,
  4. commission_pct NUMBER, department_id NUMBER)
  5. RETURN NUMBER;
  6. FUNCTION create_dept(department_id NUMBER, location_id NUMBER)
  7. RETURN NUMBER;
  8. PROCEDURE remove_emp(employee_id NUMBER);
  9. PROCEDURE remove_dept(department_id NUMBER);
  10. PROCEDURE increase_sal(employee_id NUMBER, salary_incr NUMBER);
  11. PROCEDURE increase_comm(employee_id NUMBER, comm_incr NUMBER);
  12. no_comm EXCEPTION;
  13. no_sal EXCEPTION;
  14. END emp_mgmt;

Creating a Package Body: Example

  1. CREATE OR REPLACE PACKAGE BODY emp_mgmt AS
  2. tot_emps NUMBER;
  3. tot_depts NUMBER;
  4. FUNCTION hire
  5. (last_name VARCHAR2, job_id VARCHAR2,
  6. manager_id NUMBER, salary NUMBER,
  7. commission_pct NUMBER, department_id NUMBER)
  8. RETURN NUMBER IS new_empno NUMBER;
  9. BEGIN
  10. SELECT employees_seq.NEXTVAL
  11. INTO new_empno
  12. FROM DUAL;
  13. INSERT INTO employees
  14. VALUES (new_empno, 'First', 'Last','first.example@oracle.com',
  15. '(415)555-0100','18-JUN-02','IT_PROG',90000000,00,
  16. 100,110);
  17. tot_emps := tot_emps + 1;
  18. RETURN(new_empno);
  19. END;
  20. FUNCTION create_dept(department_id NUMBER, location_id NUMBER)
  21. RETURN NUMBER IS
  22. new_deptno NUMBER;
  23. BEGIN
  24. SELECT departments_seq.NEXTVAL
  25. INTO new_deptno
  26. FROM dual;
  27. INSERT INTO departments
  28. VALUES (new_deptno, 'department name', 100, 1700);
  29. tot_depts := tot_depts + 1;
  30. RETURN(new_deptno);
  31. END;
  32. PROCEDURE remove_emp (employee_id NUMBER) IS
  33. BEGIN
  34. DELETE FROM employees
  35. WHERE employees.employee_id = remove_emp.employee_id;
  36. tot_emps := tot_emps - 1;
  37. END;
  38. PROCEDURE remove_dept(department_id NUMBER) IS
  39. BEGIN
  40. DELETE FROM departments
  41. WHERE departments.department_id = remove_dept.department_id;
  42. tot_depts := tot_depts - 1;
  43. SELECT COUNT(*) INTO tot_emps FROM employees;
  44. END;
  45. PROCEDURE increase_sal(employee_id NUMBER, salary_incr NUMBER) IS
  46. curr_sal NUMBER;
  47. BEGIN
  48. SELECT salary INTO curr_sal FROM employees
  49. WHERE employees.employee_id = increase_sal.employee_id;
  50. IF curr_sal IS NULL
  51. THEN RAISE no_sal;
  52. ELSE
  53. UPDATE employees
  54. SET salary = salary + salary_incr
  55. WHERE employee_id = employee_id;
  56. END IF;
  57. END;
  58. PROCEDURE increase_comm(employee_id NUMBER, comm_incr NUMBER) IS
  59. curr_comm NUMBER;
  60. BEGIN
  61. SELECT commission_pct
  62. INTO curr_comm
  63. FROM employees
  64. WHERE employees.employee_id = increase_comm.employee_id;
  65. IF curr_comm IS NULL
  66. THEN RAISE no_comm;
  67. ELSE
  68. UPDATE employees
  69. SET commission_pct = commission_pct + comm_incr;
  70. END IF;
  71. END;
  72. END emp_mgmt;
  73. DROP TABLE accounts; -- in case it exists
  74. CREATE TABLE accounts (
  75. acctno INTEGER,
  76. balance NUMBER
  77. );
  78. INSERT INTO accounts (acctno, balance)
  79. VALUES (12345, 1000.00);
  80. CREATE OR REPLACE PACKAGE finance AS
  81. FUNCTION compound_ (
  82. years IN NUMBER,
  83. amount IN NUMBER,
  84. rate IN NUMBER
  85. ) RETURN NUMBER;
  86. PRAGMA RESTRICT_REFERENCES (compound_, WNDS, WNPS, RNDS, RNPS);
  87. END finance;

/

  1. CREATE PACKAGE BODY finance AS
  2. FUNCTION compound_ (
  3. years IN NUMBER,
  4. amount IN NUMBER,
  5. rate IN NUMBER
  6. ) RETURN NUMBER
  7. IS
  8. BEGIN
  9. RETURN amount * POWER((rate / 100) + 1, years);
  10. END compound_;
  11. -- No pragma in package body
  12. END finance;

/

  1. DECLARE
  2. interest NUMBER;
  3. BEGIN
  4. SELECT finance.compound_(5, 1000, 6)
  5. INTO interest
  6. FROM accounts
  7. WHERE acctno = 12345;
  8. END;

/

  1. CREATE OR REPLACE PACKAGE p IS
  2. PROCEDURE java_sleep (milli_seconds IN NUMBER)
  3. AS LANGUAGE JAVA NAME 'java.lang.Thread.sleep(long)';
  4. PRAGMA RESTRICT_REFERENCES(java_sleep,WNDS,TRUST);
  5. FUNCTION f (n NUMBER) RETURN NUMBER;
  6. END p;

/

  1. CREATE OR REPLACE PACKAGE BODY p IS
  2. FUNCTION f (
  3. n NUMBER
  4. ) RETURN NUMBER
  5. IS
  6. BEGIN
  7. java_sleep(n);
  8. RETURN n;
  9. END f;
  10. END p;

/

Example 6-22 PRAGMA RESTRICT REFERENCES with TRUST on Invoker

  1. CREATE OR REPLACE PACKAGE p IS
  2. PROCEDURE java_sleep (milli_seconds IN NUMBER)
  3. AS LANGUAGE JAVA NAME 'java.lang.Thread.sleep(long)';
  4. FUNCTION f (n NUMBER) RETURN NUMBER;
  5. PRAGMA RESTRICT_REFERENCES(f,WNDS,TRUST);
  6. END p;

/

  1. CREATE OR REPLACE PACKAGE BODY p IS
  2. FUNCTION f (
  3. n NUMBER
  4. ) RETURN NUMBER
  5. IS
  6. BEGIN
  7. java_sleep(n);
  8. RETURN n;
  9. END f;
  10. END p;

发表评论

表情:
评论列表 (有 0 条评论,250人围观)

还没有评论,来说两句吧...

相关阅读