plsql procedure

1.CREATE OR REPLACE PROCEDURE discount AS
    CURSOR c_group_discount IS
        SELECT DISTINCT s.course_no, c.description
          FROM section s, enrollment e, course c
         WHERE s.section_id = e.section_id
           AND c.course_no = s.course_no
         GROUP BY s.course_no, c.description, e.section_id, s.section_id
        HAVING COUNT(*) >= 8;
BEGIN
    FOR r_group_discount IN c_group_discount
    LOOP
        UPDATE course
           SET cost = cost * 0.95
         WHERE course_no = r_group_discount.course_no;
        dbms_output.put_line('A 5% discount has been given to ' ||
                             r_group_discount.course_no || ' ' ||
                             r_group_discount.description);
    END LOOP;
END;

查询过程状态:

SQL> select object_name,object_type,status from user_objects where object_name='DISCOUNT';

OBJECT_NAME OBJECT_TYPE STATUS
--------------- --------------- -------
DISCOUNT PROCEDURE VALID

查询该过程的源代码:

SQL> col text for a70
SQL> select to_char(line,99)||'>',text from user_source where name='DISCOUNT';

TO_C TEXT
---- ----------------------------------------------------------------------
  1> PROCEDURE discount AS
  2> CURSOR c_group_discount IS
  3>     SELECT DISTINCT s.course_no, c.description
  4>       FROM section s, enrollment e, course c
  5>      WHERE s.section_id = e.section_id
  6> AND c.course_no = s.course_no
  7>      GROUP BY s.course_no, c.description, e.section_id, s.section_
     id


  8>     HAVING COUNT(*) >= 8;
  9> BEGIN


TO_C TEXT
---- ----------------------------------------------------------------------
 10> FOR r_group_discount IN c_group_discount
 11> LOOP
 12>     UPDATE course
 13> SET cost = cost * 0.95
 14>      WHERE course_no = r_group_discount.course_no;
 15>     dbms_output.put_line('A 5% discount has been given to ' ||
 16>  r_group_discount.course_no || ' ' ||
 17>  r_group_discount.description);
 18> END LOOP;
 19> END;
19 rows selected.

编译过程:

SQL> alter procedure discount compile;
Procedure altered.

测试以上过程:

SQL> set serveroutput on;
SQL> execute discount;
A 5% discount has been given to 120 Intro to Java Programming
A 5% discount has been given to 140 Systems Analysis
A 5% discount has been given to 230 Intro to the Internet
A 5% discount has been given to 25 Intro to Programming
A 5% discount has been given to 122 Intermediate Java Programming
A 5% discount has been given to 240 Intro to the BASIC Language
PL/SQL procedure successfully completed.

2.过程传人和传出参数:

CREATE OR REPLACE PROCEDURE find_sname(i_student_id IN NUMBER,
                                       o_first_name OUT VARCHAR2,
                                       o_last_name  OUT VARCHAR2) AS
BEGIN
    SELECT first_name, last_name
      INTO o_first_name, o_last_name
      FROM student
     WHERE student_id = i_student_id;
EXCEPTION
    WHEN OTHERS THEN
        dbms_output.put_line('Error in finding student_id: ' ||
                             i_student_id);
END find_sname;

测试以上过程:

DECLARE
    v_local_first_name student.first_name%TYPE;
    v_local_last_name  student.last_name%TYPE;
BEGIN
    find_sname(145, v_local_first_name, v_local_last_name);
    dbms_output.put_line('Student 145 is: ' || v_local_first_name || ' ' ||
                         v_local_last_name || '.');
END;

练习部分:

1.编写一个没有参数的过程。该过程能够告知当天是周六,还是周日。除此之外,还应该告知用户名和当前时间。还应该显示数据库中有多少有效和无效过程。

CREATE OR REPLACE PROCEDURE current_status AS
    v_day_type CHAR(1);
    v_user     VARCHAR2(30);
    v_valid    NUMBER;
    v_invalid  NUMBER;
BEGIN
    SELECT substr(to_char(SYSDATE, 'DAY'), 0, 1) INTO v_day_type FROM dual;
    IF v_day_type = 'S'
    THEN
        dbms_output.put_line('Today is a weekend.');
    ELSE
        dbms_output.put_line('Today is a weekday.');
    END IF;
    --***************
    dbms_output.put_line('The time is: ' || to_char(SYSDATE, 'HH:MI AM'));
    --****************
    SELECT USER INTO v_user FROM dual;
    dbms_output.put_line('The current user is ' || v_user);
    --**********************
    SELECT nvl(COUNT(*), 0)
      INTO v_valid
      FROM user_objects
     WHERE status = 'VALID'
       AND object_type = 'PROCEDURE';
    dbms_output.put_line('There are ' || v_valid || ' valid procedure.');
    --********************
    SELECT nvl(COUNT(*), 0)
      INTO v_invalid
      FROM user_objects
     WHERE status = 'INVALID'
       AND object_type = 'PROCEDURE';
    dbms_output.put_line('There are ' || v_invalid ||
                         ' invalid procedure.');
END;

QL> execute current_status;
Today is a weekend.
The time is: 10:58 AM
The current user is SYS
There are 123 valid procedure.
There are 2 invalid procedure.
PL/SQL procedure successfully completed.

2.编写一个过程:传人参数是邮政编码,城市和州,并且把这些信息插入到ZIPCODE表中。该过程已经检查所提供的邮政编码是否已经存在于数据库中。如果已经存在,则抛出一个异常,并显示一个错误信息。编写一个匿名语句块,使用这个过程来插入邮政编码记录。

CREATE OR REPLACE PROCEDURE insert_zip(i_zipcode IN zipcode.zip%TYPE,
                                       i_city    IN zipcode.city%TYPE,
                                       i_state   IN zipcode.state%TYPE) AS
    v_zipcode zipcode.zip%TYPE;
    v_city    zipcode.city%TYPE;
    v_state   zipcode.state%TYPE;
    v_dummy   zipcode.zip%TYPE;
BEGIN
    v_zipcode := i_zipcode;
    v_city    := i_city;
    v_state   := i_state;
    SELECT zip INTO v_dummy FROM zipcode WHERE zip = v_zipcode;
    --
    dbms_output.put_line('The zipcode ' || v_zipcode ||
                         ' is already in the database and cannot be' ||
                         ' reinserted.');
EXCEPTION
    WHEN no_data_found THEN
        INSERT INTO zipcode
        VALUES
            (v_zipcode, v_city, v_state, USER, SYSDATE, USER, SYSDATE);
    WHEN OTHERS THEN
        dbms_output.put_line('There was an unknown error ' ||
                             ' in insert_zip.');
END;

3.动态sql:

CREATE OR REPLACE PROCEDURE get_name_address(table_name_in  IN VARCHAR2,
                                             id_in          IN NUMBER,
                                             first_name_out OUT VARCHAR2,
                                             last_name_out  OUT VARCHAR2,
                                             street_out     OUT VARCHAR2,
                                             city_out       OUT VARCHAR2,
                                             state_out      OUT VARCHAR2,
                                             zip_out        OUT VARCHAR2) AS
    sql_stmt VARCHAR2(2000);
BEGIN
    sql_stmt := 'select a.first_name,a.last_name,a.street_address' ||
                ' ,b.city,b.state,b.zip' || ' from
' || table_name_in || ' a,zipcode b' ||
                ' where a.zip=b.zip' || ' and ' || table_name_in ||
                '_id=:1';
    --dbms_output.put_line(sql_stmt);
    EXECUTE IMMEDIATE sql_stmt
        INTO first_name_out, last_name_out, street_out, city_out, state_out, zip_out
        USING id_in;
END get_name_address;

测试上述过程:

DECLARE
    v_table_name VARCHAR2(20) := '&sv_table_name';
    v_id         NUMBER := &sv_id;
    v_first_name VARCHAR2(25);
    v_last_name  VARCHAR2(25);
    v_street     VARCHAR2(50);
    v_city       VARCHAR2(25);
    v_state      VARCHAR2(2);
    v_zip        VARCHAR2(5);
BEGIN
    get_name_address(v_table_name,
                     v_id,
                     v_first_name,
                     v_last_name,
                     v_street,
                     v_city,
                     v_state,
                     v_zip);
    dbms_output.put_line('First Name: ' || v_first_name);
    dbms_output.put_line('Last_name: ' || v_last_name);
    dbms_output.put_line('Street: ' || v_street);
    dbms_output.put_line('City: ' || v_city);
    dbms_output.put_line('State: ' || v_state);
    dbms_output.put_line('Zip Code: ' || v_zip);
   END;
   /
Enter value for sv_table_name: student
old   2:     v_table_name VARCHAR2(20) := '&sv_table_name';
new   2:     v_table_name VARCHAR2(20) := 'student';
Enter value for sv_id: 105
old   3:     v_id  NUMBER := &sv_id;
new   3:     v_id  NUMBER := 105;
First Name: Angel
Last_name: Moskowitz
Street: 320 John St.
City: Ft. Lee
State: NJ
Zip Code: 07024
PL/SQL procedure successfully completed.

修改以上过程,返回一个用户自定义的记录(创建一个包):

CREATE OR REPLACE PACKAGE dynamic_sql_pkg AS
    --create user defined record type
    TYPE name_addr_rec_type IS RECORD(
        first_name VARCHAR2(25),
        last_name  VARCHAR2(25),
        street     VARCHAR2(50),
        city       VARCHAR2(25),
        state      VARCHAR2(2),
        zip        VARCHAR2(5));
    PROCEDURE get_name_address(table_name_in IN VARCHAR2,
                               id_in         IN NUMBER,
                               name_addr_rec OUT name_addr_rec_type);
END dynamic_sql_pkg;


CREATE OR REPLACE PACKAGE BODY dynamic_sql_pkg AS
    PROCEDURE get_name_address(table_name_in IN VARCHAR2,
                               id_in         IN NUMBER,
                               name_addr_rec OUT name_addr_rec_type) IS
        sql_stmt VARCHAR2(2000);
    BEGIN
        sql_stmt := 'select a.first_name,a.last_name,a.street_address' ||
                    ' ,b.city,b.state,b.zip' || ' from
' || table_name_in || ' a,zipcode b' ||
                    ' where a.zip=b.zip' || ' and ' || table_name_in ||
                    '_id=:1';
        EXECUTE IMMEDIATE sql_stmt
            INTO name_addr_rec
            USING id_in;
    END get_name_address;
END dynamic_sql_pkg;

测试包可用性:

DECLARE
    v_table_name  VARCHAR2(20) := '&sv_table_name';
    v_id          NUMBER := &sv_id;
    name_addr_rec dynamic_sql_pkg.name_addr_rec_type;
BEGIN
    dynamic_sql_pkg.get_name_address(v_table_name, v_id, name_addr_rec);
    dbms_output.put_line('First Name: ' || name_addr_rec.first_name);
    dbms_output.put_line('Last Name: ' || name_addr_rec.last_name);
    dbms_output.put_line('Street: ' || name_addr_rec.street);
    dbms_output.put_line('City: ' || name_addr_rec.city);
    dbms_output.put_line('State: ' || name_addr_rec.state);
    dbms_output.put_line('Zip Code: ' || name_addr_rec.zip);
END;
 /
Enter value for sv_table_name: student
old   2:     v_table_name  VARCHAR2(20) := '&sv_table_name';
new   2:     v_table_name  VARCHAR2(20) := 'student';
Enter value for sv_id: 105
old   3:     v_id   NUMBER := &sv_id;
new   3:     v_id   NUMBER := 105;
First Name: Angel
Last Name: Moskowitz
Street: 320 John St.
City: Ft. Lee
State: NJ
Zip Code: 07024
PL/SQL procedure successfully completed、

5.CREATE OR REPLACE PROCEDURE add_contact(member_id        NUMBER,

                                        contact_type     NUMBER,
                                        last_name        VARCHAR2,
                                        first_name       VARCHAR2,
                                        middle_name      VARCHAR2 := NULL,
                                        address_type     NUMBER := NULL,
                                        street_address   street_address_table := street_address_table(),
                                        city             VARCHAR2 := NULL,
                                        state_province   VARCHAR2 := NULL,
                                        postal_code      VARCHAR2 := NULL,
                                        country_code     VARCHAR2 := NULL,
                                        telephone_type   NUMBER := NULL,
                                        area_code        VARCHAR2 := NULL,
                                        telephone_number VARCHAR2 := NULL,
                                        created_by       NUMBER,
                                        creation_date    DATE := SYSDATE,
                                        last_updated_by  NUMBER,
                                        last_update_date DATE := SYSDATE) IS
    lv_address_id NUMBER;
BEGIN
    SAVEPOINT add_contact;
    INSERT INTO contact
    VALUES
        (contact_s1.nextval,
         member_id,
         contact_type,
         first_name,
         middle_name,
         last_name,
         created_by,
         creation_date,
         last_updated_by,
         last_update_date);
    IF address_type IS NOT NULL
       AND city IS NOT NULL
       AND state_province IS NOT NULL
       AND postal_code IS NOT NULL
    THEN
        INSERT INTO address
        VALUES
            (address_s1.nextval,
             contact_s1.currval,
             address_type,
             city,
             state_province,
             postal_code,
             created_by,
             creation_date,
             last_updated_by,
             last_update_date);
        lv_address_id := address_s1.currval;
        IF street_address.count > 0
        THEN
            FOR i IN 1 .. street_address.count
            LOOP
                INSERT INTO street_address
                VALUES
                    (street_address_s1.nextval,
                     lv_address_id,
                     street_address(i),
                     created_by,
                     creation_date,
                     last_updated_by,
                     last_update_date);
            END LOOP;
        END IF;
    END IF;
    IF telephone_type IS NOT NULL
       AND country_code IS NOT NULL
       AND area_code IS NOT NULL
       AND telephone_number IS NOT NULL
    THEN
        INSERT INTO telephone
        VALUES
            (telephone_s1.nextval,
             contact_s1.currval,
             lv_address_id,
             telephone_type,
             country_code,
             area_code,
             telephone_number,
             created_by,
             creation_date,
             last_updated_by,
             last_update_date);
    END IF;
    COMMIT;
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK TO add_contact;
        raise_application_error(-20001, SQLERRM);
END add_contact;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值