--创建表 create table test_user( id number, user_name varchar(50), pass_word varchar2(50) ); -- 根据现有的表创建新表,复制表 create table test_user1 as select * from test_user; -- 复制表结构 create table test_user2 as select * from test_user where 1=2; --创建视图,视图是一张需表 create view emp_view as select * from emp; -- 视图是一张虚表 可以insert,update,delete 本质上:修改的是基表 create view emp_dept_view as select emp.empno,emp.ename,dept.deptno,dept.dname from emp,dept where emp.deptno=dept.deptno; -- 创建视图 只授予只读权限 with read only create view emp3 as select * from emp with read only; --添加主键 alter table 表名 add 约束名 alter table test_user add constraint pk_constran primary key(id); --添加唯一约束 alter table test_user add constraint uni_cons unique(user_name); --修改表,添加列 alter table test_user add sex varchar2(5); --添加检查性约束 alter table test_user add constraint check_sex4 check(sex in ('男','女','未知')); insert into test_user values(10001,'admin','123456','男'); insert into test_user values(10002,'admin2','123456','女'); insert into test_user(id,pass_word,sex) values(10003,'123456','未知'); insert into test_user(id,pass_word,sex) values(10004,'123456','未知'); -- 创建用户: create user test_tbl identified by 123456; -- unique 和primary key 的区别: 都是唯一,不能重复 unique 可以为空,并且可以为多个空 序列(SEQUENCE)是一个命名的顺序编号生成器,它能以串行的方式生成一系列顺序整数;序列能生成最大38位的整数;序列名不能重复 --mysql 自增 ,auto_increment --sql server 自增, IDENTITY (1, 1) useGeneratedKeys 获取自增主键 --oracle sequence序列递增 --dual 虚表 新创建的序列,必须先调用过nextval(对序列进行初始化) 才能调用currval select seq_user.currval from dual; --序列的当前值 select seq_user.nextval from dual; --序列的下一个值 --引用序列 序列名.nextval insert into test_user values(seq_user.nextval,'aa09','123456','男'); --rowid 伪列 select rowid,test_user.* from test_user; --rownum 伪列 不能加 表名.rownum select rownum,test_user.* from test_user where rownum<6; select rownum,test_user.* from test_user where rownum>5; select rownum,test_user.* from test_user where rownum=5; select rownum,test_user.* from test_user where rownum!=5; select rownum,test_user.* from test_user where rownum=1; -- 查询>5 <11 select * from (select rownum rw,test_user.* from test_user where rownum<11) where rw>5 select rownum,e.* from (select test_user.* from test_user order by user_name) e; select rownum ,test_user.* from test_user order by sex rownum 注意:只能用以上符号(<、<=、!=)。 select * from tablename where rownum != 10;返回的是前9条记录。 不能用:>,>=,=,Between...and。由于rownum是一个总是从1开始的伪列,Oracle 认为这种条件不成立。 对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,且rownum不能以任何表的名称作为前缀。 (1) rownum 对于等于某值的查询条件 如果希望找到学生表中第一条学生的信息,可以使用rownum=1作为条件。但是想找到学生表中第二条学生的信息,使用rownum=2结果查不到数据。因为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数)。 (2)rownum对于大于某值的查询条件 如果想找到从第二行记录以后的记录,当使用rownum>2是查不出记录的,原因是由于rownum是一个总是从1开始的伪列,Oracle 认为rownum> n(n>1的自然数)这种条件依旧不成立,所以查不到记录。 查找到第二行以后的记录可使用以下的子查询方法来解决。注意子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。 (3)rownum对于小于某值的查询条件 rownum对于rownum<n((n>1的自然数)的条件认为是成立的,所以可以找到记录。 (4)查询rownum在某区间的数据,必须使用子查询。例如要查询rownum在第二行到第三行之间的数据,包括第二行和第三行数据,那么我们只能写以下语句,先让它返回小于等于三的记录行,然后在主查询中判断新的rownum的别名列大于等于二的记录行。但是这样的操作会在大数据集中影响速度。 (5)rownum和排序 Oracle中的rownum的是在取数据的时候产生的序号,所以想对指定排序的数据去指定的rowmun行数据就必须注意了。 rownum并不是按照排序列来生成的序号。系统是按照记录插入时的顺序给记录排的号,rowid也是顺序分配的。 视图简介: 视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改。视图基于的表称为基表。视图是存储在数据字典里的一条select语句。 通过创建视图可以提取数据的逻辑上的集合或组合。 视图的优点: 1.对数据库的访问,因为视图可以有选择性的选取数据库里的一部分。 2.用户通过简单的查询可以从复杂查询中得到结果。 3.维护数据的独立性,试图可从多个表检索数据。 4.对于相同的数据可产生不同的视图。 视图的分类: 视图分为简单视图和复杂视图。 两者区别如下: 1.简单视图只从单表里获取数据,复杂视图从多表获取数据; 2.简单视图不包含函数和数据组,复杂视图包含; 3.简单视图可以实现DML操作,复杂视图不可以。 视图的定义原则: 1.视图的查询可以使用复杂的SELECT语法,包括连接/分组查询和子查询; 2.在没有WITH CHECK OPTION和 READ ONLY 的情况下,查询中不能使用 ORDER BY 子句; 3.如果没有为CHECK OPTION约束命名,系统会自动为之命名,形式为SYS_Cn; 4.OR REPLACE选项可以不删除原视图便可更改其定义并重建,或重新授予对象权限。 视图上的DML 操作: DML操作应遵循的原则: 1.简单视图可以执行DML操作; 2.在视图包含GROUP 函数,GROUP BY子句,DISTINCT关键字时不能删除数据行; 3.在视图不出现下列情况时可通过视图修改基表数据或插入数据:
select * from emp;
--concat(param1,param2) 拼接两个字符串 || select concat('0371-','8678565') as telephone from dual; select concat(ename,empno) from emp; select ename||empno from emp; --initcap 首字母大写 select initcap(ename),ename from emp; -- upper(全大写) lower(全小写) select upper(ename),lower(ename),ename from emp; select instr('410106199012132018','19901213',1,1) instring from dual; --instr(param1,param2,param3,param4) 查找字符串 1:被查找的字符串 2,要查找的字符 3,起始位置 4第几次出现 select empno,ename,hiredate, instr(to_char(hiredate,'yyyy-mm-dd'),'1981',1,1) from emp --lpad(param1,param2,param3)字符串左侧粘贴 1,原字符串 2,补充后达到的位数 3,补充字符 --rpad(param1,param2,param3) 字符串右侧粘贴 select lpad(rpad(empno,8,'#'),10,'*') from emp; --ltrim(param1,param2)从字符串param1左侧删除param2 rtrim(param1,param2) 字符串param1右侧删除param2 select ltrim('##100#024##','#') from dual; select ltrim('##100024##','#'),rtrim('**200001****','*') from dual; --param2省略时,去除空格 select ltrim(' admin '),rtrim(' admin ') from dual; select ltrim(' admin ',' '),rtrim(' admin ',' ') from dual; --去除左右两侧的空格 select trim(' admin ') from dual; --trim(leading param1 from param2) leading (头) param2从头部去除param1 --trim(trailing param2 from param2) trailing (尾) param2 从尾部去除param1 --trim(both param2 from param2) both (头,尾) param2从头,尾(两侧)去除param1 select trim(leading '#' from '###admin##') from dual; select trim(trailing '#' from '###admin##') from dual; select trim(both '#' from '###adm#in##') from dual; --substr(param1,number1,number2)截取字符串 param1,目标字符串 number1起始位,number2长度 select substr('13012345678',3,8) from dual; --replace(param1,param2,param3)替换字符串 param1目标字符串,param2被替换的字符串,param3替换字符串 select replace('云和培训java培训','yunhe','教育') from dual; select ename,replace(ename,'A','a') from emp select mod(7,3) from dual; select * from emp; -- mod(number1,number2) number1对number2 取余数 select comm,mod(comm,1000) from emp; -- round(number1,number2) nubmer2为正数,小数点向后四舍五入number2,number2为负数,小数点向前四舍五入number2 select sal,round(sal,-2) from emp; -- trunc(number1,number2) 截取,nubmer2为正数,小数点向后截取number2,number2为负数,小数点向前截取number2 select sal,trunc(sal,-2) from emp; --sign(number) 判断number符号,大于0返回1,等于0返回0,小于0返回-1 select sign(10) from dual; select sign(-10) from dual; select sign(0) from dual; --mysql分页 limit index,length oracle分页 rownum --select 语句顺序 select * from table where condition1 and condition group by column having order by -- having 字句对条件限制关键字 和where 区别: where 用于group by 之前 对普通表的列条件限制 having 用于group by 之后,对聚合函数(max,min,count,avg,sum)的条件限制 select * from emp; --列出至少有一个员工的所有部门。 --having字句的聚合函数的限制条件,不能使用select聚合函数的别名 select emp.deptno,dept.dname,count(empno) from emp,dept where emp.deptno=dept.deptno and emp.deptno is not null group by emp.deptno,dept.dname having count(empno)>=1 select dept.deptno,dept.dname,count(empno) from emp,dept where emp.deptno=dept.deptno and dept.deptno is not null group by dept.deptno,dept.dname --emp表中出每个部门的部门代码、薪水之和、平均薪水 select * from dept,(select deptno,sum(sal),avg(sal) from emp group by deptno) e where dept.deptno=e.deptno select emp.deptno,dept.dname,sum(sal),avg(sal) from emp,dept where emp.deptno=dept.deptno group by emp.deptno,dept.dname --查询emp表中出部门平均薪水小于等于2000的部门的部门代码、平均薪水,并按平均薪水从大到小排序。 select deptno,avg(sal) from emp where deptno is not null group by deptno having avg(sal)<=2000 order by avg(sal) desc; --询emp表中薪水最少,和薪水最大员工的姓名和薪水,并按薪水从大到小排序。union(连接) select ename,sal from emp where sal=(select max(sal) from emp) union select ename,sal from emp where sal=(select min(sal) from emp) select ename,sal from emp where sal=(select max(sal) from emp) or sal=(select min(sal) from emp) select ename,sal from emp where sal in((select max(sal) from emp),(select min(sal) from emp)) --列出所有员工的姓名及其直接上级领导的姓名e1(员工表) e2(经理表) select e1.empno,e1.ename,e1.mgr,e2.ename from emp e1,emp e2 where e1.mgr=e2.empno; --列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称。 select e1.hiredate,e2.hiredate,e1.empno,e1.ename,dept.dname,e1.mgr,e2.ename from emp e1,emp e2,dept where e1.mgr=e2.empno and e1.deptno=dept.deptno and e1.hiredate<e2.hiredate; --列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门. select * from emp,dept where emp.deptno(+)=dept.deptno; select * from emp right join dept on emp.deptno=dept.deptno; --列出所有CLERK(办事员)的姓名,及其部门名称,部门人数。 select * from emp where job='CLERK'; select * from (select ename,deptno,job from emp where job='CLERK') e1,(select deptno,count(*) from emp group by deptno) e2 where e1.deptno=e2.deptno --列出最低薪金大于1500的各种工作及从事此工作的全部雇员人数。 select job,count(job) from emp group by job having min(sal)>1500; select job,count(empno) from emp group by job having min(sal)>1500; --列出薪金高于公司平均薪金的所有员工,所在部门,上级领导,公司的等级工资。 select avg(sal) from emp; select * from salgrade; select emp.empno,emp.ename,emp.sal,emp.deptno,dept.dname,emp.mgr,e2.ename,salgrade.grade from emp,dept,emp e2,salgrade where emp.deptno=dept.deptno and emp.mgr=e2.empno and emp.sal between salgrade.losal and salgrade.hisal and emp.sal>(select avg(sal) from emp); --列出在每个部门工作的员工数量、平均工资和平均服务期限。 select deptno,count(empno),avg(sal),round(avg(months_between(sysdate,hiredate))/12,1) from emp group by deptno --列出各种工作的最低工资及从事此工作的雇员姓名。 select * from emp where (job,sal) in(select job,min(sal) from emp group by job) select * from emp; --列出各个部门的MANAGER(经理)的最低薪金。 select * from emp where job='MANAGER' -- 列出员工的年工资,按年薪从低到高排序 select ename,(nvl(comm,0)+nvl(sal,0))*12 as year_sal from emp order by year_sal --给任职日期超过10年的人加薪10%。 create table emp2 as select * from emp; update emp2 set sal=sal*1.1 where months_between(sysdate,hiredate)>120 --找出各月倒数第三天受雇的所有员工 select * from emp where hiredate=last_day(hiredate)-2 --显示员工姓名正好为5个字符的员工 select * from emp where ename like '_____' select * from emp where length(ename)=5 --显示所有员工姓名的前三个字符。 select ename,substr(ename,1,3) from emp --显示所有员工的姓名,用 a 替换A select ename,replace(ename,'A','a') from emp; --显示所有员工的姓名、加入公司的年份和月份,按受雇日期所在月排序,若月份相同,按年份排序 select ename,hiredate,to_char(hiredate,'yyyy') as yea,to_char(hiredate,'mm') mth from emp order by mth,yea --显示所有员工的日薪金,忽略余数。每个月的天数都以30天计 select ename,sal,trunc(sal/30,0) from emp;
select * from emp; select * from dept; select * from emp_grade; --连接 select * from emp,dept,emp_grade where emp.deptno=dept.deptno(+) and emp.grade_id=emp_grade.id(+); select * from emp left join dept on emp.deptno=dept.deptno right join emp_grade on emp.grade_id=emp_grade.id --笛卡尔成绩 select * from emp,dept order by empno; --等值连接 select * from emp,dept where emp.deptno=dept.deptno; --左连接 右连接(显示主表的所有信息) (+)在哪侧的表是匹配表 --(+)操作符只能用于实现左外连接和右外连接,而不能用于实现完全外连接。 --显示所有员工的部门信息 select * from emp,dept where emp.deptno=dept.deptno(+); --显示所有部门的员工信息 select * from dept,emp where emp.deptno(+)=dept.deptno; --左外连接(左边的表不加限制) --右外连接(右边的表不加限制) --全外连接(左右两表都不加限制) -- 左外连接( tb1 LEFT OUTER JOIN/ LEFT JOIN tal2 on tbl1.id=tabl2.id) --右外连接( tb1 RIGHT OUTER JOIN/RIGHT JOIN tal2 on tbl1.id=tabl2.id) --全外连接(tb1 FULL OUTER JOIN/FULL JOIN tal2 on tbl1.id=tabl2.id) --左外连接 select * from emp left join dept on emp.deptno=dept.deptno; --右外连接 select * from emp right join dept on emp.deptno=dept.deptno; -- 全连接 select * from emp full join dept on emp.deptno=dept.deptno; --子查询 (单行子查询 多行子查询) in() -- 只要出现聚合函数,除聚合函数外还有其他列的时候,其他列必须放在group by --聚合函数max() min() sum() avg()对列 count()行记录数统计 -- group by 先进行分组,再进行统计 -- 单行子查询 > < =(单个值) --查询薪资最低的员工信息 select * from emp where sal=(select min(sal) from emp) --查询工资高于部门20中所有员工的雇员信息。 select * from emp where sal>(select max(sal) from emp where deptno=20) select * from emp where sal>all(select sal from emp where deptno=20) --in all 多行子查询 select * from emp where sal in(select sal from emp where deptno=20) -- 多列子查询 --查询各部门中工资最低的雇员信息。 select * from emp,(select deptno,min(sal) min_sal from emp group by deptno)e where emp.deptno=e.deptno and emp.sal=e.min_sal; select * from emp where (deptno,sal) in(select deptno,min(sal) min_sal from emp group by deptno) -- 表自连接 select * from stu_grade; --即参加计算机又参加英语考试的学生信息 select * from stu_grade A,stu_grade B where A.Id=B.id and A.COURSE_NAME='计算机' and B.Course_Name='英语' declare v_ename varchar2(50); begin select ename into v_ename from emp where empno=&eno; dbms_output.put_line('员工名称:'||v_ename); exception when no_data_found then dbms_output.put_line('没有对应的员工信息'); end; declare v_ename varchar2(50); begin select ename into v_ename from emp where empno=&eno; dbms_output.put_line(concat('员工名称:',v_ename)); exception when no_data_found then dbms_output.put_line('没有对应的员工信息'); end; PL/SQL程序块 declare ---定义常量 名称 constant 数据类型 赋值操作符 := -- 定义变量 名称 数据类型 赋值 := begin exception -- no_data_find end; --输出打印dbms_output.put_line(); 字符串拼接: || 或使用concat()函数 / -- command Window 执行plsql程序 declare v_pi constant number(6,5):=3.14; --圆周率常量 v_r number(1):=2; --半径变量 v_area number(10,2); --圆面积 begin v_area:=v_pi*v_r*v_r; --计算圆面积 dbms_output.put_line('圆的面积:='||v_area); end; %TYPE数据类型 --定义一个变量与表的列的数据类型一致 --根据员工编号查找员工姓名和员工部门编号 declare v_ename emp.ename%type; v_deptno dept.deptno%type; begin select ename,deptno into v_ename,v_deptno from emp where empno=7369; dbms_output.put_line('员工名称:'||v_ename); dbms_output.put_line('员工部门编号:'||v_deptno); end; --除了可以使用常量来给变量赋值之外(:=),还可通过SELECT INTO语句将从数据库表中查询的结果赋予变量 当由多个变量通过select 赋值时 :selcet 列名1,列名2 into 变量1,变量2 from 表 %record 记录数据类型 首先需要定义记录类型和记录变量 当引用记录成员时,必须将记录变量作为前缀 语法结构 : type 记录类型名称 is record( 列名1 数据类型, 列名2 数据类型, 列名3 数据类型 ); v_emp_record 记录类型名称; --根据输入的员工编号输出该员工的姓名、基本工资、奖金及实发工资。 declare type emp_record is record( v_empname emp.ename%type, v_sal emp.sal%type, v_deptno emp.deptno%type, v_deptname dept.dname%type ); v_emp_record emp_record; begin select ename,sal,emp.deptno,dname into v_emp_record from emp,dept where emp.deptno=dept.deptno and empno=&eno; dbms_output.put_line('员工姓名:'||v_emp_record.v_empname); dbms_output.put_line('员工薪资:'||v_emp_record.v_sal); dbms_output.put_line('部门编号:'||v_emp_record.v_deptno); dbms_output.put_line('部门名称:'||v_emp_record.v_deptname); exception when no_data_found then dbms_output.put_line('没有找到对应的员工信息!'); end; -- 简写 直接使用某个表的行记录 表名%rowtype --TABLE数据类型 语法结构 type table数据类型名称 is table of 表名%rowtype index by binary_integer; table就是一个一维数组 赋值 select * into table(0) from 表 where id= declare type dept_table is table of dept%rowtype index by binary_integer; v_dept_table dept_table; begin select * into v_dept_table(0) from dept where deptno=&dno; select * into v_dept_table(1) from dept where deptno=&dno2; dbms_output.put_line('第一条记录信息:'||v_dept_table(0).deptno||v_dept_table(0).dname); dbms_output.put_line('第二条记录信息:'||v_dept_table(1).deptno||v_dept_table(1).dname); end; when no_data_found then 条件控制语句: 语法结构 if condition1 then ... elsif condition2 then ... elsif condition3 then ... else ... end if; -- 输入员工编号,如果该员工 原来没有奖金,则按照工资的10%发放 原来有奖金但不超过1000的,补到1000; 其余的按照原来奖金基础再加上10%发放; declare emp_row emp%rowtype; begin select * into emp_row from emp where empno=&eno; dbms_output.put_line('员工的奖金:'||emp_row.comm); if emp_row.comm is null then update emp set comm=sal*0.1 where empno=emp_row.empno; elsif emp_row.comm<1000 then update emp set comm=1000 where empno=emp_row.empno; else update emp set comm=emp_row.comm*1.1 where empno=emp_row.empno; end if; exception when no_data_found then dbms_output.put_line('没有找到对应的员工信息'); end; -- 条件控制语句 case 表达式 when 值1 then ...... when 值2 then ...... when 值3 then ...... else ..... end case; --根据部门编号输出部门所在地 declare v_deptno dept.deptno%type:=&deptno; begin case v_deptno when 10 then dbms_output.put_line('高新区'); when 20 then dbms_output.put_line('金水区'); when 30 then dbms_output.put_line('郑东新区'); when 40 then dbms_output.put_line('二七区'); else dbms_output.put_line('非郑州区域'); end case; end; declare v_deptname dept.dname%type:=&deptname; begin case v_deptname when '高新区' then dbms_output.put_line('10'); when '金水区' then dbms_output.put_line('20'); when '郑东新区' then dbms_output.put_line('30'); when '二七区' then dbms_output.put_line('40'); else dbms_output.put_line('非郑州区域'); end case; end; -- 循环语句语法结构 loop 退出条件: if condition then exit; end if; 执行循环语句; 循环条件变量的改变; end loop; --定义一个dept类型的表结构 手工添加3条数据 然后用循环将其数据添加到dept表中。 declare type dept_table is table of dept%rowtype index by binary_integer; v_dept_table dept_table; i number(1):=0; begin v_dept_table(0).deptno:=50; v_dept_table(0).dname:='Java开发部'; v_dept_table(1).deptno:=60; v_dept_table(1).dname:='C++开发部'; v_dept_table(2).deptno:=70; v_dept_table(2).dname:='.NET开发部'; v_dept_table(3).deptno:=80; v_dept_table(3).dname:='PHP开发部'; loop if i>2 then exit; end if; insert into dept(deptno,dname) values(v_dept_table(i).deptno,v_dept_table(i).dname); i:=i+1; end loop; end; -- 存储过程语法结构 create [or replace] procudure(存储过程关键字) pro_name(自定义存储过程名称) (argument1 datatype,.....) is[as] 声明 begin ... exception ... end; select * from emp2; -- 创建存储过程 create or replace procedure pro_emp2 is begin update emp2 set sal=sal+300; dbms_output.put_line('更新成功!'); end; --存储过程调用 1.call 存储过程名称() 2. exec 存储过程 --执行无参存储过程 call pro_emp2(); //sql window,command window 都可以执行 无输出结果 exec pro_emp2; //执行应用,在command window下执行 有输出结果 select * from emp2; -- 创建带有输入(in)参数的存储过程 create or replace procedure pro_select (v_empno in emp.empno%type) is v_sal emp.sal%type; begin select sal into v_sal from emp where empno=v_empno; dbms_output.put_line('员工薪资:'||v_sal); end; --执行有参的存储过程 call pro_emp2(7369); //sql window,command window 都可以执行 exec pro_emp2(7369); //执行应用,在command window下执行 --执行带有输出参数的存储过程 out --根据员工的编号,输出员工的薪资 create or replace procedure pro_select (v_empno in emp.empno%type,v_sal out emp.sal%type) is begin select sal into v_sal from emp where empno=v_empno; end; --带有输入,输出参数的存储过程调用 匿名程序块执行 declare v_sal emp.sal%type; begin pro_select(7369,v_sal); --作为一个子程序执行 dbms_output.put_line('薪资:'||v_sal); end; -- 带有 in out 参数的存储过程 create or replace procedure pro_in_out(param_num in out number) as begin select sal into param_num from emp where empno=param_num; end; --调用 in out 参数的存储过程 declare param_num number:=7369; begin pro_in_out(param_num); dbms_output.put_line('薪资:'||param_num); end; -- 参数传递方式 :1.位置传递 2.名称传递 3.组合传递 create or replace procedure pro_add_dept(v_deptno number,v_dname varchar2, v_loc varchar2) as begin insert into dept values(v_deptno,v_dname,v_loc); end; 1.位置传递 --调用时按参数的排列顺序 call pro_add_dept(2,'云和学习部','老君山'); 2.名称传递 --按名称传递是指在调用时按照形参与实参的名称写出实参所对应的形参,将形参与实参关联起来进行传递 call pro_add_dept(v_loc=>'峨眉山',v_deptno=>3,v_dname=>'php培训部'); -- 函数的创建 create or replace function 函数名称(arg1 argType,arg2 arg2Type) return dataType is[as] v_empno number; begin .... end; --创建一个生成随机数的函数 create or replace function fun_random return number as v_num number; begin v_num:=floor(dbms_random.value(1,100)); return v_num; end; 函数的调用 declare num number; begin num:=fun_random(); dbms_output.put_line('随机数:'||num); end; create or replace procedure pro_query_emp(v_no in emp.empno%type) as v_sal emp.sal%type; begin select sal into v_sal from emp where empno=v_no; dbms_output.put_line('员工薪水为:'||v_sal); exception when no_data_found then dbms_output.put_line('找不到该员工'); end; 数据库的概念:控制文件,日志文件 实例的概念