创建表emp
-- Create table
create table EMP
(
EMPNO NUMBER not null,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER,
HIREDATE DATE,
SAL NUMBER,
COMM NUMBER,
DEPTNO NUMBER
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
-- Create/Recreate primary, unique and foreign key constraints
alter table EMP
add constraint PK_EMP_NO primary key (EMPNO)
using index
tablespace USERS
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
alter table EMP
add constraint FK_DEPT_NO foreign key (DEPTNO)
references DEPT (DEPTNO);
创建表dept
-- Create table
create table DEPT
(
DEPTNO NUMBER not null,
DNAME VARCHAR2(14),
LOC VARCHAR2(13)
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
-- Create/Recreate primary, unique and foreign key constraints
alter table DEPT
add constraint PK_DEPT_NO primary key (DEPTNO)
using index
tablespace USERS
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
dept表 插入数据
insert into dept (DEPTNO, DNAME, LOC)
values (50, 'aaa', 'aaa');
insert into dept (DEPTNO, DNAME, LOC)
values (10, 'ACCOUNTING', 'NEW YORK');
insert into dept (DEPTNO, DNAME, LOC)
values (20, 'RESEARCH', 'DALLAS');
insert into dept (DEPTNO, DNAME, LOC)
values (30, 'SALES', 'CHICAGO');
insert into dept (DEPTNO, DNAME, LOC)
values (40, 'OPERATIONS', 'BOSTON');
emp表插入数据
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7369, 'SMITH', 'CLERK', 7902, to_date('17-12-1980', 'dd-mm-yyyy'), 800, null, 20);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7499, 'ALLEN', 'SALESMAN', 7698, to_date('20-02-1981', 'dd-mm-yyyy'), 800, 300, 30);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7521, 'WARD', 'SALESMAN', 7698, to_date('22-02-1981', 'dd-mm-yyyy'), 625, 500, 30);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7566, 'JONES', 'MANAGER', 7839, to_date('02-04-1981', 'dd-mm-yyyy'), 2975, null, 20);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7654, 'MARTIN', 'SALESMAN', 7698, to_date('28-09-1981', 'dd-mm-yyyy'), 625, 1400, 30);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7698, 'BLAKE', 'MANAGER', 7839, to_date('01-05-1981', 'dd-mm-yyyy'), 1425, null, 30);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7782, 'CLARK', 'MANAGER', 7839, to_date('09-06-1981', 'dd-mm-yyyy'), 2450, null, 10);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7788, 'SCOTT', 'ANALYST', 7566, to_date('19-04-1987', 'dd-mm-yyyy'), 3000, null, 20);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7844, 'TURNER', 'SALESMAN', 7698, to_date('08-09-1981', 'dd-mm-yyyy'), 750, 0, 30);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7876, 'ADAMS', 'CLERK', 7788, to_date('23-05-1987', 'dd-mm-yyyy'), 1100, null, 20);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7900, 'JAMES', 'CLERK', 7698, to_date('03-12-1981', 'dd-mm-yyyy'), 475, null, 30);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7902, 'FORD', 'ANALYST', 7566, to_date('03-12-1981', 'dd-mm-yyyy'), 3000, null, 20);
insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7934, 'MILLER', 'CLERK', 7782, to_date('23-01-1982', 'dd-mm-yyyy'), 1300, null, 10);
plsql 测试
set serveroutput on;
show errors;--查看错误
------------
--constant类似 final
declare
v_num constant number := 0;
begin
v_num := 2/ v_num;
dbms_output.put_line(v_num);
exception
when others then
dbms_output.put_line('error');
end;
--------------------
declare
v_num number := 0;
begin
v_num := 2/ v_num;
dbms_output.put_line(v_num);
exception
when others then
dbms_output.put_line('error');
end;
--------------------
--错误
declare
v_num number := 0;
begin
v_num := 2/ v_num;
dbms_output.put_line(v_num);
end;
-------------------
create or replace procedure proc_heloworld as
begin
dbms_output.put_line('aaa');
end;
execute proc_heloworld;
-----------------------
--类型与emp表的empno字段一致
declare
v_empno number;
v_empno2 emp.empno%type;
v_empno3 v_empno2%type;
begin
dbms_output.put_line('test');
end;
-----------------------
--复合变量
--table类型变量(类似于数组)
--type 新声明了一种类型 type_table_emp_empno
declare
type type_table_emp_empno is table of emp.empno%type index by binary_integer;
v_empnos type_table_emp_empno;
begin
v_empnos(0) := 7369;
v_empnos(2) := 7839;
v_empnos(-1) := 9999;
dbms_output.put_line(v_empnos(-1));
end;
--Record类型变量 类似于java里面的类
declare
type type_record_dept is record
(
deptno dept.deptno%type,
dname dept.dname%type,
loc dept.loc%type
);
v_temp type_record_dept;
begin
v_temp.deptno := 50;
v_temp.dname := 'aaaa';
v_temp.loc := 'bj';
dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname);
end;
--输出50 aaaa
--使用%rowtype声明record变量
declare
v_temp dept%rowtype;
begin
v_temp.deptno := 50;
v_temp.dname := '22';
v_temp.loc := 'bj';
dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname);
end;
--plsql里面的select必须返回一条记录,并且只能返回一条记录
--select 里面没有游标,必需有into
set serveroutput on;
--必需返回一条记录,可以改变where后面的查询条件
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
select ename, sal into v_ename, v_sal from emp where empno = 7369;
dbms_output.put_line(v_ename || ' ' || v_sal);
end;
-----
declare
v_emp emp%rowtype;
begin
select * into v_emp from emp where empno = 7369;
dbms_output.put_line(v_emp.ename);
end;
--insert
declare
v_deptno dept.deptno%type := 50;
v_dname dept.dname%type := 'aaa';
v_loc dept.loc%type := 'aaa';
begin
insert into dept values(v_deptno, v_dname, v_loc);
commit; --必需事务提交
end;
--update
declare
v_deptno emp.deptno%type := 30;
v_count number;
begin
update emp set sal = sal/2 where deptno = v_deptno;
dbms_output.put_line(sql%rowcount || '条记录被影响');
commit;
end;
--查询某条记录,最后要做出一个值,放入里面;
declare
v_deptno emp.deptno%type := 30;
v_count number;
begin
--update emp set sal = sal/2 where deptno = v_deptno;
select deptno into v_deptno from emp where empno = 7369;
dbms_output.put_line(sql%rowcount || '条记录被影响');
commit;
end;
--最后产生了一个值,则输出 1条记录被影响
declare
v_deptno emp.deptno%type := 30;
v_count number;
begin
--update emp set sal = sal/2 where deptno = v_deptno;
--select deptno into v_deptno from emp where empno = 7369;
select count(*) into v_count from emp;
dbms_output.put_line(sql%rowcount || '条记录被影响');
commit;
end;
--ddl
--不能添加 or replace 否则输出 ORA-00922: 选项缺失或无效
begin
execute immediate 'create or replace table T_T(num varchar2(20) default ''aaa'')';
end;
--执行成功
begin
execute immediate 'create table T_T(num varchar2(20) default ''aaa'')';
end;
--
begin
execute immediate 'drop table T_T';
end;
----------------------
----------------------
----------------------
--分支和循环
--if语句
--取出7369的薪水,如果<1200,则输出'low',如果<2000,则输出'middle', 否则'high'
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where empno = 7369;
if(v_sal < 1200) then
dbms_output.put_line('low');
elsif(v_sal < 2000) then
dbms_output.put_line('middle');
else
dbms_output.put_line('high');
end if;
end;
--------------
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where empno = 7839;
dbms_output.put_line('7839的薪水为' || ' ' || v_sal );
if(v_sal < 2500) then
v_sal := v_sal * 2;
update emp set sal = v_sal where empno = 7839;
elsif(v_sal > 2500) then
v_sal := v_sal / 2;
update emp set sal = v_sal where empno = 7839;
else
dbms_output.put_line('equal');
end if;
commit;
end;
--循环 以loop开始,以end loop结束
--do while
declare
i binary_integer := 1;
begin
loop
dbms_output.put_line(i);
i := i + 1;
exit when (i >= 11);
end loop;
end;
-- while
declare
i binary_integer := 1;
begin
while(i<11) loop
dbms_output.put_line(i);
i := i+1;
end loop;
end;
--for
declare
v_var binary_integer := 1;
begin
for i in 1..10 loop
dbms_output.put_line(i);
v_var := v_var + 1;
end loop;
dbms_output.put_line('v_var的值为' || v_var);
end;
--错误处理
declare
v_temp number;
begin
select empno into v_temp from emp where deptno = 10;
exception
when too_many_rows then
dbms_output.put_line('太多记录了');
when no_data_found then
dbms_output.put_line('无数据');
when others then
dbms_output.put_line('error');
end;
--创建错误记录表
create table errorlog(
id number primary key,
errcode number,
errmsg varchar2(1024),
errdate date
);
create sequence seq_errorlog_id start with 1 increment by 1;
--错误信息写入表errorlog
declare
v_deptno dept.deptno%type := 10;
v_errcode number;
v_errmsg varchar2(1024);
begin
delete from dept where deptno = v_deptno;
commit;
exception
when others then
rollback;
v_errcode := SQLCODE;
v_errmsg := SQLERRM;
insert into errorlog values(seq_errorlog_id.nextval, v_errcode, v_errmsg, sysdate);
commit;
end;
--游标,输出一条记录
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
fetch c into v_emp;
dbms_output.put_line(v_emp.ename);
close c;
end;
--遍历游标 do while
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
loop
fetch c into v_emp;
exit when(c%notfound);
dbms_output.put_line(v_emp.ename);
end loop;
close c;
end;
--最后一条记录输出两遍
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
loop
fetch c into v_emp;
dbms_output.put_line(v_emp.ename);
exit when(c%notfound);
end loop;
close c;
end;
--遍历游标 while
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
fetch c into v_emp;--首先fetch,如果找到了,则可以进入循环
while(c%found) loop
dbms_output.put_line(v_emp.ename);
fetch c into v_emp;
end loop;
close c;
end;
--第一条未取出,最后一条取出两次
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
fetch c into v_emp;
while(c%found) loop
fetch c into v_emp;
dbms_output.put_line(v_emp.ename);
end loop;
close c;
end;
--遍历游标 for 最方便
declare
cursor c is
select * from emp;
begin
for v_temp in c loop
dbms_output.put_line(v_temp.ename);
end loop;
end;
--带参数的游标
declare
cursor c(v_deptno emp.deptno%type, v_job emp.job%type) is
select ename, sal from emp where deptno = v_deptno and job = v_job;
begin
for v_temp in c(30, 'CLERK') loop
dbms_output.put_line(v_temp.ename);
end loop;
end;
--用于更新的游标
declare
cursor c is
select * from emp for update;
begin
for v_tmp in c loop
if(v_tmp.sal < 2000) then
update emp set sal = sal * 2 where current of c;
--赋值用:= 相等用=
elsif(v_tmp.sal = 5000) then
delete from emp where current of c;
end if;
end loop;
--commit;
end;
--procedure
create or replace procedure p is
cursor c is
select * from emp for update;
begin
for v_tmp in c loop
if(v_tmp.sal < 2000) then
update emp set sal = sal * 2 where current of c;
--赋值用:= 相等用=
elsif(v_tmp.sal = 5000) then
delete from emp where current of c;
end if;
end loop;
--commit;
end;
exec p;
--或者
begin
p;
end;
--创建带参数的存储过程
create or replace procedure p
(v_a in number, v_b number, v_ret out number, v_temp in out number)
as
begin
if(v_a > v_b ) then
v_ret := v_a;
else
v_ret := v_b;
end if;
v_temp := v_temp + 1;
end;
--执行
declare
v_a number := 3;
v_b number := 4;
v_ret number;
v_temp number := 5;
begin
p(v_a, v_b, v_ret, v_temp);
dbms_output.put_line(v_ret);
dbms_output.put_line(v_temp);
end;
--二者合并
declare
v_a number := 3;
v_b number := 4;
v_ret number;
v_temp number := 5;
begin
if(v_a > v_b ) then
v_ret := v_a;
else
v_ret := v_b;
end if;
v_temp := v_temp + 1;
dbms_output.put_line(v_ret);
dbms_output.put_line(v_temp);
end;
--删除存储过程
drop procedure p;
--创建函数
create or replace function sal_tax(v_sal number) return number is
begin
if(v_sal < 2000) then
return 0.10;
elsif(v_sal < 2750) then
return 0.15;
else
return 0.20;
end if;
end;
--调用函数
select sal_tax(sal) from emp;
--触发器
create table emp_log
(
uname varchar2(20),
action varchar2(10),
atime date
);
--for each row 每操作一行,触发一次操作
create or replace trigger trig
after insert or delete or update on emp for each row
begin
if inserting then
insert into emp_log values (USER, 'insert', sysdate);
elsif updating then
insert into emp_log values (USER, 'update', sysdate);
elsif deleting then
insert into emp_log values (USER, 'delete', sysdate);
end if;
end;
delete from emp where empno = 7839;
commit;
--错误,不能指定其长度
create or replace procedure pro_insert_dept(v_deptno in number, v_dname in varchar2(20), v_loc in varchar2(20)) is
begin
insert into dept(deptno, dname, loc) values(v_deptno, v_dname, v_loc);
end;
--正确
create or replace procedure pro_insert_dept(v_deptno in number, v_dname in varchar2, v_loc in varchar2) is
begin
insert into dept(deptno, dname, loc) values(v_deptno, v_dname, v_loc);
end;