Oracle
什么是PL/SQL?
为什么要学习plsql?
通过程序在控制台打印一句话
一般我们调试或者练习plsql程序可以用test窗口(专门用来调试或练习的)
--建议在test窗口进行练习
--过程化的语言,类似与basic declare
begin
--打印一句话 --下面这句话相当于java:System.out.println("hello world"); --dbms_output:Oracle的内置包,相当于java类 --put_line:方法,相当于println dbms_output.put_line('hello world'); end;
--点击运行或者F8 |
如果想要在命令窗口运行,需要打开输出选项:set serveroutput on
注意:oracle的控制台信息,默认不会显示到客户端,需要设置set serveroutput on,目的是打开控制台信息的输出。
PL/SQL可以分为三个部分:声明部分、可执行部分、异常处理部分。
[delare] 声明部分(变量、游标、例外) begin 逻辑执行部分(DML语句、赋值、循环、条件等) [exception] 异常处理部分(when 预定义异常错误 then) end; / |
概念:程序包:dbms_output相当于java中的类(system.out),它是oracle自带的
调用程序包:dbms_output.put_line(‘Hello World!’)相当于java的println()方法
最简单的PL/SQL:
Begin Null; End; / |
注意:在SQLPLUS中,PLSQL执行时,要在最后加上一个 /
常见的几种变量类型的定义方法,分两大类:
声明变量的语法:
变量名 变量类型(长度);
在ORACLE中有两种赋值方式:
1,直接赋值语句 :=
2, 使用select …into … 赋值:(语法;select 值 into 变量)
【示例】
打印几个变量的值,几个变量的值分别采用两种不同的赋值方法:
--打印两个变量的值,两个变量的值分别采用两种不同的赋值方法: DECLARE--声明变量 --姓名 v_name VARCHAR(20) :='Zhong';--声明的时候直接赋值 --薪资 v_sal NUMBER; --工作地点 v_local VARCHAR(200); BEGIN --开始程序逻辑 --程序运行时赋值 --方法一:--直接赋值 v_sal :=9999; --方法二:语句赋值 SELECT '上海' INTO v_local FROM dual; --输出打印 dbms_output.put_line('姓名:'||v_name||',薪资:'||v_sal||',工作地点:'||v_local); END;--程序结束
|
plsql中有两种不同的赋值方法:
一种是: 直接用:=来赋值
另一种:select 值 into 变量 from 表名。
引用变量:引用表中字段的类型 (推荐使用引用类型)
%type 例: v_ename emp.ename%type;
使用emp表的字段ename的数据类型作为v_ename的数据类型.
【示例】
查询并打印7839号(老大)员工的姓名和薪水
--查询并打印7839号(老大)员工的姓名和薪水
declare
v_ename emp.ename%TYPE; --引用类型变量 变量名 表名.字段名%type
n_sal emp.sal%TYPE ;
begin
SELECT ename ,sal INTO v_ename,n_sal FROM emp WHERE empno=7839;
dbms_output.put_line(v_ename||' '||n_sal);
end;
--查询并打印7839号(老大)员工的姓名和薪水 DECLARE --定义变量 --姓名 v_ename emp.ename%TYPE;--姓名使用的emp表中的ename的字段的数据类型 --薪水 v_sal emp.sal%TYPE;--你不需要关心具体什么数据类型了
BEGIN --赋值 --注意:into前后字段名和变量名必须对应(不管是数据类型,还是个数,顺序) --必须:查询的结果必须只有一个值,不能有多行记录 SELECT ename,sal INTO v_ename,v_sal FROM emp WHERE empno=7839; --打印 dbms_output.put_line('7839号员工的姓名是:'||v_ename||',薪资'||v_sal); END; |
引用类型的好处:
普通变量值过小报错:
使用%TYPE是非常好的编程风格,因为它使得PL/SQL更加灵活,更加适应于对数据库定义的更新。
记录型变量,代表一行,可以理解为数组,里面元素是每一字段值。
%rowtype 引用一条(行)记录的类型 例:v_emp emp%rowtype;
含义:v_emp 变量代表emp表中的一行数据的类型,它可以存储emp表中的任意一行数据。
记录型变量分量的引用方式:
【示例】
查询并打印7839号(老大)员工的姓名和薪水
--查询并打印7839号(老大)员工的姓名和薪水 DECLARE --记录型变量 v_emp emp%ROWTYPE;--该变量可以存储emp表中的一行记录
BEGIN --赋值 --默认情况下,必须是全字段赋值 SELECT * INTO v_emp FROM emp WHERE empno=7839; --打印 dbms_output.put_line('7839号员工的姓名是:'||v_emp.ename||',薪资'||v_emp.sal); END; |
场合:
如果有一个表,有100个字段,那么你程序如果要使用这100字段话,如果你使用引用型变量一个个声明,会特别麻烦,那么你可以考虑记录型变量
错误的使用:
2.返回的行太多了,记录型变量也接收不了
可以执行就是对PL/SQL进行程序控制
程序控制:
语法:
提示:语法和java作用差不多。
java三种if语法:
if(){
}
if(){
}else{
}
if(){
}else if(){
}else{
}
注意单词 。
【示例】
判断emp表中记录是否超过20条,10-20之间,10以下打印一句
--判断emp表中记录是否超过20条,,10-20之间,10以下打印一句 DECLARE --用来存储数量 v_count NUMBER; BEGIN --查询数量赋值 SELECT COUNT(1) INTO v_count FROM emp ; --判断 IF v_count>20 THEN dbms_output.put_line('记录数超过20条:'||v_count); ELSIF v_count BETWEEN 10 AND 20 THEN dbms_output.put_line('记录数在10到20条之间:'||v_count); ELSE dbms_output.put_line('记录数不足10条:'||v_count); END IF; END; |
语法:
在ORACLE中有三种循环:
Loop 循环 EXIT WHEN...条件 end loop;
While()…loop 条件判断循环
For 变量 in 起始..终止 Loop
这里我建议只记忆一种写法:
记住loop的写法
【示例】
打印数字1-10
-- 打印数字1-10
DECLARE
v_num NUMBER :=1; --定义初始值
BEGIN
LOOP --开启循环
EXIT WHEN v_num >10 ;--结束循环条件
dbms_output.put_line(v_num);
v_num:=v_num+1;
END LOOP; --循环体结束
END;
--打印数字1-10 DECLARE --声明一个变量 v_num NUMBER :=1; BEGIN --循环并打印 LOOP EXIT WHEN v_num>10; --退出循环条件 dbms_output.put_line(v_num); --递增 --v_num++;--不支持 v_num :=v_num+1; END LOOP; END; |
游标(Cursor),也称之为光标,从字面意思理解就是游动的光标。 游标是映射在结果集中一行数据上的位置实体。 游标是从表中检索出结果集,并从中每次指向一条记录进行交互的机制。 |
游标从概念上讲基于数据库的表返回结果集,也可以理解为游标就是个结果集,但该结果集是带向前移动的指针的,每次只指向一行数据。
游标的主要作用:用于临时存储一个查询返回的多行数据(结果集),通过遍历游标,可以逐行访问处理该结果集的数据。
(显示)游标的使用方式:声明--->打开--->读取--->关闭
游标声明:
CURSOR 游标名 [ (参数名 数据类型[,参数名 数据类型]...)] IS SELECT 语句; 【示例】 无参游标: cursor c_emp is select ename from emp; 有参游标: cursor c_emp(v_deptno emp.deptno%TYPE) is select ename from emp where deptno=v_deptno; |
游标的打开:
Open 游标名(参数列表) 【示例】 open c_emp;-- 打开游标执行查询 |
游标的取值:
fetch 游标名 into 变量列表|记录型变量 【示例】 fetch c_emp into v_ename;--取一行游标的值到变量中,注意:v_ename必须与emp表中的ename列类型一致。(v_ename emp.ename%type;) |
游标的关闭:
close 游标名 【示例】 close c_emp;--关闭游标释放资源 |
解释游标获取数据的基本原理:
游标刚open的时候,指针结果集的第一条记录之前。
游标与结果集的区别是什么?游标是有位置的。
fetch会向前游动,并获取游标的位置的内容。
注意:游动过的就不能回来了,循环一次就到头。
游标的属性 |
返回值类型 |
说明 |
%ROWCOUNT |
整型 |
获得FETCH语句返回的数据行数 |
%FOUND |
布尔型 |
最近的FETCH语句返回一行数据则为真,否则为假 |
%NOTFOUND |
布尔型 |
与%FOUND属性返回值相反 |
%ISOPEN |
布尔型 |
游标已经打开时值为真,否则为假 |
【示例】
使用游标查询emp表中所有员工的姓名和工资,并将其依次打印出来。
【引用型变量获取游标的值】:
DECLARE
N_NUM NUMBER := 1;
R_ROW EMP%ROWTYPE;
CURSOR C_EMP IS
SELECT * FROM EMP;
BEGIN
OPEN C_EMP;
LOOP
FETCH C_EMP
INTO R_ROW;
DBMS_OUTPUT.PUT_LINE(R_ROW.ENAME|| ' ' ||R_ROW.SAL);
EXIT WHEN c_emp%NOTFOUND;
END LOOP;
CLOSE C_EMP;
END;
--使用游标查询emp表中所有员工的姓名和工资,并将其依次打印出来。 DECLARE --声明一个游标 CURSOR C_EMP IS SELECT ENAME, SAL FROM EMP; --引用型变量 V_ENAME EMP.ENAME%TYPE; --姓名 V_SAL EMP.SAL%TYPE; --工资
BEGIN --打开游标,执行查询 OPEN C_EMP; --使用游标,循环取值 LOOP --获取游标的值放入变量的时候,必须要into前后要对应(数量和类型) FETCH C_EMP INTO V_ENAME, V_SAL; EXIT WHEN C_EMP%NOTFOUND; --输出打印 DBMS_OUTPUT.PUT_LINE('员工的姓名:' || V_ENAME || ',员工的工资' || V_SAL); END LOOP; CLOSE c_emp ;--关闭游标,释放资源 END;
|
【使用记录型变量存值】:
DECLARE
V_NAME EMP.ENAME%TYPE;
N_SAL EMP.SAL%TYPE;
CURSOR C_EMP IS
SELECT ENAME, SAL FROM EMP;
BEGIN
OPEN C_EMP;
LOOP
FETCH C_EMP
INTO V_NAME, N_SAL;
dbms_output.put_line('名字:'||v_name||'薪水:'||n_sal);
EXIT WHEN C_EMP%NOTFOUND;
END LOOP;
CLOSE c_emp;
END;
--使用游标查询emp表中所有员工的姓名和工资,并将其依次打印出来。 DECLARE --声明一个游标 CURSOR C_EMP IS SELECT * FROM EMP; --记录型变量 V_emp emp%ROWTYPE;
BEGIN --打开游标,执行查询 OPEN C_EMP; --使用游标,循环取值 LOOP --获取游标的值放入变量的时候,必须要into前后要对应(数量和类型) FETCH C_EMP INTO v_emp; EXIT WHEN C_EMP%NOTFOUND; --输出打印 DBMS_OUTPUT.PUT_LINE('员工的姓名:' || v_emp.ename || ',员工的工资' || v_emp.sal); END LOOP; CLOSE c_emp ;--关闭游标,释放资源 END;
|
【示例】
使用游标查询并打印某部门的员工的姓名和薪资,部门编号为运行时手动输入。
-- Created on 2015/5/5 by CLARK ---查询10号部门的员工的姓名和薪资 declare --定义游标--带参数的游标:需要定一个形式参数 CURSOR c_emp(v_deptno emp.deptno%TYPE) IS SELECT ename,sal FROM emp WHERE deptno=v_deptno ;
--声明变量 v_ename emp.ename%TYPE; v_sal emp.sal%TYPE;
BEGIN --用 --打开游标 OPEN c_emp(10); --循环fetch LOOP --取出数据 FETCH c_emp INTO v_ename,v_sal; --退出条件 EXIT WHEN c_emp%NOTFOUND; --打印--写任何的逻辑 dbms_output.put_line('姓名:'||v_ename||',薪资:'||v_sal); END LOOP; --关闭 CLOSE c_emp; end;
--使用游标查询并打印某部门的员工的姓名和薪资,部门编号为运行时手动输入。 DECLARE --声明一个带参数的游标 CURSOR C_EMP(v_deptno emp.deptno%TYPE) IS SELECT * FROM EMP WHERE deptno=v_deptno; --记录型变量 v_emp emp%ROWTYPE;
BEGIN --打开游标,执行查询 --打开游标的时候需要传入参数 OPEN C_EMP(20); --使用游标,循环取值 LOOP --获取游标的值放入变量的时候,必须要into前后要对应(数量和类型) FETCH C_EMP INTO v_emp; EXIT WHEN C_EMP%NOTFOUND; --输出打印 DBMS_OUTPUT.PUT_LINE('员工的姓名:' || v_emp.ename || ',员工的工资' || v_emp.sal); END LOOP;
CLOSE c_emp ;--关闭游标,释放资源 END; |
存储过程:就是一块PLSQL语句包装起来,起个名称
语法上:相当于plsql语句戴个帽子。
相对而言:单纯plsql可以认为是匿名程序。
存储作用:
提示:
根据参数的类型,我们将其分为3类讲解:
最简单,就是包装了一个代码块
建议用这个窗口:
【示例】
create or replace procedure p_hello
AS begin
dbms_output.put_line('hello world');
end p_hello; |
查询是否创建:
在工具procedures这里
关于写存储的3个窗口的选择:
编译发布的时候使用command、测试使用test
测试一下:
如何调用执行,两种方法:
注意:
第一个问题:is和as是可以互用的,用哪个都没关系的
第二个问题:过程中没有declare关键字,declare用在语句块中
存储可以带参数可以不带参数?其实都有应用.
不带参数的存储一般用来处理内部数据的。不需要输入参数也不需要结果的,是可以使用。
【示例】
查询并打印某个员工(如7839号员工)的姓名和薪水--存储过程:要求,调用的时候传入员工编号,自动控制台打印。
--查询并打印某个员工(如7839号员工)的姓名和薪水--存储过程:要求,调用的时候传入员工编号,自动控制台打印。 create or replace procedure p_queryempsal(i_empno IN emp.empno%TYPE)--i_empno输入参数的名字,IN代表是输入值的参数, IS --声明变量 v_ename emp.ename%TYPE; v_sal emp.sal%TYPE; BEGIN --赋值 SELECT ename ,sal INTO v_ename,v_sal FROM emp WHERE empno= i_empno; --打印 dbms_output.put_line('姓名:'||v_ename||',薪水:'||v_sal); end p_queryempsal;
|
命令调用:
程序调用:
【示例】
输入员工号查询某个员工(7839号员工)信息,要求,将薪水作为返回值输出,给调用的程序使用。
----输入员工号查询某个员工(7839号(老大)员工)信息,要求,将薪水作为返回值输出,给调用的程序使用。 CREATE OR REPLACE PROCEDURE p_queryempsal_out( i_empno IN emp.empno%TYPE,o_sal OUT emp.sal%TYPE) AS BEGIN --赋值:将薪水的值赋给输出的参数o_sal SELECT sal INTO o_sal FROM emp WHERE empno=i_empno;
END;
|
调用(使用plsql程序调用):
DECLARE --输入参数值 v_empno emp.empno%TYPE:=7839; --声明一个变量来接收输出参数 v_sal emp.sal%TYPE;
BEGIN
p_queryempsal_out(v_empno,v_sal);--第二个参数是输出的参数,必须有变量来接收!! --当上面的语句执行之后,v_sal就有值了。
dbms_output.put_line('员工编号为:'||v_empno||'的薪资为:'||v_sal); END; / |
注意:调用的时候,参数要与定义的参数的顺序和类型一致.
【扩展】
如何直接测试存储(相当于debug)测试:
小结:
存储过程作用:主要用来执行一段程序。
存储函数创建语法:
CREATE [OR REPLACE] FUNCTION 函数名(参数列表) RETURN 函数值类型 AS PLSQL子程序体; |
存储函数的编写示例:
/* 查询某职工的总收入。 */ create or replace function queryEmpSalary(i_empid in number) RETURN NUMBER as pSal number; --定义变量保存员工的工资 pComm number; --定义变量保存员工的奖金 begin select sal,comm into pSal, pcomm from emp where empno = i_empid; return psal*12+ nvl(pcomm,0); end; / |
存储函数的调用:
declare v_sal number; begin v_sal:=queryEmpSalary(7934); dbms_output.put_line('salary is:' || v_sal); end; / |
begin dbms_output.put_line('salary is:' || queryEmpSalary(7934)); end; |
存储过程和存储函数的区别:
|
如何选择存储过程和存储函数?
原则上,如果只有一个返回值,用存储函数,否则,就用存储过程。
但是,一般我们会直接选择使用存储过程,原因是:
需求:如果一条语句无法实现结果集的查询,(比如需要多表查询,或者需要复杂逻辑查询,),你可以选择调用存储查询出你的结果.
调用存储的语句:转义语法
如何得到?
通过connection得到:
准备环境:
【示例】
通过员工号查询员工的薪资
package cn.itcast.jdbc;
import java.sql.CallableStatement;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import cn.itcast.utils.JDBCUtils;
public class PTest {
public static void main(String[] args) throws Exception {
// 1.获得连接对象
Connection conn = JDBCUtils.getConnection();
// 2.获得语句对象
// {call
String sql = "{call p_querysal_out(?,?)}";
CallableStatement call = conn.prepareCall(sql);
// 3.设置输入参数
call.setInt(1, 0000);
// 4.OUT参数的类型必须在执行存储过程之前进行注册
call.registerOutParameter(2, OracleTypes.DOUBLE);
// 5.执行存储过程
call.execute();
// 6.获取输出参数
double sal = call.getDouble(2);
System.out.println("sal:" + sal);
// 7.释放资源
JDBCUtils.release(conn, call, null);
}
}
数据库触发器是一个与表相关联的、存储的PL/SQL程序。每当一个特定的数据操作语句(Insert,update,delete)在指定的表上发出时,Oracle自动地执行触发器中定义的语句序列。 |
解释:
首先,它也是一段plsql程序。
然后,它是来触发与表数据操作相关的(insert,update,delete)。
然后,在进行表数据操作的时候,会自动触发执行的一段程序。
换句话说:触发器就是在执行某个操作(增删改)的时候触发一个动作(一段程序)。
有点像springMVC的拦截器,可以对cud增强。
创建触发器语法:
CREATE [or REPLACE] TRIGGER 触发器名 {BEFORE | AFTER} {DELETE | INSERT | UPDATE [OF 列名]} ON 表名 [FOR EACH ROW [WHEN(条件) ] ] PLSQL 块 |
解释:
【示例 】
-每当dept表中添加了一个新部门时,打印”成功插入新部门”
打开窗口:
create or replace trigger tri_adddept AFTER INSERT on dept declare begin dbms_output.put_line('插入了新部门'); end ;
--测试哈 SELECT * FROM dept; INSERT INTO dept VALUES(80,'itcast1','上海'); SELECT * FROM dept;
|
在指定的操作语句操作之前或之后执行一次,不管这条语句影响了多少行 。
触发语句作用的每一条记录都被触发。在行级触发器中使用old和new伪记录变量, 识别值的状态。 |
【示例】目标:演示语句级触发器和行级触发器的区别
复制出来一张表depttemp,分别建立语句级和行级触发器,然后进行批量插入操作测试。
CREATE TABLE depttemp AS SELECT * FROM dept WHERE 1<>1; SELECT * FROM depttemp; |
两个触发器编写:
--语句级别 create or replace trigger tri_adddepttemp_yuju after insert on depttemp declare begin--plsql语句 dbms_output.put_line('成功插入了一个部门:语句级触发器触发了。。:'); end tri_adddepttemp_yuju;
--行级别: create or replace trigger tri_adddepttemp_hangji after insert on depttemp for each row declare begin--plsql语句 dbms_output.put_line('成功插入了一个部门:行级触发器触发了。。:'); end tri_adddepttemp_hangji; |
批量插入数据测试:
--先建立两种触发器 --批量插入数据 INSERT INTO depttemp SELECT * FROM dept;
|
语句级触发器和行级触发器区别:
简单的说:行级触发器,是对应行操作的;语句级触发器,是对应表操作的。
:new代表操作之后的数据,只出现在INSERT/UPDATE中,
:old代表操作(cud)之前的那条数据,出现在UPDATE/DELETE,
INSERT时:NEW表示新插入的行数据,UPDATE时:NEW表示要替换的新数据,:OLD表示要被更改的原来数据,DELETE时:OLD表示要被删除的数据。
【示例】
涨工资:涨后的工资不能少于涨前的工资
分析:行级触发器,数据确认示例--行级触发器
--涨工资:涨后的工资不能少于涨前的工资 create or replace trigger tri_checkempsal BEFORE UPDATE ON emp--更新之前拦截触发 for each row--行级触发器 declare BEGIN --如果涨后小于涨前,则,终止更新操作 IF :new.Sal<:old.Sal THEN --终止程序继续运行,也就终止了更新操作了。 raise_application_error(-20001,'涨后的工资不能少于涨前的工资!!涨前的工资:'||:old.Sal||',涨后的工资:'||:new.sal); --相当于抛出异常(throw),(使用了oracle内置的一个函数来抛出异常) END IF; end tri_checkempsal; |
测试:
【示例】
数据的备份:
业务的原理:在更新或者删除数据的时候,将旧的数据备份出来到另外一张表中。
建立一张备份表: 目标:在更新dept的时候,进行触发该动作。(备份数据)
--数据的备份: create or replace trigger tri_deptbak before UPDATE on dept FOR EACH ROW--行级触发器 declare
begin INSERT INTO depttemp VALUES(:OLD.DEPTNO,:OLD.DNAME,:OLD.LOC,SYSDATE); --COMMIT; END ;
|
但是要注意:触发器会引起锁,降低效率!使用时要慎重。如无必要,尽量不要使用触发器。
行级触发器会引发行级锁(锁行数据)
语句级触发器可能会引起表级锁(锁表)
【示例】
在插入数据的之前,自动插入主键值(值是序列)
思考:这个该用哪种触发器?行级触发器
CREATE OR REPLACE TRIGGER tri_beforeInsert_t_testseq |
实现了一个类似mysql的自增长主键的功能.
为什么要有数据字典?
数据库是数据的集合,数据库维护和管理这用户的数据,那么这些用户数据表都存在哪里,用户的信息是怎样的,存储这些用户的数据的路径在哪里,这些信息不属于用户的信息,却是数据库维护和管理用户数据的核心,这些信息就是数据库的数据字典来维护的,数据库的数据字典就汇集了这些数据库运行所需要的基础信息。
什么是数据字典?
Oracle的数据字典是Oracle数据库安装之后,自动创建的一系列表。
数据字典表和用户创建的表没有什么区别,不过数据字典表里的数据是Oracle系统存放的系统数据,而普通表存放的是用户的数据而已。
对于数据字典表,里面的数据是由数据库系统自身来维护的。所以这里虽然和普通表一样可以用DML语句来修改数据内容,但是大家最好还是不要自己来做了,因为这些表都是作用于数据库内部的。所以这里我们切记记住不要去修改这些表里的内容。,所以,数据字典主要用来查询的。
数据字典表的用户都是sys,存在在system这个表空间里,表名都用"$"结尾,为了便于用户对数据字典表的查询(这样的名字是不利于我们记忆的),所以Oracle对这些数据字典都分别建立了用户视图,不仅有更容易接受的名字,还隐藏了数据字典表与表之间的关系,让我们直接通过视图来进行查询,简单而形象,Oracle针对这些对象的范围,分别把视图命名为DBA_XXXX, ALL_XXXX和USER_XXXX,所以我们说的数据字典一般是指数据字典视图。
视图名称 |
作用 |
user_对象视图 |
当前用户schema(方案-和用户同名)下的创建对象; |
all_对象视图 |
当前用户有权限访问到的所有对象的信息; |
dba_对象视图 |
管理员视图,包括了所有数据库对象的信息; |
v$_ |
性能视图,查询数据库性能使用。 |
数据字典视图非常多,我们无法一一记住,但是有个视图,我们必须知道,那就是dictionary视图,该视图里记录了所有的数据字典视图的名称。所以当我们需要查找某个数据字典而又不知道这个信息在哪个视图里的时候,就可以在dictionary视图里找。该视图还有个同义词dict。
【示例】
需求1:查询所有数据字典的名称和描述
需求2:我想查看当前用户下有哪些视图,但我不知道查询当前用户视图的数据字典的名称
--需求1:查询所有数据字典的名称和描述
SELECT * FROM DICTIONARY;--视图 SELECT * FROM dict;--同义词
--需求2:我想查看当前用户下有哪些视图对象,但我不知道查询当前用户视图的数据字典的名称 SELECT * FROM DICTIONARY WHERE table_name LIKE UPPER('user_%view%'); SELECT * FROM User_Views;--当前用户下创建的所有视图
|
数据字典中的表名默认是大写的!!!
数据字典名称 |
作用 |
USER_OBJECTS |
当前用户所创建数据库对象。 |
ALL_OBJECTS |
当前用户能够访问的数据库对象 |
USER_TABLES |
当前用户创建的表对象的信息 |
USER_TAB_COLUMNS |
当前用户下创建的列信息。 |
USER_CONSTRAINTS |
当前用户表上的约束对象 |
USER_CONS_COLUMNS |
当前用户下创建的列约束对象 |
USER_VIEWS |
当前用户下创建的视图 |
USER-SEQUENCES |
当前用户下创建的序列 |
USER-SYNONYMS |
当前用户下创建的同义词 |
|
|
【示例】
需求:由于业务需要,查询当前用户下有没有emp这张表(如果没有就创建,有的话就直接插入数据)
--需求:由于业务需要,查询当前用户下有没有emp这张表(如果没有就创建,有的话就直接插入数据) SELECT * FROM user_tables WHERE table_name =UPPER('emp');
--我想看看emp表中有几列,将列名都打印出来 SELECT * FROM USER_TAB_COLUMNS WHERE table_name =UPPER('emp'); |
[扩展]:利用数据字典自己编写一个类似plsql管理Oracle的网页版工具。
使用oracle自带的备份还原命令:exp(备份),imp(导入)
注意:你的系统中必须有这个命令才能去执行这个命令。
导入和导出命令,既可以直接写命令+参数,也可以使用向导的方式。
下面采用向导的方式:
目标:备份scott用户下的所有对象。
每次提取多少数据的时候,当缓存区满了,再写入文件。 导出文件的名字和位置,默认就在当前目录下。 备份的范围,2是默认值,表示备份当前用户下的所有对象。 主要是对象的权限,默认值导出。 导出表对象的时候,是否连数据一起导出,默认值是。 要导出用户确认,先输入用户名直接回车确认
导出的结果: 建议大家在传递该备份的时候,压缩一下: |
导入:
新建一个新的用户scott2
要导入的数据的用户名密码。
导入文件的名字和路径,默认在当前文件夹下面。 是否导入选择一些内容。 |
提示:数据库的备份和还原,用于备份和还原数据库的所有的对象的时候。
使用plsqlDeveloper工具:
你可以使用ctrl或shilft键进行选择。
目标:导出emp表中的10号部门的数据
还原方法:
用途:一般如果需要服务器上的某个表的数据,可以用这种方法进行传输。
【导入的前提】
先建立用户,然后在用户下面导入数据。
问题来了:
语句怎么弄?如果一条数据,你手动写没问题,那么有100条数据。
想想:起始测试环境下数据库已经有这些数据了,能否将这些数据转换成insert语句。
【扩展】
drop table DEPT cascade constraints;不管dept是否有外表关联,都可以删除。(会自动解除关系)
Oracle重点:
[扩展补充:]
百度搜索关键