localhost:1521@ORCL test/122333 sys/122333 dba scott/tiger
connect SCOTT/tiger@ORCL
show all
select * from emp;
set pagesize 100 linesize 120
show user
select user from dual
spool c:\test
记录信息
spool off
describe emp; desc emp;
select table_name from user_tables;
sqlplus sys/122333 as sysdba
create user student identified by student
grant create session to student;
grant select on scott.dept to student;
drop user student cascade;
grant connect to user1;
grant create table to user1;
grant create procedure to user1;
grant unlimited tablespace to user1;
create table emp as select * from scott.emp;
rownum 是每个表的虚列
select ename, sal, sal*(1+20/100) from emp;
select ename as 名称, sal 工资 from emp;
select ename as "Name", sal '工资' from emp;
select ename||job from emp;
select distinct job from emp;
select ename, sal from emp order by sal asc, ename desc;
select empno, sal*months_between(sysdate, hiredate) as total from emp order by total;
select nvl(comm, 0) from emp;
select concat(rpad(ename, 15, '.'), job) as 职务列表 from emp;
select empno, initcap(ename), job from emp where substr(ename, 1,1) = 'W';
select empno, length(ename), ename from emp where instr(ename, 'S', 1, 1) > 0; --起始位置1,出现次数1
select trim('s' from 'sos') from dual;
select sysdate from dual;
select last_day('08-2月-03') from dual;
select ename, round(sysdate-hiredate) days from emp where deptno = 10;
select to_date('1980-01-01', 'yyyy-mm-dd') from dual;
to_char to_number
select to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS AM DY') from dual;
select decode(2, 1, '1', 3, '2', '11') from dual;
select userenv('isdba'),userenv('instance'),userenv('language'),userenv('lang'),userenv('terminal') from dual;
select ename, sal, dname from emp, dept where emp.deptno(+) = dept.deptno;
select deptno, max(sal) from emp group by deptno having max(sal) >= 3000;
select deptno, max(avg(sal)) from emp group by deptno; 会出错,因为各部门平均工资的最高值不应该属于某个部门
select empno, ename, sal from emp where (job, deptno) = (select job, deptno from emp where ename = 'SCOTT');
insert into manager select empno, ename, sal from emp where job = 'CLERK';
update manager set (ename, sal) = (select ename, sal from emp where empno = 7788) where empno = 1000;
注意truncate/drop/delete区别
select empno , ename, job, sal from emp where deptno = 10 for update;
create sequence AAA minvalue 1 maxvalue 999 start with 1 increment by 1 cache 30;
select sequence_name from user_sequences;
drop table 图书4 cascade constraints;
rename 图书 to 图书5;
truncate table 图书5;
comment on table emp is '公司雇员列表';
select object_name from user_objects where object_type = 'TABLE';
alter table 图书 disable constraint sys_C0011485;
alter table 出版社 add 电子邮件 varchar2(30) check(电子邮件 like '%@%');
alter table 图书 set unused column 出版日期;
alter table 图书 drop unused columns;
alter table emp add constraint PK_4 primary key(empno);
alter table emp drop constraint PK_4;
create table 考生(
考号 varchar2(5),
姓名 varchar2(30),
成绩 number(3))
partition by range(成绩)
(partition A values less than (300) tablespace users,
partition B values less than (500) tablespace users,
partition C values less than (MAXValue) tablespace users);
select * from 考生 partition(C);
grant create view to user1;
grant drop any view to user1;
create or replace view 图书作者(书名, 作者, 出版社) as select 图书名称, 作者, 出版社名称 from 图书, 出版社 where 图书.出版社编号 = 出版社.编号;
create or replace view manager as select * from emp where job = 'MANAGER' with read only;
create or replace view 清华图书 as select * from 图书 where 出版社编号 = '01' with check option;
desc user_updatable_columns;
desc user_objects;
col col_name format a10;
grant create any index to user1;
grant drop any index to user1;
create index emp_jobsal on emp(job,sal);
select index_name, index_type, uniqueness,table_name from user_indexes;
select column_name from user_ind_columns;
select * from user_sys_privs;
select * from user_tab_privs;
select aaa.nextval,aaa.currval from dual;
insert into 图书 values('A'||to_char(bookid.nextval, 'fm0000'), '网页制作精选', '01' ,'刘莹', 4, 26.50);
grant create public synonym to user1;
grant create synonym to user1;
grant drop any synonym to user1;
synonym
dict dictionary
cat user_catalog
clu user_clusters
ind user_indexes
obj user_objects
seq user_sequences
syn user_synonyms
cols user_tab_columns
tabs user_tables
create cluster comm(stuno number(5), stuname varchar2(10), sex varchar2(2)) size 500 tablespace users;
create table student(...) cluster comm(stuno, stunname, sex);
create index inx_comm on cluster comm;
创建聚簇后,要创建使用聚簇的表,对聚簇还应该建立索引。如果不对聚簇建立索引,则不能对聚簇表进行插入、修改和删除操作。
drop cluster comm including tables cascade constraints;
create database link abc connect to scott identified by tiger using 'CHENKUND';
分布式查询
select ename, dname from emp@abc e, dept d where e.deptno = d.deptno;
PL/SQL块执行时需要在最后加一个“/”符号
set serveroutput on
declare
v_job varchar2(9);
v_count binary_integer default 0;
v_total_sal number(9,2) := 0;
v_date date:= sysdate+7;
c_tax_rate constant number(3,2) := 8.25;
c_valid boolean not null := true;
begin
v_job := 'MANAGER';
DBMS_OUTPUT.PUT_LINE(v_job);
DBMS_OUTPUT.PUT_LINE(v_count);
DBMS_OUTPUT.PUT_LINE(v_date);
DBMS_OUTPUT.PUT_LINE(c_tax_rate);
end;
/
DECLARE
v_ename emp.ename%TYPE;
BEGIN
...
END;
variable g_ename varchar2(100)
print g_ename
:g_ename := :g_ename || 'Hello~';
declare
emp_record emp%ROWTYPE;
begin
select * into emp_record from emp where empno = 7788;
DBMS_OUTPUT.PUT_LINE(emp_record.ename);
end;
/
declare
type type_table is table of varchar2(10) index by binary_integer;
v_t type_table;
begin
v_t(1):='MONDAY';
v_t(2):='TUESDAY';
v_t(3):='WEDNESDAY';
v_t(4):='THURSDAY';
v_t(5):='FRIDAY';
DBMS_OUTPUT.PUT_LINE(v_t(3));
end;
/
declare
a number(5) := 2;
begin
DBMS_OUTPUT.PUT_LINE(a**3);
end;
/
IF-THEN-END IF
declare
v_temperature number(5):= 32;
v_result boolean := false;
begin
v_result:= v_temperature > 30;
if v_result then
dbms_output.put_line('温度'|| v_temperature ||'度,偏高')
end if;
end;
/
IF-THEN-ELSE-END IF
IF-THEN-ELSIF-ELSE-END IF
CASE-WHEN-THEN-...-ELSE-END CASE
declare
v_job varchar2(10);
begin
select job into v_job
from emp where empno=7788;
case v_job
when 'PRESIDENT' then
DBMS_OUTPUT.put_line('雇员职务:总裁');
else
DBMS_OUTPUT.put_line('雇员职务:未知');
end case;
end;
/
赋值
declare
v_grade varchar2(10);
v_result varchar2(10);
begin
v_grade:='B';
v_result := case v_grade
when 'A' then '优'
when 'B' then '良'
when 'C' then '中'
when 'D' then '差'
else '未知'
end; -- 没有case
dbms_output.put_line('等级:'|| v_result);
end;
/
表达式
declare
v_sal number(5);
begin
select sal into v_sal from emp where empno = 7788;
case
when v_sal >= 3000 then
dbms_output.put_line('high');
when v_sal >= 1500 then
dbms_output.put_line('middle');
else
dbms_output.put_line('low');
end case;
end;
/
declare
v_total number(5):=0;
v_count number(5):=1;
begin
loop
v_total := v_total + v_count**2;
exit when v_count = 15;
v_count:=v_count+2;
end loop;
dbms_output.put_line(v_total);
end;
/
begin
for i in 1..8
loop
dbms_output.put_line(to_char(i) || rpad('*', i,'*'));
end loop;
end;
/
begin
for i in reverse 1..8
loop
dbms_output.put_line(to_char(i));
end loop;
end;
/
declare v_count number(2):=1;
begin
while v_count < 6 loop
insert into emp(empno, ename) values(5000+v_count, '临时');
v_count:=v_count+1;
end loop;
end;
/
SQL%ROWCOUNT SQL%FOUND SQL%NOTFOUND SQL%ISOPEN
begin
update emp set sal=sal+100 where empno = 1234;
if sql%found then
dbms_output.put_line('success');
commit;
else
dbms_output.put_line('fail');
end if;
end;
/
declare
v_ename varchar2(10);
v_job varchar2(10);
cursor emp_cursor is select ename, job from emp where empno = 7788;
begin
open emp_cursor;
fetch emp_cursor into v_ename, v_job;
dbms_output.put_line(v_ename ||','||v_job);
close emp_cursor;
end;
/
declare
cursor aaa is select ename, job, sal from emp where empno=7788;
emp_record aaa%rowtype;
begin
open aaa;
fetch aaa into emp_record;
dbms_output.put_line(emp_record.ename || emp_record.job || to_char(emp_record.sal));
close aaa;
end;
/
declare
cursor AAA is select ename, sal from emp order by sal desc
a AAA%rowtype;
begin
open AAA;
for i in 1..3
loop
fetch AAA into a;
dbms_output.put_line(a.ename ||','|| a.sal);
end loop;
close AAA;
end;
/
declare
cursor emp_cursor is
select empno, ename from emp;
begin
for emp_record in emp_cursor loop
dbms_output.put_line(emp_record.empno || emp_record.ename);
end loop;
end;
/
begin
for re in (select ename from emp)
loop
dbms_output.put_line(re.ename);
end loop;
end;
/
declare
v_ename varchar2(10);
cursor emp_cursor is select ename from emp;
begin
open emp_cursor;
if emp_cursor%isopen then
loop
fetch emp_cursor into v_ename;
exit when emp_cursor%notfound;
dbms_output.put_line(to_char(emp_cursor%rowcount)||'-'||v_ename);
end loop;
close emp_cursor;
else
dbms_output.put_line('not open!!!');
end if;
end;
/
declare
v_empno number(5);
v_ename varchar2(10);
cursor emp_cursor(p_deptno number, p_job varchar2) is
select empno, ename from emp where deptno = p_deptno and job = p_job;
begin
open emp_cursor(10, 'CLERK');
loop
fetch emp_cursor into v_empno,v_ename;
exit when emp_cursor%notfound;
dbms_output.put_line(v_empno ||','||v_ename);
end loop;
end;
/
declare
v_empno number(5);
v_ename varchar2(10);
v_deptno number(5);
v_job varchar2(10);
cursor emp_cursor is
select empno, ename from emp where deptno = v_deptno and job = v_job;
begin
v_deptno :=10;
v_job:='CLERK';
open emp_cursor;
loop
fetch emp_cursor into v_empno,v_ename;
exit when emp_cursor%notfound;
dbms_output.put_line(v_empno ||','||v_ename);
end loop;
end;
/
declare
str varchar2(100);
v_ename varchar2(10);
begin
str:='select ename from scott.emp where empno=7788';
execute immediate str into v_ename;
dbms_output.put_line(v_ename);
end;
/
declare
type cur_type is ref cursor;
cur cur_type;
rec scott.emp%ROWTYPE;
str varchar2(50);
letter char:='A';
begin
loop
str:='select ename from emp where ename like ''%'||letter||'%''';
open cur for str;
dbms_output.put_line('contains '||letter||' name');
loop
fetch cur into rec.ename;
exit when cur%notfound;
dbms_output.put_line(rec.ename);
end loop;
exit when letter='Z';
letter:=chr(ascii(letter)+1);
end loop;
end;
/
declare
v_name varchar2(10);
begin
select ename into v_name from emp where empno = 1234;
DBMS_OUTPUT.PUT_LINE('name :'|| v_name);
exception
when no_data_found then
DBMS_OUTPUT.PUT_LINE('numero error');
when others then
DBMS_OUTPUT.PUT_LINE('other');
end;
/
declare
v_temp number(5):=1;
begin
v_temp := v_temp/0;
exception
when others then
DBMS_OUTPUT.PUT_LINE('error');
DBMS_OUTPUT.PUT_LINE(sqlcode());
DBMS_OUTPUT.PUT_LINE(sqlerrm());
end;
/
系统预定义异常
CURSOR_ALREADY_OPEN ORA_06511 试图打开已经打开的游标
INVALID_CURSOR ORA_01001 试图使用没有打开的游标
DUP_VAL_ON_INDEX ORA_00001 保存重复值到惟一索引约束的列中
ZERO_DIVIDE ORA_01476 发生除数为零的除法错误
INVALID_NUMBER ORA_01722 试图对无效字符进行数值转换
ROWTYPE_MISMATCH ORA_06504 主变量和游标的类型不兼容
VALUE_ERROR ORA_06502 转换、截断或算术运算发生错误
TOO_MANY_ROWS ORA_01422 SELECT INTO 语句返回多于一行的数据
NO_DATA_FOUND ORA_01403 SELECT INTO 语句没有数据返回
TIMEOUT_ON_RESOURCE ORA_00051 等待资源时发生超时错误
TRANSACTION_BACKED_OUT ORA_00060 由于死锁,提交失败
STORAGE_ERROR ORA_06500 发生内存错误
PROGRAM_ERROR ORA_06501 发生PL/SQL 内部错误
NOT_LOGGED_ON ORA_01012 试图操作未连接的数据库
LOGIN_DENIED ORA_01017 在连接时提供了无效用户名或口令
declare
v_ename varchar2(10);
null_insert_error exception;
pragma exception_init(null_insert_error, -1400);
begin
insert into emp(empno) values(null);
exception
when null_insert_error then
dbms_output.put_line('unable to insert null value');
when others then
dbms_output.put_line('other system error');
end;
/
declare
new_no number(10);
new_excp1 exception;
new_excp2 exception;
begin
new_no:= 6789;
insert into emp(empno, ename) values(new_no, 'xiaozheng');
if new_no < 7000 then
raise new_excp1;
end if;
if new_no > 8000 then
raise new_excp2;
end if;
commit;
exception
when new_excp1 then
rollback;
dbms_output.put_line('<7000');
when new_excp2 then
rollback;
dbms_output.put_line('>8000');
end;
/
RAISE_APPLICATION_ERROR
create or replace procedure emp_count as v_total number(10);
begin
select count(*) into v_total from emp;
dbms_output.put_line(v_total);
end;
/
execute emp_count;
begin emp_count end;/
grant execute on emp_count to user1;
alter procedure emp_count compile;
create or replace procedure change_salary(p_empno in number default 7788,
p_raise number default 10)
as
v_ename varchar2(10);
v_sal number(5);
begin
select ename, sal into v_ename, v_sal from emp where empno = p_empno;
update emp set sal = sal+p_raise where empno = p_empno;
dbms_output.put_line(v_ename || ' change to ' || to_char(v_sal + p_raise));
commit;
exception
when others then
dbms_output.put_line('error');
rollback;
end;
/
execute change_salary(7782, 80);
execute change_salary(p_empno=> 7782, p_raise=>80);
create or replace procedure emp_count(p_total out number) as
begin
select count(*) into p_total from emp;
end;
/
declare
v_empcount number;
begin
emp_count(v_empcount);
dbms_output.put_line(v_empcount);
end;
/
create or replace function get_emp_name(p_empno number default 7788)
return varchar2 as
v_ename varchar2(10);
begin
select ename into v_ename from emp where empno=p_empno;
return (v_ename);
exception
when no_data_found then
dbms_output.put_line('no data');
return (null);
when too_many_rows then
dbms_output.put_line('reduplicate');
when others then
dbms_output.put_line('others');
return(null);
end;
/
desc user_source; //查询存储过程、函数
desc get_emp_name; //查询其参数
show errors //查看编译错误
desc user_dependencies; //检查存储过程或函数的依赖性
常用系统包
DBMS_OUTPUT 在SQL*Plus 环境下输出信息
DBMS_DDL 编译过程函数和包
DBMS_SESSION 改变用户的会话,初始化包等
DBMS_TRANSACTION 控制数据库事务
DBMS_MAIL 连接Oracle*Mail
DBMS_LOCK 进行复杂的锁机制管理
DBMS_ALERT 识别数据库事件告警
DBMS_PIPE 通过管道在会话间传递信息
DBMS_JOB 管理Oracle 的作业
DBMS_LOB 操纵大对象
DBMS_SQL 执行动态SQL 语句
create or replace package employe is
procedure show_detail;
procedure get_employe(p_empno number);
procedure save_employe;
procedure change_name(p_newname varchar2);
procedure change_sal(p_newsal number);
end employe;
/
create or replace package body employe is
employe emp%rowtype;
procedure show_detail as
begin
dbms_output.put_line('info');
dbms_output.put_line(employe.empno);
dbms_output.put_line(employe.ename);
dbms_output.put_line(employe.job);
dbms_output.put_line(employe.sal);
dbms_output.put_line(employe.deptno);
end show_detail;
PROCEDURE GET_EMPLOYE(P_EMPNO NUMBER)
AS
BEGIN
SELECT * INTO EMPLOYE FROM EMP WHERE EMPNO=P_EMPNO;
DBMS_OUTPUT.PUT_LINE('获取雇员'||EMPLOYE.ENAME||'信息成功');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('获取雇员信息发生错误!');
END GET_EMPLOYE;
PROCEDURE SAVE_EMPLOYE
AS
BEGIN
UPDATE EMP SET ENAME=EMPLOYE.ENAME, SAL=EMPLOYE.SAL WHERE EMPNO=
EMPLOYE.EMPNO;
DBMS_OUTPUT.PUT_LINE('雇员信息保存完成!');
END SAVE_EMPLOYE;
PROCEDURE CHANGE_NAME(P_NEWNAME VARCHAR2)
AS
BEGIN
EMPLOYE.ENAME:=P_NEWNAME;
DBMS_OUTPUT.PUT_LINE('修改名称完成!');
END CHANGE_NAME;
PROCEDURE CHANGE_SAL(P_NEWSAL NUMBER)
AS
BEGIN
EMPLOYE.SAL:=P_NEWSAL;
DBMS_OUTPUT.PUT_LINE('修改工资完成!');
END CHANGE_SAL;
END EMPLOYE;
/
ALTER PACKAGE 包名 COMPILE PACKAGE
ALTER PACKAGE 包名 COMPILE PACKAGE BODY
grant execute on emp_pk to user1;
CREATE OR REPLACE TRIGGER DML_LOG
BEFORE --触发时间为操作前
DELETE OR INSERT OR UPDATE -- 由三种事件触发
ON emp
FOR EACH ROW -- 行级触发器
BEGIN
IF INSERTING THEN
INSERT INTO logs VALUES(logs_id_squ.NEXTVAL,'EMP','INSERT',:new.empno,SYSDATE,USER);
ELSIF DELETING THEN
INSERT INTO logs VALUES(logs_id_squ.NEXTVAL,'EMP','DELETE',:old.empno,SYSDATE,USER);
ELSE
INSERT INTO logs VALUES(logs_id_squ.NEXTVAL,'EMP','UPDATE',:new.empno,SYSDATE,USER);
END IF;
END;
create or replace trigger log_sal
before
update of sal
on emp
for each row
WHEN (new.job='CLERK' AND (ABS(new.sal-old.sal)>200)) //when中new old不加:
declare
v_no number;
begin
select count(*) into v_no from logerr;
INSERT INTO logerr VALUES(v_no+1,'雇员'||:new.ename||'的原工资:'||:old.sal||'新工资:'||:new.sal);
end;
/
数据库事件触发器的触发事件
种 类 关 键 字 说 明
CREATE 在创建新对象时触发模式级
ALTER 修改数据库或数据库对象时触发
DROP 删除对象时触发
STARTUP 数据库打开时触发
SHUTDOWN 在使用NORMAL 或IMMEDIATE 选项关闭数据库时触发数据库级
SERVERERROR 发生服务器错误时触发数据库级与模式级
LOGON 当用户连接到数据库,建立会话时触发
LOGOFF 当会话从数据库中断开时触发
语句级触发器适合于对整个表的操作权限进行控制
数据库事件属性
属 性 适用触发器类型 说 明
Sys.sysevent 所有类型 返回触发器触发事件字符串
Sys.instance_num 所有类型 返回Oracle 实例号
Sys.database_name 所有类型 返回数据库名字
Sys.server_error(stack_position) SERVERERROR
从错误堆栈指定位置返回错误号,参数为1 表示最近的错误
Is_servererror(error_number) SERVERERROR 判断堆栈中是否有参数指定的错误号
Sys.login_user 所有类型 返回导致触发器触发的用户名
Sys.dictionary_obj_type CREATE、ALTER、DROP 返回DDL 触发器触发时涉及的对象类型
Sys. dictionary_obj_name CREATE、ALTER、DROP 返回DDL 触发器触发时涉及的对象名称
Sys.des_encrypted_password CREATE、ALTER、DROP 创建或修改用户时,返回加密后的用户密码
grant administer database trigger to user1
create or replace trigger init_logon
after startup
on database
begin
delete from userlog;
end;
/
create or replace trigger database_logon
after logon
on database
begin
insert into userlog values(sys.login_user, sysdate);
end;
/
create or replace trigger nodrop_emp before
drop on schema
begin
if sys.dictionary_obj_name = 'EMP' then
raise_application_error(-20005, 'no drop emp');
end if;
end;
/
create or replace trigger change_name instead of insert on emp_name
declare
v_empno number(4);
begin
select max(empno)+1 into v_empno from emp;
insert into emp(empno, ename)
values (v_empno, :new.ename);
end;
/
user_triggers