Oracle学习笔记

整理电脑文档,翻到以前的学习笔记,在这里分享给大家,希望给学习Oracle的你,提供一点帮助。


Oracle SQL 语句中有数据操纵语言(DML)、数据定义语言(DDL)、数据控制语言(DCL)、事务控制语言(TCL) 等等。
语法格式:ALTER TABLE 命令 ALTER TABLE 表名ADD CONSTRAINT 约束名 约束内容
语法结构:根据结果集创建表 CREATE TABLE 表名 AS SELECT 语句
代码演示:复制表结构 CREATE TABLE INFOS2 AS SELECT * FROM INFOS WHERE 1=2;只要使where后条件不成立即可
语法结构:根据结果集创建表 INSERT INTO 表名(列名1,列名2……) VALUES (值1,值2……)
代码演示:INSERT 向表中插入一个结果集 INSERT INTO INFOS2 SELECT * FROM INFOS;
语法结构:UPDATE 操作 UPDATE 表名 SET 列名1=值,列名2=值…… WHERE 条件
语法结构:DELETE 操作 DELETE FROM 表名WHERE 条件
代码演示:DISTINCT 消除重复行 SELECT DISTINCT DEPTNO FROM EMP;
代码演示:IN 操作 SELECT ENAME,JOB,SAL FROM EMP WHERE job IN ('SALESMAN', 'PRESIDENT', 'ANALYST');
LIKE 模糊查询 在一些查询时,可能把握不准需要查询的确切值,比如百度搜索时输入关键字即可查询出相关的结果,这种查询称为模糊查询。
模糊查询使用LIKE 关键字通过字符匹配检索出所需要的数据行。字符匹配操作可以使用通配符“%”和“_”:
%:表示零个或者多个任意字符。 _:代表一个任意字符。
语法是:LIKE '字符串'[ESCAPE '字符']。匹配的字符串中,ESCAPE后面的“字符”作为转义字符。
'%30%%' escape '' 包含“30%”的字符串,“\”指转义字符,“%”在字符串中表示一个字符“%”。
集合运算就是将两个或者多个结果集组合成为一个结果集。集合运算包括:
? INTERSECT(交集),返回两个查询共有的记录。
? UNION ALL(并集),返回各个查询的所有记录,包括重复记录。
? UNION(并集),返回各个查询的所有记录,不包括重复记录。
? MINUS(补集),返回第一个查询检索出的记录减去第二个查询检索出的记录之后剩余的记录。
当使用集合操作的时候,要注意:查询所返回的列数以及列的类型必须匹配,列名可以不同。
代码演示:用union 插入多条数据

INSERT INTO DEPT  SELECT 50,'公关部','台湾' FROM DUAL UNION SELECT 60,'研发部','西安' FROM DUAL UNION SELECT 70,'培训部','西安' FROM DUAL;

代码演示:内联接

SELECT e.ENAME,e.JOB,e.SAL,d.DNAME FROM EMP e INNER JOIN DEPT d ON e.DEPTNO=d.DEPTNO WHERE e.SAL>2000;

Oracle 中的算术运算符,只有+、-、*、/四个,其中除号(/)的结果是浮点数。
字符串连接操作符(||) 代码演示:字符串连接

SELECT (ENAME || 'is a ' || JOB) AS "Employee Details"  FROM EMP WHERE SAL>2000;
  1. 单行子查询:不向外部返回结果,或者只返回一行结果。代码演示:单行子查询
SELECT ENAME,JOB,SAL FROM EMP WHERE DEPTNO=(SELECT DEPTNO FROM DEPT WHERE DNAME='SALES');
  1. 多行子查询:向外部返回零行、一行或者多行结果。代码演示:ANY/ALL 子查询
SELECT ENAME,JOB,SAL FROM EMP WHERE SAL<(>)ANY(ALL) (SELECT SAL FROM EMP WHERE JOB='SALESMAN');

在Oracle 的表的使用过程中,实际表中还有一些附加的列,称为伪列。 两个伪列:ROWID 和ROWNUM。
表中的每一行在数据文件中都有一个物理地址,ROWID 伪列返回的就是该行的物理地址。
代码演示:ROWID

SELECT ROWID,ENAME FROM EMP WHERE SAL>2000;

在查询的结果集中,ROWNUM 为结果集中每一行标识一个行号,第一行返回1,第二行返回2,以此类推。通过ROWNUM 伪列可以限制查询结果集中返回的行数。
代码演示:ROWNUM

SELECT ROWNUM,ENAME,JOB,SAL FROM EMP WHERE ROWNUM<=5;

查询出表EMP中第5 条到第10 条之间的记录。
代码演示:ROWNUM 应用

SELECT * FROM (SELECT ROWNUM R,ENAME,JOB,SAL FROM EMP WHERE ROWNUM<=10) WHERE R>5;

Oracle函数
AVG (平均)
COUNT (计数)
MAX (最大值)
MIN (最小值)
SUM (总合)
运用函数的语法是:
SELECT "函数名"("栏位名") FROM "表格名"
HAVING
那我们如何对函数产生的值来设定条件呢?举例来说,我们可能只需要知道哪些店的营业额有超过 $1,500。在这个情况下,我们不能使用 WHERE 的指令。那要怎么办呢?很幸运地,SQL 有提供一个 HAVING 的指令,而我们就可以用这个指令来达到这个目标。 HAVING 子句通常是在一个 SQL 句子的最后。一个含有 HAVING 子句的 SQL 并不一定要包含 GROUP BY 子句。HAVING 的语法如下:

SELECT "栏位1", SUM("栏位2") 
FROM "表格名" 
GROUP BY "栏位1" 
HAVING (函数条件) 

注意: 如果被 SELECT 的只有函数栏, 那就不需要 GROUP BY 子句。

外部链接
之前我们看到的左连接 (left join),又称内部连接 (inner join)。在这个情况下,要两个表格内都有同样的值,那一笔资料才会被选出。
那如果我们想要列出一个表格中每一笔的资料,无论它的值在另一个表格中有没有出现,那该怎么办呢?在这个时候,
我们就需要用到 SQL OUTER JOIN (外部连接) 的指令。
外部连接的语法是依数据库的不同而有所不同的。举例来说,在 Oracle 上,我们会在 WHERE 子句中要选出所有资料的那个表格之后加上一个 "(+)"来代表说这个表格中的所有资料我们都要。

CONCATENATE
有的时候,我们有需要将由不同栏位获得的资料串连在一起。每一种数据库都有提供方法来达到这个目的:
MySQL: CONCAT()
Oracle: CONCAT(), ||
SQL Server: +
CONCAT() 的语法如下:
CONCAT(字符串1, 字符串2, 字符串3, ...): 将字符串1、字符串2、字符串3,等字符串连在一起。请注意,Oracle的CONCAT()只允许两个参数;换言之,一次只能将两个字符串串连起来。不过,在Oracle中,我们可以用'||'来一次串连多个字符串。

CASE
CASE 是 SQL 用来做为 if-then-else 之类逻辑的关键字。
CASE 的语法如下:

SELECT CASE ("栏位名")
  WHEN "条件1" THEN "结果1"
  WHEN "条件2" THEN "结果2"
  ...
  [ELSE "结果N"]
  END
FROM "表格名"
"条件" 可以是一个数值或是公式。 ELSE 子句则并不是必须的。

EXTRACT(fmt FROM d),提取日期中的特定部分。fmt 为:YEAR、MONTH、DAY、HOUR、MINUTE、SECOND。其中YEAR、MONTH、DAY
可以为DATE 类型匹配,也可以与TIMESTAMP 类型匹配;但是HOUR、MINUTE、SECOND 必须与TIMESTAMP 类型匹配。
代码演示:TO_CHAR 对日期的处理

SELECT TO_CHAR(SYSDATE,'YYYY"年"MM"月"DD"日" HH24:MI:SS') "date"  FROM DUAL;

代码演示:TO_NUM 函数

SELECT TO_NUMBER('-$12,345.67','$99,999.99') "NUM" FROM DUAL

TO_DATE(x [,fmt]) 把一个字符串以fmt 格式转换为一个日期类型
NVL(x,value) 如果x 为空,返回value,否则返回x。NVL2(x,value1,value2) 如果x 非空,返回value1,否则返回value2。

语法结构:创建索引

CREATE [UNIQUE] INDEX index_name ON table_name(column_name[,column_name…]) 

创建索引不是为了在sql语句中用的,而是可以大大提高系统的性能。
语法结构:PL/SQL 块的语法

[DECLARE
--declaration statements] ①
BEGIN
--executable statements ②
[EXCEPTION
--exception statements] ③
END;

创建过程语法:

create [or replace] procedure  procedure_name
   [ (argment [ { in| in  out }]  type,
     argment  [ { in | out | in out } ] type
   { is  | as }
  <类型.变量的说明>
  ( 注:  不用 declare 语句 )
  Begin
  <执行部分>
 exception
   <可选的异常处理说明>
end;

这里的IN表示向存储过程传递参数,OUT表示从存储过程返回参数。而IN OUT 表示传递参数和返回参数;
在存储过程内的变量类型只能指定变量类型;不能指定长度;
在AS或IS 后声明要用到的变量名称和变量类型及长度;
在AS或IS 后声明变量不要加declare 语句。

复制表结构及其数据:

create table table_name_new as select * from table_name_old 

只复制表结构:

create table table_name_new as select * from table_name_old where 1=2;

或者:

create table table_name_new like table_name_old

只复制表数据:
如果两个表结构一样:

insert into table_name_new select * from table_name_old 

如果两个表结构不一样:

insert into table_name_new(column1,column2...) select column1,column2... from table_name_oldpasting

oracle中exists用法
比如:a,b 关联列为 a.id = b.id,现在要取 a 中的数据,其中id在b中也存在:

select * from a where exists(select 1 from b where a.id = b.id)

或者:现在要取 a 中的数据,其中id在b中不存在:

select * from a where not exists(select 1 from b where a.id = b.id)

oracle数据库里in 和exits的区别:
表A(小表),表B(大表)

select * from B where cc in (select cc from A)

这个语句中是先从A表中把cc找出来,然后根据cc再在B中去找相关的cc 由于A表的cc远小于B表的cc 所以可以节省时间

select * from B exists (select cc from A where cc=B.cc)

这句话是先从B表里把cc找出来 然后再在A表里找相关的cc 由于B表的cc远多于A表的cc 所以这样做很浪费时间
总结: 用in 时 大表在前小表在后
用exists时 小表在前大表在后

新增字段:ALTER TABLE [表名] ADD [字段名] NVARCHAR (50) NULL
删除字段:ALTER TABLE [表名] DROP COLUMN [字段名]
修改字段:ALTER TABLE [表名] ALTER COLUMN [字段名] NVARCHAR (50) NULL
新建视图

create or replace view td_m_dataright_release as
select "DATA_CODE","DATA_NAME","DATA_TYPE","CLASS_CODE","RIGHT_TYPE","HELP_INDEX","REMARK","UPDATE_TIME","UPDATE_STAFF_ID","RIGHT_MODE","RIGHT_OBJ","COMB_TAG","PROVINCE_CODE"
 from ess_cen.TD_M_DATARIGHT_RELEASE
 where province_code='0097';

同义词是数据库方案对象的一个别名,经常用于简化对象访问和提高对象访问的安全性。
Oracle的同义词有两种类型:公有同义词与私有同义词。
1:公有同义词由一个特殊的用户组Public所拥有。
2:私有同义词是由创建他的用户所有。
创建同义词的语法:

Create [public] synonym 同义词名称 for [username.]objectName

删除同义词的语法:

Drop [public] synonym 同义词名称 

查看所有同义词:

select * from dba_synonyms

三个默认用户:
sys [as sysdba]
syste
Oracle 10中上两个用户没有密码 ,在安装时自己设定
scott tiger 一开始此用户被锁,要自己解锁
登陆sys用户
sqlplus / assysdba
oradim -startup -sid orcl
创建用户
create user username identified by password;
授权
系统权限

grant create session to username;
grant create table to username;
grant unlimited tablespace to username;
grant create table,unlimited tablespace to username;

撤销权限

revoke create table from username;

查看用户所拥有的权限

select * from user_sys_privs;

在Oracle中各个用户都相对隔离开
例如用户lisi和wangwu
对象权限
在用户lisi中,给用户wangwu授权

 grant select,insert,update on tablename  on wangwu;

对象权限可以控制到列
只授权(只限更新和插入)某一列

grant update(列名),insert(列名) on tablename  to wangwu;

授所有权

grant  all on  tablename  to  username;

撤销权限

revoke all on  tablename  from  username;

给所有用户授权

grant create session  to  public;

增删插操作后要注意提交(commit)
权限的传递
系统权限
在sys用户中给用户A授权

grant alert any table to userA  with admin option;

在A用户给用户B授权

grant alert any table to userB  with admin option;

对象权限
在sys用户创建表
create table A;
给用户A授权

grant select on A to userA with grant option;

用户A给用户B授权

grant select on sys.A to userB with grant option;

角色:权限的集合
在sys用户创建角色
create role myrole;

grant create session,create table to myrole;

创建用户C

create user C identified by password;
grant myrole to C;
drop role myrole;

有些系统权限无法直接赋予角色,只能直接授权给用户
如:unlimited tablespace
注意:
create table create any table 注意两者的区别
[alert table]无 alert any table
[drop table]无 drop any table
表是属于某一个用户的,而角色是不属于某个用户的。
修改用户密码,可在sys用户下修改

alert user scott identified by password;

数据库的三种验证机制:操作系统验证、密码文件验证、数据库验证。
Linux下,Oracle的启动过程:lsnrctl start、sqlplus sys/orcl as sysdba、startup
windows下,Oracle的启动过程:lsnrctl start、oradim -startup -sid orcl、sqlplus sys/orcl as sysdba、startup
在sys用户中连接scott用户 conn scott/tiger
用户加锁:alert user 用户名 account lock
用户解锁:alert user 用户名 account unlock
用户口令即刻失效:alert user 用户名 password expire
删除用户:drop user 用户名 cascade; ( 强制删除,包括表)

WITH用于一个语句中某些中间结果放在临时表空间的SQL语句
如:

WITH  channel_summary AS (
SELECT channels.channel_desc, SUM(amount_sold) AS channel_total
FROM sales, channels
WHERE sales.channel_id = channels.channel_id
GROUP BY channels.channel_desc
)
SELECT channel_desc, channel_total
FROM channel_summary
WHERE channel_total > (
SELECT SUM(channel_total) * 1/3
FROM channel_summary);

channel_summary表就是WITH生成的中间表
就这一功能来说,子查询就可以实现,为什么要用with呢?
虽然都能实现,但执行计划是不同的。当有多个相似子查询的时候,用with写公共部分,因为子查询结果在内存临时表中,执行效率当然就高。如果你后面需要不止一次地引用这个结果,那么WITH就会大大提高效率。
代码的可读性好

set define off关闭替代变量功能
在SQLPlus中默认的"&"表示替代变量,也就是说,只要在命令中出现该符号,SQLPlus就会要你输入替代值。
这就意味着你无法将一个含有该符号的字符串输入数据库或赋给变量,如字符串“SQL&Plus”系统会理解为以“SQL”打头的字符串,
它会提示你输入替代变量 Plus的值,如果你输入ABC,则最终字符串转化为“SQLABC”。
set define off 则关闭该功能,“&”将作为普通字符,如上例,最终字符就为“SQL&Plus”
set define off关闭替代变量功能
set define on 开启替代变量功能
set define * 将默认替代变量标志符该为“*”(也可以设为其它字符)

oracle数据中删除数据时提示“记录被另一个用户锁住” 解决方法
1 查看数据库锁,诊断锁的来源及类型

select object_id,session_id,locked_mode from v$locked_object; 

或者用以下命令:

select b.owner,b.object_name,l.session_id,l.locked_mode 
from v$locked_object l, dba_objects b 
where b.object_id=l.object_id

2 找出数据库的serial#,以备杀死

   select t2.username,t2.sid,t2.serial#,t2.logon_time 
   from v$locked_object t1,v$session t2 
   where t1.session_id=t2.sid order by t2.logon_time;

3 杀死该session

 alter system kill session 'sid,serial#'
Oracle学习笔记_第1张图片
I LOVE STUDY.jpg

你可能感兴趣的:(Oracle学习笔记)