下面为数据库实验的一些报告(oracle)(第十周之后)
可直接下载资源:https://download.csdn.net/download/qq_42785226/14622190
这些报告每次大概是一节课的时间,由于课程原因,很多内容都简化了,知识内容也可能相对片面一些,并不全面,只作练习参考使用。
csdn不允许文字长度过长,这里没办法只好拆成三份。
数据库实验报告
5、 列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门 10
6、列出所有“CLERK”(办事员)的姓名及其部门名称。 11
8、列出在部门“SALES”(销售部)工作的员工的姓名,假定不知道销售部的部门编号。 12
11、列出薪金等于部门30中员工的薪金的所有员工的姓名和薪金。 13
12、 列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金。 13
17、列出各个部门的MANAGER(经理)的最低薪金。 17
Dual操作(DESC,查询内容,日期(格式),作计算器等): 18
Dual查询user、日期(带特定格式)、生成随机数: 24
定义(declare)(常量、变量)、赋值(:=)操作练习: 24
IF、 ELSIF、 ENDIF练习(注意为:ELSIF): 25
导入表:SQL> $imp system/test tables=(xs,kc,xs_kc) file=c:\xskc.dmp; 27
黑屏下查询归档文件信息:SQL> conn /as sysdba; SQL> ArCHIVE Log list; 28
查询表信息:SQL> select * from cat; 28
查询用户信息:SQL> select * from dba_users; 33
查询数据文件信息dba_data_files:select * from dba_data_files; 36
查询归档文件信息:select name,log_mode from v$database; 38
查询控制文件信息:select * from v$controlfile; 38
查询日志文件信息:select * from v$log; 38
按组添加日志文件LOGFILE并作出相关查询:ALTER DATABASE ADD LOGFILE GROUP 4('log1a.rdo','log2a.rdo')size 5000k; 39
按成员MEMBER添加日志文件LOGFILE到组GROUP并作出相关查询:ALTER DATABASE ADD LOGFILE MEMBER 'log3a.log' TO Group 4; 40
按成员删除日志文件:ALTER DATABASE DROP LOGFILE MEMBER 'log3a.log'; 40
按组删除日志文件:ALTER DATABASE DROP LOGFILE Group 4; 41
查询数据块大小:SHOW PARAMETER db_block_size; 42
查询用户分区信息:select * from user_extents; 42
ARCHIVE LOG LIST;黑屏模式下进行归档模式查询 42
SQL> SELECT name,log_mode FROM v$database; 43
以下四步将数据库从非归档模式转化为归档模式(黑屏下): 43
4.嵌入到PL/SQL程序语句(如赋值语句)的case 47
select to_char(months_between(sysdate,to_date('20151001','yyyymmdd'))) from dual; 50
select trunc(sysdate-to_date('20181001','yyyymmdd'))天数 from dual; 50
/*嵌入到pl/sql程序语句(如赋值语句)的case*/ 50
SQL> select * from part_book1; 58
SQL> select * from part_book1 partition(part1); 58
SQL> select * from part_book1 partition(part2); 58
SQL>select * from dba_part_tables; 58
SQL> select * from dba_part_tables where table_name='PART_BOOK1'; 59
SQL> Alter table part_book1 add partition part4 values('北京邮电出版社') tablespace system; 60
查询图书是否过期及应缴金额(select--case查询) 60
循环练习——exit when+for逆序循环(for count in reserve count_1..count_10) 61
利用游标WHILE循环统计并输出scott.emp表各个部门的平均工资, 若平均工资大于2000,则输出“该部门平均工资较高。” 81
带update的游标,loop EXIT WHEN -end loop;Scott.emp表,利用游标,给工资低于1200 的员工增加工资50。并输出“编码为’员工编码号’的工资已经更新” 83
修改emp表的工资,工资不足1000的,调整为1500,工资高于1000的,调整为原来工资的1.5倍,调整后,若工资〉10000,则设其为10000。 86
将对xs表的操作记录(insert,delete,update)在sql_info表中记录下来: 92
创建一个触发器,输出对scott.emp表的操作(插入后员工号和员工名,更新后员工工资,删除的员工号和员工名。): 93
当执行插入操作时,统计操作后员工人数;当执行更新工资操作时,统计更新后员工平均工资;当执行删除操作时,统计删除后各个部门剩余的人数(游标): 94
创建一个存储过程,以部门号为该存储过程的in类型参数,查询该部门的平均工资,并输出该部门中比平均工资高的员工号、员工名。(for 循环遍历 游标): 95
用存储过程进行模糊查找,如查找ename中包含L的雇员信息: 96
创建logoff触发器,在退出登录的时候进行记录(注意此时的触发器时间上不要采用after,因为采用after客户机注销进程终止,不能进行其他操作): 105
设置触发器:作用为禁止在休息日(周六、周天)改变scott.emp雇员信息(包括添加删除和修改)。 107
数据库实验第十一周
一个表空间带多个数据文件,test1.dbf不支持自动扩展test2.dbf支持自动扩展,每次增加1000k,表空间区管理为本地管理,指定大小1M,段设置为自动管理。
SQL> create tablespace table1
2 datafile 'c:test1.dbf' size 2M autoextend off,
3 'c:test2.dbf' size 5M autoextend on next 1000k
4 extent management local
5 uniform size 1M
6 segment space management auto;
Tablespace created
一个表空间带多个数据文件,test3.dbf和test4.dbf,表空间区管理为本地管理管理,段设置为自动管理。
SQL> create tablespace table2
2 datafile 'c:test3.dbf' size 2M,
3 'c:test4.dbf' size 5M
4 extent management local autoallocate
5 segment space management auto;
Tablespace created
SQL> select * from v$datafile;
FILE# CREATION_CHANGE# CREATION_TIME TS# RFILE# STATUS ENABLED CHECKPOINT_CHANGE# CHECKPOINT_TIME UNRECOVERABLE_CHANGE# UNRECOVERABLE_TIME LAST_CHANGE# LAST_TIME OFFLINE_CHANGE# ONLINE_CHANGE# ONLINE_TIME BYTES BLOCKS CREATE_BYTES BLOCK_SIZE NAME PLUGGED_IN BLOCK1_OFFSET AUX_NAME FIRST_NONLOGGED_SCN FIRST_NONLOGGED_TIME
---------- ---------------- ------------- ---------- ---------- ------- ---------- ------------------ --------------- --------------------- ------------------ ------------ ----------- --------------- -------------- ----------- ---------- ---------- ------------ ---------- -------------------------------------------------------------------------------- ---------- ------------- -------------------------------------------------------------------------------- ------------------- --------------------
1 11 2007/4/17 3:3 0 1 SYSTEM READ WRITE 1014748 2020/11/13 15:4 0 521802 521803 2020/9/6 11 503316480 61440 0 8192 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF 0 8192 NONE 0
2 519918 2007/4/17 6:0 1 2 ONLINE READ WRITE 1014748 2020/11/13 15:4 0 521802 521803 2020/9/6 11 73400320 8960 0 8192 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS01.DBF 0 8192 NONE 0
3 5554 2007/4/17 3:3 2 3 ONLINE READ WRITE 1014748 2020/11/13 15:4 0 521802 521803 2020/9/6 11 272629760 33280 0 8192 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSAUX01.DBF 0 8192 NONE 0
4 9202 2007/4/17 3:3 4 4 ONLINE READ WRITE 1014748 2020/11/13 15:4 0 521802 521803 2020/9/6 11 5242880 640 0 8192 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF 0 8192 NONE 0
5 546572 2020/9/6 11:0 6 5 ONLINE READ WRITE 1014748 2020/11/13 15:4 0 0 0 104857600 12800 104857600 8192 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EXAMPLE01.DBF 0 8192 NONE 0
6 1021166 2020/11/13 17 7 6 ONLINE READ WRITE 1021170 2020/11/13 17:0 0 0 0 2097152 256 2097152 8192 C:\ORACLE\PRODUCT\10.2.0\DB_1\DATABASE\TEST1.DBF 0 8192 NONE 0
7 1021169 2020/11/13 17 7 7 ONLINE READ WRITE 1021170 2020/11/13 17:0 0 0 0 5242880 640 5242880 8192 C:\ORACLE\PRODUCT\10.2.0\DB_1\DATABASE\TEST2.DBF 0 8192 NONE 0
8 1021775 2020/11/13 17 8 8 ONLINE READ WRITE 1021779 2020/11/13 17:2 0 0 0 2097152 256 2097152 8192 C:\ORACLE\PRODUCT\10.2.0\DB_1\DATABASE\TEST3.DBF 0 8192 NONE 0
9 1021778 2020/11/13 17 8 9 ONLINE READ WRITE 1021779 2020/11/13 17:2 0 0 0 5242880 640 5242880 8192 C:\ORACLE\PRODUCT\10.2.0\DB_1\DATABASE\TEST4.DBF 0 8192 NONE 0
9 rows selected
SQL>
SQL> create tablespace table3
2 datafile 'c:test5.dbf' size 2M,
3 'c:test6.dbf' size 5M
4 extent management local autoallocate
5 segment space management auto;
Tablespace created
SQL> select * from v$datafile;
FILE# CREATION_CHANGE# CREATION_TIME TS# RFILE# STATUS ENABLED CHECKPOINT_CHANGE# CHECKPOINT_TIME UNRECOVERABLE_CHANGE# UNRECOVERABLE_TIME LAST_CHANGE# LAST_TIME OFFLINE_CHANGE# ONLINE_CHANGE# ONLINE_TIME BYTES BLOCKS CREATE_BYTES BLOCK_SIZE NAME PLUGGED_IN BLOCK1_OFFSET AUX_NAME FIRST_NONLOGGED_SCN FIRST_NONLOGGED_TIME
---------- ---------------- ------------- ---------- ---------- ------- ---------- ------------------ --------------- --------------------- ------------------ ------------ ----------- --------------- -------------- ----------- ---------- ---------- ------------ ---------- -------------------------------------------------------------------------------- ---------- ------------- -------------------------------------------------------------------------------- ------------------- --------------------
1 11 2007/4/17 3:3 0 1 SYSTEM READ WRITE 1014748 2020/11/13 15:4 0 521802 521803 2020/9/6 11 503316480 61440 0 8192 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF 0 8192 NONE 0
2 519918 2007/4/17 6:0 1 2 ONLINE READ WRITE 1014748 2020/11/13 15:4 0 521802 521803 2020/9/6 11 73400320 8960 0 8192 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS01.DBF 0 8192 NONE 0
3 5554 2007/4/17 3:3 2 3 ONLINE READ WRITE 1014748 2020/11/13 15:4 0 521802 521803 2020/9/6 11 272629760 33280 0 8192 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSAUX01.DBF 0 8192 NONE 0
4 9202 2007/4/17 3:3 4 4 ONLINE READ WRITE 1014748 2020/11/13 15:4 0 521802 521803 2020/9/6 11 5242880 640 0 8192 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF 0 8192 NONE 0
5 546572 2020/9/6 11:0 6 5 ONLINE READ WRITE 1014748 2020/11/13 15:4 0 0 0 104857600 12800 104857600 8192 C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EXAMPLE01.DBF 0 8192 NONE 0
6 1021166 2020/11/13 17 7 6 ONLINE READ WRITE 1021170 2020/11/13 17:0 0 0 0 2097152 256 2097152 8192 C:\ORACLE\PRODUCT\10.2.0\DB_1\DATABASE\TEST1.DBF 0 8192 NONE 0
7 1021169 2020/11/13 17 7 7 ONLINE READ WRITE 1021170 2020/11/13 17:0 0 0 0 5242880 640 5242880 8192 C:\ORACLE\PRODUCT\10.2.0\DB_1\DATABASE\TEST2.DBF 0 8192 NONE 0
8 1021775 2020/11/13 17 8 8 ONLINE READ WRITE 1021779 2020/11/13 17:2 0 0 0 2097152 256 2097152 8192 C:\ORACLE\PRODUCT\10.2.0\DB_1\DATABASE\TEST3.DBF 0 8192 NONE 0
9 1021778 2020/11/13 17 8 9 ONLINE READ WRITE 1021779 2020/11/13 17:2 0 0 0 5242880 640 5242880 8192 C:\ORACLE\PRODUCT\10.2.0\DB_1\DATABASE\TEST4.DBF 0 8192 NONE 0
10 1021995 2020/11/13 17 9 10 ONLINE READ WRITE 1021999 2020/11/13 17:3 0 0 0 2097152 256 2097152 8192 C:\ORACLE\PRODUCT\10.2.0\DB_1\DATABASE\TEST5.DBF 0 8192 NONE 0
11 1021998 2020/11/13 17 9 11 ONLINE READ WRITE 1021999 2020/11/13 17:3 0 0 0 5242880 640 5242880 8192 C:\ORACLE\PRODUCT\10.2.0\DB_1\DATABASE\TEST6.DBF 0 8192 NONE 0
11 rows selected
SQL>
SQL> create tablespace table4
2 datafile 'c:/test5.dbf' size 2M,
3 'c:/test6.dbf' size 5M
4 extent management local autoallocate
5 segment space management auto;
Tablespace created
经过上述一系列操作后表空间创建结果如下:
(注意在创建表空间时,我们所规定的dbf文件所在位置的不同:如果我们路径名位置写错了(找不到路径),将会存在默认的路径位置。例如:
datafile 'c:test5.dbf' size 2M,
'c:test6.dbf' size 5M…
与datafile 'c:/test5.dbf' size 2M,
'c:/test6.dbf' size 5M
上面那个路径没有加/导致路径出错,放在默认位置
删除表空间(先创建后删除):
SQL>create table t1
2 (no int)
3 tablespace ts1;
Table created
SQL> drop tablespace ts1 including contents and datafiles;
Tablespace dropped
SQL> create temporary tablespace tmptbs
2 tempfile 'c:\tmptbs.dbf'
3 size 2m reuse
4 EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1m;
Tablespace created
(由于文件过大,不在机器上实验,以免造成空间浪费或者资源调度空间不够导致宕机):
create bigfile tablespace bigtbs
datafile 'c:\bigtbs.dbf' size 10G;
SQL> create undo tablespace undotbs01
2 datafile 'c:\undotbs02.dbf' size 2m reuse;
Tablespace created
将表空间test1设置为脱机状态:
SQL> Alter tablespace test1 OFFLINE;
Tablespace altered
有的时候在online状态下是不允许改名的,显示该文件正在使用,这时就可以先将表空间状态修改为offline状态之后再进行改名:
SQL> alter tablespace test1 rename to t2;
Tablespace altered
SQL> Alter tablespace t2
2 add datafile 'c:\101.dbf' size 1m
3 reuse;
Tablespace altered
SQL> Alter database orcl datafile 'c:\101.dbf' resize 2m;
Database altered
(四步:修改表空间状态为offline,物理方式手动移动,将表空间中文件的原名称和路径修改为新的路径和名称(在这里可以实现改名),修改表空间的状态为online)。
SQL> alter tablespace table2 offline ;
Tablespace altered
物理方式手动移动数据文件。
SQL> alter tablespace table2 rename datafile 'c:\test3.dbf' to 'd:\t3.dbf';
Tablespace altered
SQL> alter tablespace table2 online ;
Tablespace altered
SQL> alter tablespace table2 read only;
Tablespace altered
在设置之前table2应该为只读状态,否则此时无法设置为读写。
SQL> alter tablespace table2 read write;
Tablespace altered
数据库实验第十二周
SQL> declare
2 cursor my_cursor
3 is select xh from xs;
4 v_xh xs.xh%type;
5 begin
6 open my_cursor;
7 fetch my_cursor into v_xh;
8 dbms_output.put_line(v_xh);
9 dbms_output.put_line(my_cursor%rowcount);
10 Close my_cursor;
11 exception
12 when others then
13 dbms_output.put_line(sqlcode||sqlerrm);
14 end;
15 /
061101
1
PL/SQL procedure successfully completed
SQL> select xh from xs;
XH
------
061101
101112
001
121112
SQL> declare
2 cursor c_1 is select * from xs;
3 v_1 c_1%rowtype;
4 begin
5 if c_1%isopen=false then
6 open c_1;
7 end if;
8 fetch c_1 into v_1;
9 dbms_output.put_line(v_1.xh||v_1.xm||v_1.zxf);
10 close c_1;
11 end;
12 /
061101王林50
PL/SQL procedure successfully completed
SQL> select * from xs;
XH XM ZYM XB CSSJ ZXF BZ
------ ------ ------ -- ----------- --- --------------------
061101 王林 计算机 男 1986/2/10 50
101112 李明 计算机 男 1986/1/30 36
001 张琼 计算机 45 三好学生
121112 王小二 计算机 男 1986/1/30 36
SQL>
2 DECLARE
3 TYPE emp_record_type IS RECORD(
4 f_name scott.emp.ename%TYPE,
5 h_date scott.emp.hiredate%TYPE);
6 v_1 EMP_RECORD_TYPE;
7 CURSOR c3(v_deptno NUMBER,v_job VARCHAR2)
8 --声明游标,有参数有返回值
9 RETURN EMP_RECORD_TYPE
10 IS
11 SELECT ename, hiredate FROM scott.emp
12 WHERE deptno=v_deptno AND job =v_job;
13 BEGIN
14 OPEN c3(v_job=>'MANAGER', v_deptno=>10);
15 --打开游标,传递参数值
16 LOOP
17 FETCH c3 INTO v_1; --提取游标
18 IF c3%FOUND THEN
19 DBMS_OUTPUT.PUT_LINE(v_1.f_name||'的雇佣日期是' ||v_1.h_date);
20 ELSE
21 DBMS_OUTPUT.PUT_LINE('已经处理完结果集了');
22 EXIT;
23 END IF;
24 END LOOP;
25 CLOSE c3; --关闭游标
26 END;
27 /
CLARK的雇佣日期是09-6月 -81
已经处理完结果集了
PL/SQL procedure successfully completed
SQL> SELECT ename, hiredate FROM scott.emp WHERE deptno>10 AND job='MANAGER';
ENAME HIREDATE
---------- -----------
JONES 1981/4/2
BLAKE 1981/5/1
SQL> SELECT ename, hiredate FROM scott.emp WHERE deptno>=10 AND job>='MANAGER';
ENAME HIREDATE
---------- -----------
ALLEN 1981/2/20
WARD 1981/2/22
JONES 1981/4/2
MARTIN 1981/9/28
BLAKE 1981/5/1
CLARK 1981/6/9
KING 1981/11/17
TURNER 1981/9/8
8 rows selected
/*
DECLARE
CURSOR cursor_name IS SELECT…;
BEGIN
OPEN cursor_name;
FETCH…INTO…;
WHILE cursor_name%FOUND
LOOP
……
FETCH…INTO…;
END LOOP;
CLOSE cursor;
END;
注:在打开游标后用fetch语句先取一行到变量,然后再用while对该游标进行判断,而不是打开后就立即用while进行判断 。
*/
/*
系统隐含地定义了一个数据类型为%ROWTYPE的变量,并以此作为循环的计算器。
系统自动打开游标,不用显式地使用OPEN语句打开;
系统重复地自动从游标工作区中fetch数据并放入计数器变量中。
系统自动进行%FOUND属性检查以确定是否有数据
当游标工作区中所有的记录都被提取完毕或循环中断时,系统自动地关闭游标。
DECLARE
CURSOR cursor_name IS SELECT…;
BEGIN
FOR loop_variable IN 游标名称
LOOP
……
END LOOP;
END;
*/
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0
Connected as system@ORCL
SQL> set serveroutput on;
SQL> select * from xs;
XH XM ZYM XB CSSJ ZXF BZ
------ ------ ------ -- ----------- --- --------------------
061101 王林 计算机 男 1986/2/10 50
101112 李明 计算机 男 1986/1/30 36
001 张琼 计算机 45 三好学生
121112 王小二 计算机 男 1986/1/30 36
2 DECLARE
3 v_xh char;
4 v_zxf number(2);
5 /* 定义游标is select from */
6 CURSOR XS_CUR3
7 IS SELECT XH,ZXF FROM XS;
8 BEGIN
9 /* 打开游标 */
10 OPEN XS_CUR3;
11 /* 游标赋值fetch into */
12 FETCH XS_CUR3 INTO v_xh,v_zxf;
13 /*游标遍历while found条件*/
14 WHILE XS_CUR3%FOUND
15 LOOP
16 dbms_output.put_line('学号: '||v_xh||' 总学分:'||v_zxf);
17 FETCH XS_CUR3 INTO v_xh,v_zxf;
18 END LOOP;
19 /* 遍历执行完毕,关闭游标 */
20 CLOSE XS_CUR3;
21 END;
22 /
学号: 061101 总学分:50
学号: 101112 总学分:36
学号: 001 总学分:45
学号: 121112 总学分:36
PL/SQL procedure successfully completed
利用游标WHILE循环统计并输出scott.emp表各个部门的平均工资, 若平均工资大于2000,则输出“该部门平均工资较高。”
3 DECLARE
4 CURSOR c_dept_stat IS SELECT deptno,avg(sal) avgsal FROM scott.emp GROUP BY deptno;
5 v_dept c_dept_stat%ROWTYPE;
6 BEGIN
7 OPEN c_dept_stat;
8 FETCH c_dept_stat INTO v_dept;
9 WHILE c_dept_stat%FOUND LOOP
10 DBMS_OUTPUT.PUT_LINE('部门号为'||v_dept.deptno||' '||'平均工资为'||trunc(v_dept.avgsal,1));
11 if (v_dept.avgsal>=2000) then
12 dbms_output.put_line(v_dept.deptno||'号部门工资较高');
13 end if;
14 FETCH c_dept_stat INTO v_dept;
15 END LOOP;
16 CLOSE c_dept_stat;
17 END;
18 /
部门号为30 平均工资为1566.6
部门号为20 平均工资为2175
20号部门工资较高
部门号为10 平均工资为2916.6
10号部门工资较高
PL/SQL procedure successfully completed
SQL> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
SQL> SELECT deptno,avg(sal) avgsal FROM scott.emp GROUP BY deptno;
DEPTNO AVGSAL
------ ----------
30 1566.66666
20 2175
10 2916.66666
SQL>
2 DECLARE
3 CURSOR c_1 IS SELECT deptno,avg(sal) avgsal FROM scott.emp GROUP BY deptno;
4 V_dept c_1%ROWTYPE;
5 BEGIN
6 FOR v_dept IN c_1
7 LOOP
8 DBMS_OUTPUT.PUT_LINE('部门号: '||v_dept.deptno||' 平均工资: '||v_dept.avgsal);
9 END LOOP;
10 END;
11 /
部门号: 30 平均工资: 1566.666666666666666666666666666666666667
部门号: 20 平均工资: 2175
部门号: 10 平均工资: 2916.666666666666666666666666666666666667
PL/SQL procedure successfully completed
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0
Connected as system@ORCL
SQL> conn system/test
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0
Connected as system
SQL> set serveroutput on;
SQL>
数据库实验第十三周
带update的游标,loop EXIT WHEN -end loop;Scott.emp表,利用游标,给工资低于1200 的员工增加工资50。并输出“编码为’员工编码号’的工资已经更新”
4 DECLARE
5 v_empno scott.emp.empno%TYPE;
6 v_sal scott.emp.sal%TYPE;
7 CURSOR c_cursor IS SELECT empno,sal FROM scott.emp;
8 BEGIN
9 --打开游标
10 OPEN c_cursor;
11 --循环遍历操作 loop-end loop;
12 LOOP
13 FETCH c_cursor INTO v_empno, v_sal;
14 --exit when %notfound
15 EXIT WHEN c_cursor%NOTFOUND;
16 --查询条件,满足则执行update操作 if-end if;
17 IF v_sal<=1200 THEN
18 UPDATE scott.emp SET Sal=Sal+50 WHERE empno=v_empno;
19 DBMS_OUTPUT.PUT_LINE('编码为'||v_empno||'工资已更新!');
20 END IF;
21 DBMS_OUTPUT.PUT_LINE('记录数:'|| c_cursor %ROWCOUNT);
22 END LOOP;
23 CLOSE c_cursor;
24 END;
25 /
编码为7369工资已更新!
记录数:1
记录数:2
记录数:3
记录数:4
记录数:5
记录数:6
记录数:7
记录数:8
记录数:9
记录数:10
编码为7876工资已更新!
记录数:11
编码为7900工资已更新!
记录数:12
记录数:13
记录数:14
PL/SQL procedure successfully completed
SQL>
SQL> DECLARE
2 v_empno scott.emp.empno%TYPE;
3 v_sal scott.emp.sal%TYPE;
4 --定义游标的时候标明update: for update
5 CURSOR c_cursor IS SELECT empno,sal FROM scott.emp where sal<1200 for update;
6 begin
7 open c_cursor;
8 LOOP
9 FETCH c_cursor INTO v_empno, v_sal;
10 EXIT WHEN c_cursor%NOTFOUND;
11 --不再记录员工编号进行等值查询,而是查找当前游标所在的那一条位置: where current of c_cursor
12 UPDATE scott.emp SET Sal=Sal+50 WHERE current of c_cursor;
13 DBMS_OUTPUT.PUT_LINE('编码为'||v_empno||'工资已更新!');
14 DBMS_OUTPUT.PUT_LINE('记录数:'|| c_cursor%ROWCOUNT);
15 END LOOP;
16 CLOSE c_cursor;
17 END;
18 /
编码为7369工资已更新!
记录数:1
编码为7900工资已更新!
记录数:2
PL/SQL procedure successfully completed
SQL>
for循环 FOR v_emp IN c_emp LOOP -END LOOP;修改scott.emp表员工的工资,如果员工的部门号为10,工资提高100;部门号为20,工资提高150;部门号为30,工资提高200;否则工资提高250。
3 DECLARE
4 CURSOR c_emp IS SELECT * FROM scott.emp FOR UPDATE;
5 v_zl NUMBER;
6 v_emp c_emp%rowtype;
7 BEGIN
8 FOR v_emp IN c_emp LOOP
9 CASE v_emp.deptno
10 WHEN 10 THEN v_zl:=100;
11 WHEN 20 THEN v_zl:=150;
12 WHEN 30 THEN v_zl:=200;
13 ELSE v_zl:=250;
14 END CASE;
15 UPDATE scott.emp SET sal=sal+v_zl WHERE CURRENT OF c_emp;
16 END LOOP;
17 END;
18 /
PL/SQL procedure successfully completed
SQL> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 1150.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1800.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1450.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 3125.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1450.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 3050.00 30
7782 CLARK MANAGER 7839 1981/6/9 2550.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3150.00 20
7839 KING PRESIDENT 1981/11/17 5100.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1700.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1400.00 20
7900 JAMES CLERK 7698 1981/12/3 1350.00 30
7902 FORD ANALYST 7566 1981/12/3 3150.00 20
7934 MILLER CLERK 7782 1982/1/23 1400.00 10
14 rows selected
SQL>
修改emp表的工资,工资不足1000的,调整为1500,工资高于1000的,调整为原来工资的1.5倍,调整后,若工资〉10000,则设其为10000。
3 declare
4 cursor c_1 is
5 select empno,sal from scott.emp
6 for update of sal nowait;
7 v_sal scott.emp.sal%type;
8 begin
9 for cursor_1 in c_1
10 loop
11 if cursor_1.sal<=1000 then
12 v_sal:=1500;
13 else
14 v_sal:=cursor_1.sal*1.5;
15 if v_sal>10000 then
16 v_sal:=10000;
17 end if;
18 end if;
19 update scott.emp set sal=v_sal where current of c_1;
20 end loop;
21 end;
22 /
PL/SQL procedure successfully completed
SQL> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 1725.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 2700.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 2175.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 4687.50 20
7654 MARTIN SALESMAN 7698 1981/9/28 2175.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 4575.00 30
7782 CLARK MANAGER 7839 1981/6/9 3825.00 10
7788 SCOTT ANALYST 7566 1987/4/19 4725.00 20
7839 KING PRESIDENT 1981/11/17 7650.00 10
7844 TURNER SALESMAN 7698 1981/9/8 2550.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 2100.00 20
7900 JAMES CLERK 7698 1981/12/3 2025.00 30
7902 FORD ANALYST 7566 1981/12/3 4725.00 20
7934 MILLER CLERK 7782 1982/1/23 2100.00 10
14 rows selected
SQL> declare
2 type t_dept is REF CURSOR return scott.emp%rowtype;
3 c_1 t_dept;
4 v_row scott.emp%rowtype;
5 begin
6 open c_1 for select * from scott.emp where deptno=10;
7 fetch c_1 into v_row;
8 dbms_output.put_line(v_row.empno||' ' ||v_row.job);
9 close c_1;
10
11 open c_1 for select * from scott.emp where sal>=2000;
12 fetch c_1 into v_row;
13 dbms_output.put_line(v_row.deptno||' ' ||v_row.job);
14 close c_1;
15 end;
16 /
7782 MANAGER
30 SALESMAN
PL/SQL procedure successfully completed
SQL>
数据库实验第十四周
SQL> CREATE OR REPLACE PROCEDURE HelloWorld3 (
2 p_user_name VARCHAR2,
3 p_val1 VARCHAR2 DEFAULT ' Good Moning,',
4 p_val2 VARCHAR2 DEFAULT ' Nice to Meet you') AS
5 BEGIN
6 dbms_output.put_line('Hello ' || p_user_name || p_val1 || p_val2 || '!');
7 END HelloWorld3;
8 /
Procedure created
SQL>
SQL> BEGIN
2 HelloWorld3('Edward');
3 HelloWorld3('Edward', ' Good Night,');
4 HelloWorld3('Edward', ' Good Night,', 'Bye');
5 END;
6 /
Hello Edward Good Moning, Nice to Meet you!
Hello Edward Good Night, Nice to Meet you!
Hello Edward Good Night,Bye!
PL/SQL procedure successfully completed
SQL>
SQL> BEGIN
2 HelloWorld3('Edward');
3 HelloWorld3('Edward', p_val1 => ' Good Night,');
4 HelloWorld3('Edward', p_val1 => ' Good Night,', p_val2 => 'Bye');
5 HelloWorld3('Edward', p_val2 => ' HeiHei ');
6 END;
7 /
Hello Edward Good Moning, Nice to Meet you!
Hello Edward Good Night, Nice to Meet you!
Hello Edward Good Night,Bye!
Hello Edward Good Moning, HeiHei !
PL/SQL procedure successfully completed
SQL>
Connected to Oracle Database 12c Enterprise Edition Release 12.2.0.1.0
Connected as C##scott@ORCL
在存储过程界面添加存储过程:
create or replace procedure update_emp
as
begin
update C##scott.emp set ename='candy1' where empno=7876;
end update_emp;
SQL> begin
2 update_emp;
3 end;
4 /
PL/SQL procedure successfully completed
第一次存储过程执行完毕,查询执行结果发现7876编号名称改为candy:
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 0087/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 candy CLERK 7788 0087/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
二次单独查询7876编号,发现又被改回去了:
SQL> select * from emp where empno = 7876;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7876 ADAMS CLERK 7788 0087/5/23 1100.00 20
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 0087/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 0087/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
再次执行存储过程:
SQL>
SQL> begin
2 update_emp;
3 end;
4 /
PL/SQL procedure successfully completed
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 0087/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 candy1 CLERK 7788 0087/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
再次执行二次查询:
SQL> select * from emp where empno = 7876;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7876 ADAMS CLERK 7788 0087/5/23 1100.00 20
删除存储过程:
SQL> DROP PROCEDURE update_emp;
Procedure dropped
数据库实验第十五周
create or replace trigger del_xs
before delete on xs
for each row
begin
insert into xs_2 (xh,xm,zym,xb,cssj,zxf) values (:old.xh,:old.xm, :old.zym, :old.xb, :old.cssj,:old.zxf);
end del_xs;
SQL> select * from xs;
XH XM ZYM XB CSSJ ZXF BZ
------ ------ ------ -- ----------- --- --------------------
061101 王林 计算机 男 1986/2/10 50
101112 李明 计算机 男 1986/1/30 36
001 张琼 计算机 45 三好学生
121112 王小二 计算机 男 1986/1/30 36
SQL> delete from xs where xh=001;
1 row deleted
此时该行数据将会在新创建的表中找到。
将对xs表的操作记录(insert,delete,update)在sql_info表中记录下来:
SQL> select * from sql_info;
INFO TIME
---------- -----------
SQL> insert into xs(xh,xm,zym) values ('002','hello','nan');
1 row inserted
SQL> select * from sql_info;
INFO TIME
---------- -----------
插入 2020/12/11
create or replace trigger t2
after delete or insert or update on xs
for each row
declare
v_info sql_info.info%type;
begin
if inserting then
v_info:='插入';
elsif updating then
v_info:='更新';
else
v_info:='删除';
end if;
insert INTO SQL_INFO VALUES(v_info,sysdate);
end t2;
创建一个触发器,输出对scott.emp表的操作(插入后员工号和员工名,更新后员工工资,删除的员工号和员工名。):
CREATE OR REPLACE TRIGGER t3
BEFORE INSERT OR UPDATE OR DELETE ON scott.emp
FOR EACH ROW
BEGIN
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE(:new.empno||' '||:new.ename);
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE(:old.sal||' '||:new.sal);
ELSE
DBMS_OUTPUT.PUT_LINE(:old.empno||' '|| :old.ename);
END IF;
END t3;
SQL> set serveroutput on;
SQL>
SQL> declare
2 begin
3 update scott.emp set empno=7521 where empno=7522;
4 commit;
5 end;
6 /
更新记录后平均工资为 2073.21
针对Scott.emp表,记录其相应操作的信息,具体如下:
当执行插入操作时,统计操作后员工人数;当执行更新工资操作时,统计更新后员工平均工资;当执行删除操作时,统计删除后各个部门剩余的人数(游标):
CREATE OR REPLACE TRIGGER t4
AFTER INSERT OR UPDATE OR DELETE
ON scott.emp
declare
v_1 number; v_2 scott.emp.sal%type;
begin
if inserting then
select count(*) into v_1 from scott.emp;
DBMS_OUTPUT.PUT_LINE('添加记录后总人数为'||v_1);
elsif updating then
select avg(sal) into v_2 from scott.emp;
DBMS_OUTPUT.PUT_LINE('更新记录后平均工资为'||' '||v_2);
else
for v_s in (select deptno,count(*) num from scott.emp group by deptno)
loop
DBMS_OUTPUT.PUT_LINE('删除记录后各个部门的部门号和人数为' ||v_s.deptno||' '||v_s.num);
end loop;
end if;
end t4;
SQL> delete from scott.emp where hiredate<=to_date('1980-12-17','yyyy-mm-dd');
7369 SMITH
删除记录后各个部门的部门号和人数为30 6
删除记录后各个部门的部门号和人数为20 4
删除记录后各个部门的部门号和人数为10 3
1 row deleted
数据库实验第十六周
创建一个存储过程,以部门号为该存储过程的in类型参数,查询该部门的平均工资,并输出该部门中比平均工资高的员工号、员工名。(for 循环遍历 游标):
- CREATE&nbs***bsp;REPLACE PROCEDURE show_emp(
- p_deptno emp.deptno%TYPE)
- AS
- v_sal emp.sal%TYPE;
- BEGIN
- SELECT avg(sal) INTO v_sal FROM emp WHERE deptno=p_deptno;
- DBMS_OUTPUT.PUT_LINE(p_deptno||' '||'average salary is:'||v_sal);
- FOR v_emp IN (SELECT * FROM emp WHERE deptno=p_deptno AND sal>v_sal)
- LOOP
- DBMS_OUTPUT.PUT_LINE(v_emp.empno||' '||v_emp.ename);
- END LOOP;
- END show_emp;
SQL> set serverout on;
SQL> begin
2 show_emp(20);
3 end;
4 /
20 average salary is:2175
7566 JONES
7788 SCOTT
7902 FORD
PL/SQL procedure successfully completed
用存储过程进行模糊查找,如查找ename中包含L的雇员信息:
- create&nbs***bsp;replace procedure Tp1
- (varEmpName emp.ename%type)
- is
- --cursor c_1 is select * from scott.emp where ename like '%'||varEmpName||'%';
- begin
- for v_1 in (select * from emp where ename like '%'||varEmpName||'%')
- loop
- dbms_output.put_line(v_1.empno||' '||v_1.ename||' '||v_1.job||' '||v_1.deptno);
- end loop;
- end;
SQL> begin
2 tp1('L');
3 end;
4 /
7499 ALLEN SALESMAN 30
7698 BLAKE MANAGER 30
7782 CLARK MANAGER 10
7934 MILLER CLERK 10
PL/SQL procedure successfully completed
SQL> select * from xs;
XH XM ZYM XB CSSJ ZXF BZ
------ ------ ------ -- ----------- --- --------------------
061101 王林 计算机 男 1986/2/10 50
101112 李明 计算机 男 1986/1/30 36
001 张琼 计算机 45 三好学生
121112 王小二 计算机 男 1986/1/30 36
SQL> select * from xs where rownum<=2;
XH XM ZYM XB CSSJ ZXF BZ
------ ------ ------ -- ----------- --- --------------------
061101 王林 计算机 男 1986/2/10 50
101112 李明 计算机 男 1986/1/30 36
SQL> select deptno,count(*) PersonNum,avg(sal) avgsal from scott.emp
2 group by deptno
3 order by PersonNum desc;
DEPTNO PERSONNUM AVGSAL
------ ---------- ----------
30 6 1566.66666
20 5 2175
10 3 2916.66666
注意上述查询在使用rownum时不能直接写成如下格式:
SQL> select deptno,count(*) PersonNum,avg(sal) avgsal from scott.emp
2 group by deptno
3 order by PersonNum desc
- where rownum<=1;
ORA-00933: SQL 命令未正确结束
否则会报ORA-00933: SQL 命令未正确结束错误。
正确做法:
再写一层查询嵌套内部查询:
SQL> select * from(
2 select deptno,count(*) PersonNum,avg(sal) avgsal from emp
3 group by deptno
4 order by PersonNum desc)
5 where rownum<=1;
DEPTNO PERSONNUM AVGSAL
------ ---------- ----------
30 6 1566.66666
SQL>
补充内容
一、
LOOP
Exit when...
END LOOP;
二、
WHILE
LOOP
END LOOP;
三、
FOR count IN count_1...count_n
LOOP
END LOPP;
For循环中的逆序:
for n in reverse 1..10
一、
LOOP
Exit when...
END LOOP;
Command:
SEt SERVEROUTPUT on;
DECLARE
s NUMBER:=1;
n NUMBER:=2;
BEGIN
LOOP
s:=s*n;
n:=n+1;
exit when n>10;
END LOOP;
dbms_output.put_line(to_char(s));
END;
/
实现:
SQL> SEt SERVEROUTPUT on;
SQL> DECLARE
2 s NUMBER:=1;
3 n NUMBER:=2;
4 BEGIN
5 LOOP
6 s:=s*n;
7 n:=n+1;
8 exit when n>10;
9 END LOOP;
10 dbms_output.put_line(to_char(s));
11 END;
12 /
3628800
PL/SQL procedure successfully completed
二、
WHILE
LOOP
END LOOP;
Command:
DECLARE
s NUMBER:=1;
n NUMBER:=2;
BEGIN
while n<=10
LOOP
s:=s*n;
n:=n+1;
end LOOP;
dbms_output.put_line(to_char(s));
END;
实现:
SQL> DECLARE
2 s NUMBER:=1;
3 n NUMBER:=2;
4 BEGIN
5 while n<=10
6 LOOP
7 s:=s*n;
8 n:=n+1;
9 end LOOP;
10 dbms_output.put_line(to_char(s));
11 END;
12 /
3628800
PL/SQL procedure successfully completed
三、
FOR count IN count_1...count_n
LOOP
END LOPP;
Command:
DECLARE
s NUMBER:=1;
n NUMBER:=2;
BEGIN
for n in 2..10
Loop
s:=s*n;
end loop;
dbms_output.put_line(to_char(s));
END;
实现:
SQL> DECLARE
2 s NUMBER:=1;
3 n NUMBER:=2;
4 BEGIN
5 for n in 2..10
6 Loop
7 s:=s*n;
8 end loop;
9 dbms_output.put_line(to_char(s));
10 END;
11 /
3628800
PL/SQL procedure successfully completed
For循环中的逆序:
for n in reverse 1..10
Command:
DECLARE
s NUMBER:=1;
n NUMBER:=2;
begin
for n in reverse 1..10
loop
s:=s*n;
dbms_output.put_line(to_char(n));
end loop;
dbms_output.put_line(to_char(s));
END;
实现:
SQL> DECLARE
2 s NUMBER:=1;
3 n NUMBER:=2;
4 begin
5 for n in reverse 1..10
6 loop
7 s:=s*n;
8 dbms_output.put_line(to_char(n));
9 end loop;
10 dbms_output.put_line(to_char(s));
11 END;
12 /
10
9
8
7
6
5
4
3
2
1
3628800
PL/SQL procedure successfully completed
Command:
declare
i int;a int;b int;c int;
begin
for i in 100..999
loop
a:= trunc(i/100);
b:=trunc(i/10) mod 10;
c:=i mod 10;
-- dbms_output.put_line(a||' '||b||' '||c);
if (i=a*a*a+b*b*b+c*c*c) then
dbms_output.put_line(i);
end if;
end loop;
end;
/
实现:
SQL> set serveroutput on;
SQL> declare
2 i int;a int;b int;c int;
3 begin
4 for i in 100..999
5 loop
6 a:= trunc(i/100);
7 b:=trunc(i/10) mod 10;
8 c:=i mod 10;
9 -- dbms_output.put_line(a||' '||b||' '||c);
10 if (i=a*a*a+b*b*b+c*c*c) then
11 dbms_output.put_line(i);
12 end if;
13 end loop;
14 end;
15 /
153
370
371
407
PL/SQL procedure successfully completed
首先创建保存记录的表:
SQL> create table u_1
2 ( username varchar2(50),
3 activity varchar2(20),
4 time date
5 )
6 ;
Table created
SQL> select username,activity,to_char(time,'yyyy-MM-dd HH24:mi') from u_1;
USERNAME ACTIVITY TO_CHAR(TIME,'YYYY-MM-DDHH24:MI')
-------------------------------------------------- -------------------- ---------------------------------
C##SCOTT LOGON 2020-12-19 23:41
C##SCOTT LOGON 2020-12-19 23:41
C##SCOTT LOGON 2020-12-19 23:41
SYS LOGON 2020-12-19 23:41
SYS LOGON 2020-12-19 23:41
SYSTEM LOGON 2020-12-19 23:42
SYSTEM LOGON 2020-12-19 23:42
SYSTEM LOGON 2020-12-19 23:42
SYS LOGON 2020-12-20 10:09
SYS LOGON 2020-12-20 10:09
SYS LOGON 2020-12-20 10:09
SYS LOGON 2020-12-20 10:09
SYS LOGON 2020-12-20 10:09
SYS LOGON 2020-12-20 10:09
SYS LOGON 2020-12-20 10:09
SYS LOGON 2020-12-20 10:09
SYS LOGON 2020-12-20 10:09
SYS LOGON 2020-12-20 10:09
SYS LOGON 2020-12-20 10:09
SYS LOGON 2020-12-20 10:09
USERNAME ACTIVITY TO_CHAR(TIME,'YYYY-MM-DDHH24:MI')
-------------------------------------------------- -------------------- ---------------------------------
SYSTEM LOGON 2020-12-20 10:12
SYSTEM LOGON 2020-12-20 10:12
SYSTEM LOGON 2020-12-20 10:12
23 rows selected
创建logoff触发器,在退出登录的时候进行记录(注意此时的触发器时间上不要采用after,因为采用after客户机注销进程终止,不能进行其他操作):
首先创建保存记录的表:
SQL> create table u_2
2 ( username varchar2(50),
3 activity varchar2(20),
4 time date
5 )
6 ;
Table created
SQL>
将触发器的after改成before:
create or replace trigger st2
before logoff on database
begin
insert into u_2 values(user,'LOGOFF',sysdate);
END st2;
SQL> select username,activity,to_char(time,'yyyy-MM-dd HH24:mi') from u_2;
USERNAME ACTIVITY TO_CHAR(TIME,'YYYY-MM-DDHH24:MI')
-------------------------------------------------- -------------------- ---------------------------------
退出后查询表:
SQL> select username,activity,to_char(time,'yyyy-MM-dd HH24:mi') from u_2;
USERNAME ACTIVITY TO_CHAR(TIME,'YYYY-MM-DDHH24:MI')
-------------------------------------------------- -------------------- ---------------------------------
SYSTEM LOGOFF 2020-12-20 10:42
SYSTEM LOGOFF 2020-12-20 10:42
SYSTEM LOGOFF 2020-12-20 10:42
查询sysdate并转换为char格式输出:
SQL> Select to_char(sysdate,'yyyy-MM-dd HH24:mi') from dual;
TO_CHAR(SYSDATE,'YYYY-MM-DDHH24:MI')
------------------------------------
2020-12-20 11:06
SQL> Select to_char(sysdate, 'DAY') from dual;
TO_CHAR(SYSDATE,'DAY')
----------------------
星期日
SQL>
Connected to Oracle Database 12c Enterprise Edition Release 12.2.0.1.0
Connected as C##scott
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 0087/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 candy1 CLERK 7788 0087/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
设置触发器:作用为禁止在休息日(周六、周天)改变scott.emp雇员信息(包括添加删除和修改)。
create or replace trigger tr_sec_emp
before insert or update or delete on emp
begin
if to_char(sysdate, 'DAY') in ('星期六','星期日') then
raise_application_error(-20001,'不能在休息日修改员工信息');
end if;
end;
SQL> update emp set ename='candy' where empno=7876;
update emp set ename='candy' where empno=7876
ORA-20001: 不能在休息日修改员工信息
ORA-06512: 在 "C##SCOTT.TR_SEC_EMP", line 3
ORA-04088: 触发器 'C##SCOTT.TR_SEC_EMP' 执行过程中出错
上述不能执行的同时给出了相关触发器和触发器代码限制的所在行数。
关闭相应触发器:
SQL> Alter trigger tr_sec_emp disable;
Trigger altered
SQL> update emp set ename='candy' where empno=7876;
1 row updated
SQL> select * from emp where empno=7876;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7876 candy CLERK 7788 0087/5/23 1100.00 20
打开触发器后则又不能在规定范围内进行修改:
SQL> Alter trigger tr_sec_emp enable;
Trigger altered
SQL> update emp set ename='candytest' where empno=7876;
update emp set ename='candytest' where empno=7876
ORA-20001: 不能在休息日修改员工信息
ORA-06512: 在 "C##SCOTT.TR_SEC_EMP", line 3
ORA-04088: 触发器 'C##SCOTT.TR_SEC_EMP' 执行过程中出错
Alter trigger 触发器名字 disable;
Alter trigger 触发器名字 enable;
关闭某表的所有触发器
alter table 表名字 disable all triggers ;
开启所有触发器
alter table 表名字 enable all triggers ;
存储过程要注意权限问题,很有可能权限不足,比如有时候在system用户下对scott的表进行操作等可能会出现权限问题,这个时候可以退出system用户(或者退出当前用户切换或者重新打开一个oracle进程登录(一台机器可允许多个oracle用户登录)),然后重新编译关于scott的存储过程即可编译成功。(即使有时候在system用户下可以编译运行也不是永久的修改,而只是临时的修改,再次运行程序可能会发现其中的数据并没有修改,只是在存储过程执行的后一次实现了临时性的结果展示,并没有对数据进行永久的替换保存,这一点需要注意。)
例一(权限不足):
例二(临时性结果展示,未保存到数据库内部):
在存储过程界面添加存储过程:
create or replace procedure update_emp
as
begin
update C##scott.emp set ename='candy1' where empno=7876;
end update_emp;
SQL> begin
2 update_emp;
3 end;
4 /
PL/SQL procedure successfully completed
第一次存储过程执行完毕,查询执行结果发现7876编号名称改为candy:
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 0087/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 candy1 CLERK 7788 0087/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
二次单独查询7876编号,发现又被改回去了:
SQL> select * from emp where empno = 7876;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7876 ADAMS CLERK 7788 0087/5/23 1100.00 20
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 0087/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 0087/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
再次执行存储过程:
SQL>
SQL> begin
2 update_emp;
3 end;
4 /
PL/SQL procedure successfully completed
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 0087/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 candy1 CLERK 7788 0087/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
再次执行二次查询:
SQL> select * from emp where empno = 7876;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7876 ADAMS CLERK 7788 0087/5/23 1100.00 20
删除存储过程:
SQL> DROP PROCEDURE update_emp;
Procedure dropped
例三(切换到scott用户之后不再会出现上述两个例子的问题,权限OK,编译compiled successful,执行程序的数据永久保存到数据库中,不会再产生临时性的错误):
SQL> begin
2 update_emp;
3 end;
4 /
PL/SQL procedure successfully completed
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 candy1 CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 candy1 CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 candy1 CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
SQL> select * from emp where ename='candy1';
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7876 candy1 CLERK 7788 1987/5/23 1100.00 20
SQL> DROP PROCEDURE update_emp;
Procedure dropped
Connected to Oracle Database 12c Enterprise Edition Release 12.2.0.1.0
Connected as system@ORCL
SQL> select * from C##Scott.Emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 0087/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 candy1 CLERK 7788 0087/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
SQL>
SQL> declare
2 v_1 number;
3 begin
4 select empno into v_1 from C##Scott.emp;
5 dbms_output.put_line(v_1);
6 exception
7 when no_data_found then
8 dbms_output.put_line('出现no_data_found异常了');
9 when too_many_rows then
10 dbms_output.put_line('出现too_many_rows异常了');
11 when others then
12 dbms_output.put_line('出现others异常了');
13 end;
14 /
出现too_many_rows异常了
PL/SQL procedure successfully completed
SQL>
SQL> declare
2 v_1 number;
3 begin
4 select empno into v_1 from C##Scott.emp where ename = 'test_no_data_found';
5 dbms_output.put_line(v_1);
6 exception
7 when no_data_found then
8 dbms_output.put_line('出现no_data_found异常了');
9 when too_many_rows then
10 dbms_output.put_line('出现too_many_rows异常了');
11 when others then
12 dbms_output.put_line('出现others异常了');
13 end;
14 /
出现no_data_found异常了
PL/SQL procedure successfully completed
PL/SQL中打印错误信息:dbms_output.put_line('错误代码: '||sqlcode||' 错误信息: '||sqlerrm);
SQL> declare
2 v_1 number;
3 begin
4 select empno into v_1 from C##Scott.emp where ename = 'test_no_data_found';
5 dbms_output.put_line(v_1);
6 exception
7 when no_data_found then
8 dbms_output.put_line('出现no_data_found异常了');
9 dbms_output.put_line('错误代码: '||sqlcode||' 错误信息: '||sqlerrm);
10 when too_many_rows then
11 dbms_output.put_line('出现too_many_rows异常了');
12 when others then
13 dbms_output.put_line('出现others异常了');
14 end;
15 /
出现no_data_found异常了
错误代码: 100 错误信息: ORA-01403: 未找到任何数据
PL/SQL procedure successfully completed
SQL>
SQL> declare
2 v_1 number;
3 begin
4 select empno into v_1 from C##Scott.emp;
5 dbms_output.put_line(v_1);
6 exception
7 when no_data_found then
8 dbms_output.put_line('出现no_data_found异常了');
9 dbms_output.put_line('错误代码: '||sqlcode||' 错误信息: '||sqlerrm);
10 when too_many_rows then
11 dbms_output.put_line('出现too_many_rows异常了');
12 dbms_output.put_line('错误代码: '||sqlcode||' 错误信息: '||sqlerrm);
13 when others then
14 dbms_output.put_line('出现others异常了');
15 dbms_output.put_line('错误代码: '||sqlcode||' 错误信息: '||sqlerrm);
16 end;
17 /
出现too_many_rows异常了
错误代码: -1422 错误信息: ORA-01422: 实际返回的行数超出请求的行数
PL/SQL procedure successfully completed
出现代码异常抛出时不再执行下面的语句,直接跳转到异常处理(其中用户自定义异常错误代码为1,错误信息为User-Defined Exception):
SQL> declare
2 v_1 number;
3 e_1 exception;
4 e_2 exception;
5 begin
6 select empno into v_1 from C##Scott.emp where ename = 'candy1';
7 dbms_output.put_line(v_1);
8 if v_1 > 7600 then
9 raise e_1;
10 else
11 raise e_2;
12 end if;
13 exception
14 when e_1 then
15 dbms_output.put_line('test自定义异常,这里以raise代替throws,超过7600号');
16 dbms_output.put_line('错误代码: '||sqlcode||' 错误信息: '||sqlerrm);
17 when e_2 then
18 dbms_output.put_line('test自定义异常,这里以raise代替throws,超过7500号');
19 dbms_output.put_line('错误代码: '||sqlcode||' 错误信息: '||sqlerrm);
20 when others then
21 dbms_output.put_line('出现others异常了');
22 dbms_output.put_line('错误代码: '||sqlcode||' 错误信息: '||sqlerrm);
23 end;
24 /
7876
test自定义异常,这里以raise代替throws,超过7600号
错误代码: 1 错误信息: User-Defined Exception
PL/SQL procedure successfully completed
SQL>
SQL> declare
2 v_1 number;
3 e_1 exception;
4 e_2 exception;
5 begin
6 select empno into v_1 from C##Scott.emp where ename = 'WARD';
7 dbms_output.put_line(v_1);
8 if v_1 > 7600 then
9 raise e_1;
10 else
11 raise e_2;
12 end if;
13 exception
14 when e_1 then
15 dbms_output.put_line('test自定义异常,这里以raise代替throws,超过7600号');
16 dbms_output.put_line('错误代码: '||sqlcode||' 错误信息: '||sqlerrm);
17 when e_2 then
18 dbms_output.put_line('test自定义异常,这里以raise代替throws,超过7500号');
19 dbms_output.put_line('错误代码: '||sqlcode||' 错误信息: '||sqlerrm);
20 when others then
21 dbms_output.put_line('出现others异常了');
22 dbms_output.put_line('错误代码: '||sqlcode||' 错误信息: '||sqlerrm);
23 end;
24 /
7521
test自定义异常,这里以raise代替throws,超过7500号
错误代码: 1 错误信息: User-Defined Exception
PL/SQL procedure successfully completed
SQL>