一、表操作
1. 常用数据类型
NUMBER(p,s):可变长度的数字。p表示整数加小数的最大位数,s为最大小数位数。支持最大精度为38位
NVARCHAR2(size):变长字符串,最大长度为4000字节(以字符数为单位)
VARCHAR2(size):变长字符串,最大长度为4000字节(以字节数为单位)
CHAR(size):定长字符串,最大长度为2000字节,最小为1字节,默认大小为1字节
DATE:日期值
TIMESTAMP:日期值(增加毫秒)
2. 创建表
语法1:CREATE TABLE [schema.]表名(列名1 列类型 [默认值] [列约束], ...);
语法2:CREATE TABLE [schema.]表名 AS SELECT * FROM [schema.]表名 WHERE 条件表达式;
示例:CREATE TABLE MYBOOK(BOOK_ID NUMBER(8) NOT NULL, BOOK_NAME VARCHAR2(100), CONSTRAINT MYBOOK_PK PRIMARY KEY(BOOK_ID));
3. 查看表信息
SQL> desc 表名;
4. 增加列
语法:ALTER TABLE 表名 ADD 列名 列类型;
5. 删除列
删除一列:ALTER TABLE 表名 DROP COLUMN 列名;
删除多列:ALTER TABLE 表名 DROP (列名1,列名2...);
设置列无效:ALTER TABLE 表名 SET UNUSED(列名1,列名2...);
删除无效列:ALTER TABLE 表名 DROP UNUSED COLUMN;
6. 更新列
修改列名:ALTER TABLE 表名 RENAME COLUMN 原列名 TO 新列名;
修改列数据类型:ALTER TABLE 表名 MODIFY 列名 新数据类型; //修改的列没有数据时可任意改,有数据时类型只能由短向长改
修改列的默认值:ALTER TABLE 表名 MODIFY (列名 DEFAULT 默认值);
7. 重命名表
语法:ALTER TABLE 表名 RENAME TO 新表名;
8. 删除表
语法:DROP TABLE 表名;
选项:
DROP TABLE 表名 CASCADE CONSTRAINTS; //删除表时同时删除引用这个表的视图、约束、索引、触发器等
DROP TABLE 表名 PURGE; //删除表后立即释放该表所占用的资源空间
9. 完整性约束
(1)NOT NULL约束
创建时指定NOT NULL约束:CREATE TABLE 表名(列名 类型 NOT NULL, ...);
修改时指定NOT NULL约束:ALTER TABLE 表名 MODIFY 列名 NOT NULL;
删除表中的NOT NULL约束:ALTER TABLE 表名 MODIFY 列名 NULL;
(2)PRIMARY KEY约束:一个表只能定义一个PRIMARY KEY约束,定义的列不能有重复值且不能有NULL值,Oracle会自动为PRIMARY KEY约束的列建立一个唯一索引。
创建时指定PRIMARY KEY约束:CREATE TABLE 表名(列名 类型 NOT NULL, ... , CONSTRAINT 主键名 PRIMARY KEY(列1,列2));
修改时指定PRIMARY KEY约束:ALTER TABLE 表名 ADD CONSTRAINT 主键名 PRIMARY KEY(列1,列2);
删除表中的PRIMARY KEY约束:ALTER TABLE 表名 DROP CONSTRAINT 主键名;
(3)UNIQUE约束:唯一性约束,定义的列不能有重复值但可以有多个NULL值,Oracle会自动为UNIQUE约束的列建立一个唯一索引。
创建时指定UNIQUE约束:CREATE TABLE 表名(列名 类型 CONSTRAINT 约束名 UNIQUE, ...);
修改时指定UNIQUE约束:ALTER TABLE 表名 ADD UNIQUE (列名);
删除表中的UNIQUE约束:ALTER TABLE 表名 DROP UNIQUE (列名); 或者ALTER TABLE 表名 DROP CONSTRAINT 约束名;
(4)CHECK约束:CHECK约束是指检查性约束,只有符合条件的记录才会保存到表中。在CHECK约束的表达式必须引用表中的一个列或多个列且表达式和运算结果是一个布尔值,在一个列上可以定义多个CHECK约束。
创建时指定CHECK约束:CREATE TABLE 表名(列名 类型 CONSTRAINT 约束名 CHECK(列名1 > 0), ...);
修改时指定CHECK约束:ALTER TABLE 表名 ADD CONSTRAINT 约束名 CHECK(列名1 > 0);
删除表中的CHECK约束:ALTER TABLE 表名 DROP CONSTRAINT 约束名;
(5)FOREIGN KEY约束:定义外键约束时引用的列应该具有主键约束,定义了外键约束的列只能为相关表中引用列的值或者NULL值
创建时指定FOREIGN KEY约束:CREATE TABLE 表名(列名 类型 REFERENCES 主表名(列名));
修改时指定FOREIGN KEY约束:ALTER TABLE 表名 ADD CONSTRAINT 约束名 FOREIGN KEY (列名) REFERENCES 主表名(列名);
删除表中的FOREIGN KEY约束:ALTER TABLE 表名 DROP CONSTRAINT 约束名;
定义FOREIGN KEY约束时指定引用类型:定义外键约束时可以使用关键字ON指定引用行为的类型
CASCADE:当主表中被引用列的数据被删除时,子表中对应的数据也将被删除
SET NULL:当主表中被引用列的数据被删除时,子表中对应的数据被设置为NULL,前提是对应列必须支持NULL值
NO ACTION:当主表中被引用列的数据被删除时,将违反外键约束,该操作也将被禁止执行,这也是外键约束的默认引用类型
语法:ALTER TABLE 表名 ADD CONSTRAINT 约束名 FOREIGN KEY (列名) REFERENCES 主表名 ON DELETE CASCADE;
(6)禁止约束:禁止约束时所有的约束对表都无效
禁止约束:ALTER TABLE 表名 DISABLE CONSTRAINT 约束名;
禁止约束但保留唯一索引:ALTER TABLE 表名 DISABLE CONSTRAINT 约束名 KEEP INDEX;
(7)激活约束:
激活约束:ALTER TABLE 表名 ENABLE CONSTRAINT 约束名;
激活约束:ALTER TABLE 表名 MODIFY CONSTRAINT 约束名 ENABLE;
(8)验证约束:定义或激活约束时是否对以前的数据进行验证
ENABLE VALIDATE:激活验证状态是默认状态,激活时同时对新老数据检查
ENABLE NOVALIDATE:激活非验证状态只对新数据进行检查
DISABLE NOVALIDATE:禁止非激活状态对新老数据都不做检查
语法:ALTER TABLE 表名 MODIFY CONSTRAINT 约束名 DISABLE NOVALIDATE;
(9)延迟约束:对添加和更新操作的数据不会立即执行约束检查
INITIALLY DEFERRABLE:约束的状态为延迟检查
INITIALLY IMMEDIATE:约束的状态是立即检查,默认
语法:ALTER TABLE 表名 MODIFY CONSTRAINT 约束名 INITIALLY DEFERRABLE;
(10)查询约束信息(查询数据字典视图和动态性能视图)
OWNER:约束的所有者
CONSTRAIN_NAME:约束名
CONSTRAINT_TYPE:约束类型
DEFERRED:约束是立即执行还是延迟执行
DEFERRABLE:约束是否为可延迟的
STATUS :约束的状态
TABLE_NAME:约束的表名
COLUMN_NAME:约束的列名
查询表中的约束信息:SELECT CONSTRAIN_NAME,CONSTRAINT_TYPE,DEFERRED,DEFERRABLE,STATUS FROM USER_CONSTRAINTS WHERE TABLE_NAME='表名';
查询定义约束的列:SELECT CONSTRAIN_NAME,COLUMN_NAME FROM USER_CONS_COLUMNS WHERE TABLE_NAME='表名';
二、SQL基础
1. SELECT语句
SELECT * FROM 表名 [WHERE 表达式] ;
比较操作符:
=:等于,字符需用''引住
<>、!=:不等于
>=:大于等于
<=:小于等于
>:大于
<:小于
BETWEEN AND:在两值之间
IN:匹配于列表值
LIKE:匹配于字符样式,%表示0个或多个字符,_表示单个字符
ISNULL:为空
2. ORDER BY语句
SELECT * FROM 表名 ORDER BY [列名1 .. [ASC|DESC]]; //先按列1排序,然后按列2排序
ASC:升序,默认
DESC:降序
3. GROUP BY语句
SELECT 列1 ... FROM 表名 [GROUP BY 列1 ...]; //查询出来的列只能是在GROUP BY条件中出现的列或其它列的统计信息
4. HAVING语句
SELECT 列1 ... FROM 表名 [GROUP BY 列1 ...] HAVING 表达式; //HAVING必须跟在GROUP BY后面
5. DISTINCT
SELECT DISTINCT 列名 FROM 表名; //与之对应的是ALL(默认)
6. INSERT语句
单行记录的插入:INSERT INTO 表名(列1, ...) VALUES(值1,...);
多行记录的插入:INSERT INTO 表名1(列1, ...) SELECT (列1,...) FROM 表名2;
7. UPDATE语句
语法:UPDATE 表名 SET 列1=值1,... WHERE 表达式;
多表关联UPDATE语句(被修改值从另一个表而来):
update A a
set a.name=(select b.name from B b where b.id=a.id)
where
exists (select 1 from B b where b.id=a.id)
-- UPDATE多个值
update A a
set (a.name,a.type)=(select b.name,b.type from B b where b.id=a.id)
where
exists (select 1 from B b where b.id=a.id)
--如果舍弃where条件,则默认对A表进行全表更新
8. DELETE语句
语法:DELETE FROM 表名 WHERE 表达式;
9. MERGE语句修改表数据
省略INSERT子句的MERGE语句:
MERGE INTO 新表 USING 老表 ON 表达式 WHEN MATCHED THEN UPDATE SET 新表.列=老表.列 WHERE 表达式;
带条件的UPDATE语句和INSERT语句:
MERGE INTO 新表 USING 老表 ON 表达式
WHEN MATCHED THEN UPDATE SET 新表.列=老表.列 WHERE 表达式
WHEN NOT MATCHED THEN INSERT VALUES (老表.列1,...);
三、连接查询
1. 简单自然连接:使用相等操作符指定连接条件的连接查询,主要用于检索主从表之间的相关数据
语法:SELECT 表名1.列1,...表名2.列1,... FROM 表名1, 表名2 WHERE 表名1.列1 = 表名2.列2;
增加别名:SELECT t1.列1 AS "姓名",...t2.列1 AS "部门",... FROM 表名1 t1, 表名2 t2 WHERE 表名1.列1 = 表名2.列2;
2. 内连接:
语法:SELECT 表名1.列1,...表名2.列1,... FROM 表名1 INNER JOIN 表名2 ON 表名1.列1 = 表名2.列2;
3. 左外连接:左外连接不仅会返回连接表中满足连接条件的所有记录,而且还会返回不满足连接条件的连接操作符左边表的其他行
语法1:SELECT 表名1.列1,...表名2.列1,... FROM 表名1 LEFT OUTER JOIN 表名2 ON 表名1.列1 = 表名2.列2;
语法2:SELECT 表名1.列1,...表名2.列1,... FROM 表名1, 表名2 WHERE 表名1.列1 = 表名2.列2(+);
4. 右外连接:右外连接不仅会返回连接表中满足连接条件的所有记录,而且还会返回不满足连接条件的连接操作符右边表的其他行
语法1:SELECT 表名1.列1,...表名2.列1,... FROM 表名1 RIGHT OUTER JOIN 表名2 ON 表名1.列1 = 表名2.列2;
语法2:SELECT 表名1.列1,...表名2.列1,... FROM 表名1, 表名2 WHERE 表名1.列1(+) = 表名2.列2;
5. 自连接:自连接是指在同一张表之间的连接查询,主要用于显示上下级关系或者层次关系
语法:SELECT 表名.列1,... FROM 表名 t1, 表名 t2 WHERE t1.列1 = t2.列2;
四、Oracle子查询
1. 单行子查询(子查询返回单行数据)
(1)在WHERE子句中使用子查询
语法:SELECT 列名1,... FROM 表名1 WHERE 列名2=(SELECT 列名3 FROM 表名2 WHERE 表达式); //还可以用>、<、>=、<=、<>等单行操作符
(2)在HAVING子句中使用子查询
语法:SELECT 列名1,... FROM 表名1 GROUP BY 列名2 HAVING 列名3=(SELECT 列名4 FROM 表名2 GROUP BY 列名5 );
(3)在FROM子句中使用子查询
语法:SELECT 列名1,... FROM 表名1, (SELECT 列名4 FROM 表名2 GROUP BY 列名5 ) 别名1 WHERE 表名1.列名3=别名1.列名4; //子句会被作为视图对待,必须指定别名
(4)常见单行子查询错误
单行子查询最多返回一行,如果子查询返回多行,就会出现错误;
子查询不能包含ORDER BY子句,否则将出现语法错误;
2. 多行子查询(子查询返回多行数据)
(1)在多行子查询中使用IN操作符
语法:SELECT 列名1,... FROM 表名1 WHERE 列名2 IN(SELECT 列名3 FROM 表名2 WHERE 表达式);
(2)在多行子查询中使用ANY操作符,必须与单行操作符结合使用
语法:SELECT 列名1,... FROM 表名1 WHERE 列名2>ANY(SELECT 列名3 FROM 表名2 WHERE 表达式); //大于子查询中的任何一个即可,相当于大于最小
(3)在多行子查询中使用ALL操作符,必须与单行操作符结合使用
语法:SELECT 列名1,... FROM 表名1 WHERE 列名2>ALL(SELECT 列名3 FROM 表名2 WHERE 表达式); //大于子查询中的任何一个,相当于大于最大
3. 多列子查询(多列子查询返回单行数据时可以使用单行比较符,返回多行数据时必须使用多行比较符IN、ANY、ALL)
语法:SELECT 列名1,... FROM 表名1 WHERE (列名2, 列名3) IN(SELECT 列名3, 列名4 FROM 表名2 WHERE 表达式); //需多列同时匹配
4. 关联子查询(引用外部SQL语句中的列或多列)
语法:SELECT 列名1,... FROM 表名1 WHERE 列名2=(SELECT 列名3 FROM 表名2 WHERE 表名1.列名4=表名2.列名5);
使用EXISTS语法:SELECT 列名1,... FROM 表名1 WHERE EXISTS (SELECT 列名2 FROM 表名2 WHERE 表名1.列名3=表名2.列名4); // 可以将列名4设置为一个常量值提高性能,如1,只要子查询返回一行或多行,EXISTS就是TRUE。如果子查询未返回行,EXISTS返回FALSE
使用NO EXISTS语法:SELECT 列名1,... FROM 表名1 WHERE NOT EXISTS (SELECT 1 FROM 表名2 WHERE 表名1.列名3=表名2.列名4); //检索不满足条件的行
5. 嵌套子查询(子查询内部还可以嵌套其它子查询,最多可为255层)
6. 包含子查询的UPDATE和DELETE语句
语法:UPDATE 表名1 SET (列1, 列2) = (SELECT 列3, 列4 FROM 表名2 WHERE 表达式) WHERE 列5=(SELECT 列6 FROM 表名3 WHERE 表达式);
五、Oracle高级查询
1. 使用UNION ALL操作符,用于获取两个结果集的并集,包含重复的行。必须确保不同查询的列个数和数据类型都要匹配
语法:SELECT 列名1, ... FROM 表名1 WHERE 表达式 UNION ALL SELECT 列名1, ... FROM 表名2 WHERE 表达式;
2. 使用UNION操作符,与UNION ALL不同的是,它会自动去掉结果集中的重复行,并且会以第一列的结果进行排序
语法:SELECT 列名1, ... FROM 表名1 WHERE 表达式 UNION SELECT 列名1, ... FROM 表名2 WHERE 表达式;
3. 使用INTERSECT操作符,用于获取两个结果集的交集,并且会以第一列的结果进行排序
语法:SELECT 列名1, ... FROM 表名1 WHERE 表达式 INTERSECT SELECT 列名1, ... FROM 表名2 WHERE 表达式;
4. 使用MINUS操作符,用于获取两个结果集的差集,只会显示在第一个结果集而不在第二个结果集中的数据,并且会以第一列的结果进行排序
语法:SELECT 列名1, ... FROM 表名1 WHERE 表达式 INTERSECT SELECT 列名1, ... FROM 表名2 WHERE 表达式;
5. 使用TRANSLATE(x,s1,s2)函数,用于将x中的s1字符串按字符逐一替换为s2中的字符
语法:SELECT TRANSLATE('1234564789', '45647', 'abcd') FROM DUAL; //返回123abca89
6. 使用DECODE(v, if1, then1, if2,..., default_value)函数,如果v等于if1,返回结果then1,以此类推,都不等时返回default_value
语法:SELECT DECODE(1,1,2,3) FROM DUAL; //返回2
7. 使用简单CASE表达式
语法:SELECT CASE 列名1 WHEN 10 THEN '小' WHEN 20 THEN '中' ELSE '大' END FROM 表名;
8. 使用搜索CASE表达式
示例:
SELECT COUNT(CASE WHEN 列1<10 THEN 1 ELSE NULL END) LOW,
COUNT(CASE WHEN 列1 BETWEEN 10 AND 20 THEN 1 ELSE NULL END) MED,
COUNT(CASE WHEN 列1>20 THEN 1 ELSE NULL END) HIGN FROM 表名;
9. 层次化查询
(1)CONNECT BY ... START WITH:能清楚的返回子节点和父节点的关系
(2)伪例LEVEL:它是一个数值,指出节点在树中所处的层次
(3)LEVEL LPAD():格式化层次化查询结果
10. 使用扩展的GROUP BY子句
(1)ROLLUP子句:为每一个分组返回一条小计记录,并为全部分组返回总计
(2)CUBE子句:为每一个分组返回一条小计记录,并为全部分组返回总计
(3)GROUPING(列1)函数:如果列值为空返回0,列值非空返回0,只能在ROLLUP或CUBE语句中使用
(4)GROUPING SETS子句:只返回小计记录
(5)GROUPING_ID()函数:将不包含小计或者总计的记录除去
(6)GROUP_ID()函数:用于消除GROUP BY子句返回的重复记录