GRANT debug any procedure, debug connect session TO scott;
sqlplus scott/tiger
PL/SQL块最大优点:降低网络开销,提高应用程序性能。
procedure语法:
create or replace procedure procedure_name
(argu1 [in|out] datatype,argu2 datatype...)
is [as]
PL/SQL Block;
procedure_name:存储过程名称
argu1,argu2...:参数名称,可以指定输入参数(IN),也可以指定输出参数(OUT),也可以指定输入输出参数(IN OUT)
datatype:参数数据类型,不能指定长度。
is [as]:开始一个PL/SQL块
---输出当前系统日期和时间的过程
create or replace procedure pro_output_time
is
begin
dbms_output.put_line(systimestamp);
end;
set serveroutput on
调试:
方法一
call pro_output_time();
fangfaer
exec pro_output_time()
方法三
sql>
begin
pro_output_time();
end;
/
获取雇员7788的姓名
create or replace procedure pro_emp_ename(v_empno number )
is
v_ename emp.ename%type;
begin
select ename into v_ename from emp where empno=v_empno;
dbms_output.put_line('ename: '||v_ename);
end;
call pro_emp_ename(7788);
begin
pro_emp_ename(7788);
end;
--在emp表中增加雇员,雇员标号重复,部门不存在时抛出异常,
方法一:
//raise_application_error函数
create or replace procedure pro_add_emp(v_empno number,v_ename varchar2,v_sal number,v_deptno number,v_job varchar2 default 'CLERk')
is
no_deptno exception;
pragma exception_init(no_deptno,-2291);
begin
insert into emp(empno,ename,sal,deptno,job)
values (v_empno,v_ename,v_sal,v_deptno,v_job);
commit;
exception
when dup_val_on_index then
raise_application_error(-20001,'empno is extists');
when no_deptno then
raise_application_error(-20002,'deptno is not extist');
end;
方法二:
//sqlcode sqlerrm 方法插入错误表errors
create table errors(error_id number,program_name varchar2(50),error_code number,error_message varchar2(100),create_date date default sysdate,constraint pk_error primary key(error_id));
create sequence seq_errors
minvalue 1
maxvalue 999999999999999999
start with 1
increment by 1
cache 20;
create or replace procedure pro_add_emp1(v_empno number,v_ename varchar2,
v_sal number,v_deptno number,v_job varchar2 default 'CLERK')
is
v_error_code number;
v_error_message varchar2(100);
begin
insert into emp(empno,ename,sal,deptno,job)
values (v_empno,v_ename,v_sal,v_deptno,v_job);
commit;
exception
when dup_val_on_index then
raise_application_error(-20002,'empno is duplicat.');
when others then
v_error_code:=sqlcode;
v_error_message:=substr(sqlerrm,1,100);
insert into errors(error_id,program_name,error_code ,error_message)
values(seq_errors.nextval,'pro_add_emp',v_error_code,v_error_message);
end;
---根据员工号查询员工名和薪水,如果员工号不存在抛出异常员工号不存在
create or replace procedure pro_output_emp(v_empno number,v_ename out varchar2,v_sal out number)
is
e_no_empno exception;
begin
select ename,sal into v_ename,v_sal from emp where empno=v_empno;
if sql%notfound then
raise e_no_empno;
end if;
exception
when e_no_empno then
dbms_output.put_line('empno is not exists');
end;
ORDERS表字段为order_id, order_date, customer_id, ship_date, total;数据来自oe.orders,主键为order_id
CUSTOMERS表字段为customer_id, cust_first_name, cust_last_name, date_of_birth, marital_status, cust_email,city_name数据来自oe.customers,主键为customer_id
ORDERS表与CUSTOMERS为多对1关系,需要用建立朱外键约束关系。
分析:因为orders外键依赖于customers的主键所以建表和插入数据时以customers为先
//创建customers表
create table customers
(CUSTOMER_ID NUMBER(6) NOT NULL primary key ,
CUST_FIRST_NAME VARCHAR2(20) NOT NULL,
CUST_LAST_NAME VARCHAR2(20) NOT NULL ,
DATE_OF_BIRTH date ,
MARITAL_STATUS VARCHAR2(20),
CUST_EMAIL VARCHAR2(30),
city_name varchar2(50) default 'luoyang');
//创建orders表
create table orders
(order_id number(12) not null,
order_date date ,
customer_id number(6) not null ,
ship_date date not null ,
total number(8,2),
constraint pk_order_id primary key(order_id),
constraint fk_customer_id foreign key(customer_id) REFERENCES customers(customer_id));
grant dba to scott;
//向customers中插入数据
insert into customers(CUSTOMER_ID, CUST_FIRST_NAME, CUST_LAST_NAME ,DATE_OF_BIRTH, MARITAL_STATUS ,CUST_EMAIL) select CUSTOMER_ID, CUST_FIRST_NAME, CUST_LAST_NAME ,DATE_OF_BIRTH, MARITAL_STATUS ,CUST_EMAIL from oe.customers;
//向orders中插入数据
insert into orders(order_id,order_date ,customer_id ,ship_date,total)
select order_id,order_date ,customer_id ,add_months(order_date,2),order_total from oe.orders;
1.建立函数fun_valid_customer,根据输入的客户号,检查客户是否存在,如果客户存在,则返回TRUE,否则返回FALSE。
方法一:
create or replace function fun_valid_customer (v_customer_id number)
return varchar2
is
v_return varchar2(50);
v_CUST_FIRST_NAME varchar2(50);
begin
update customers set customer_id=v_customer_id where customer_id=v_customer_id;
if sql%found then
v_return:='true';
else
v_return:='false';
end if;
return v_return;
end;
方法二:
create or replace function fun_valid_customer (v_customer_id number)
return varchar2
is
v_return varchar2(50);
v_CUST_FIRST_NAME varchar2(50);
begin
select CUST_FIRST_NAME into v_CUST_FIRST_NAME from customers where customer_id=v_customer_id;
if sql%found then
v_return:='true';
return v_return;
end if;
exception
when no_data_found then
return 'false';
end;
方法三:
create or replace function fun_valid_customer (v_customer_id number)
return boolean
is
v_tmp number;
begin
select 1 into v_tmp from customers where customer_id=v_customer_id;
return true;
exception
when no_data_found then
return false;
end;
本例选择方法三
2.建立函数fun_get_total,根据输入的订单号返回订单总价,然后调用该函数。当建立函数fun_get_total时,实现规则:
如果订单不存在,则显示自定义错误消息“ORA-20001:Please check correct order no.”
create or replace function fun_get_total(v_order_id number)
return number
is
v_total number(8,2);
begin
select total into v_total from orders where order_id=v_order_id;
return v_total;
exception
when no_data_found then
raise_application_error(-20001,'Please check correct order no.');
end;
3.建立过程pro_add_order,根据输入的订单号,预定日期,客户号,交付日期和订单总价,为ORDERS表插入数据,然后调用过程。当建立过程pro_add_order,实现规则:
使用pro_valid_customer检查客户号是否正确;如果正确,则插入数据,否则显示自定义错误消息“ORA-20001,Please check correct customer no.”
如果交付日期小于预定日期,则显示错误信息“ORA-20002:交付日期必须在预定日期之后。”
如果输入了已经存在的订单号,则显示自定义错误信息“ORA-20003:该订单已经存在。”
create or replace procedure pro_add_order(v_order_id number,v_order_date date,v_customer_id number,v_ship_date date,v_total number)
is
v_count number;
begin
if fun_valid_customer(v_customer_id) then
if v_ship_date < v_order_date then
raise_application_error(-20002,'ship date is must after order date');
else
update orders set order_id=v_order_id where order_id=v_order_id;
if sql%found then
raise_application_error(-20003,'The order already exists');
else
insert into orders(order_id ,order_date ,customer_id,ship_date,total ) values(v_order_id ,v_order_date ,v_customer_id,v_ship_date,v_total );
commit;
end if;
end if;
else
raise_application_error(-20001,'Please check correct customer no.');
end if;
end;
4.建立过程pro_delete_order,根据输入的订单号取消特定订单,然后调用该过程。实现规则:如果定的不存在,则显示错误信息“ORA-20001,请检查并输入正确的订单号。”
create or replace procedure pro_delete_order(v_order_id number)
is
begin
delete from orders where order_id=v_order_id;
if sql%notfound then
raise_application_error(-20001,'Please check and enter the correct order id' );
end if;
commit;
end;