数据库(个人学习笔记,不断更新修改中)
2015-07-11 11:49
441 查看
SQL可分为:
1,数据定义语言(DDL) : Data Definition Language
CREATE TABLE创建表,
ALTER TABLE修改表,
DROP TABLE删除表等动作
2,数据操纵语言(DML) : Data Manipulation Language
INSERT语句用于将数据插入到数据库中,
UPDATE语句用于更新数据库中已存在的数据,
DELETE用于删除数据库中已存在的数据
3,事务控制语言(TCL):Transaction Control Language
COMMIT用来确认已经进行的数据库改变,
ROLLBACK语句用来取消已经进行的数据库改变
SAVEPOINT语句用来设置保存点,使当前的事务可以回退到指定的保存点,便于取消部分改变
4,数据查询语言(DQL):Data Query Language
SELECT用来查询所需要的数据。使用最广泛,语法灵活复杂。
5,数据控制语言(DCL) : Data Control Language
GRANT用于给用户或角色授予权限,
REVOKE用于收回用户或角色已有的权限。
CREATE USER语句
Oracle数据类型
NUMBER(6,2)表示数字类型/NUMBER(2)
CHAR(20)表示固定长度的字符类型
VARCHAR2(100);表示变长的字符类型
DATE定义日期时间的数据
创建表:CREATE TABLE emp()
查看表格结构:DESC emp
查看表中数据:SELECT * FROM emp1_liuwenshou 查看表中数据(把*号换成字段号,字段号可以查看指定字段的数据)
查看表中指定字段数据:SELECT ename,job,sal FROM myemp1_liuwenshou
删除表格:DROP TABLE emp
赋默认值:DEFAULT ‘M’
非空(NOT NULL)
修改表名:RENAME old_name TO new_name;
增加列:ALTER TABLE employee ADD (hiredate DATE DEFAULT sysdate);
删除列:ALTER TABLE employee DROP (hiredate);
修改列:ALTER TABLE employee MODIFY(job VARCHAR2(40) DEFAULT 'CLERK' );
插入列:INSERT INTO employee(id, name, job, birth)
VALUES(1003, 'donna', 'MANAGER', TO_DATE('1978-09-01', 'YYYY-MM-DD'))
更新记录:UPDATE employee SET salary = 8500,gender='F' WHERE name = 'ROSE';
删除记录:DELETE FROM employee WHERE job is null;
字符串类型
SELECT CONCAT(ename,job) FROM myemp1_liuwenshou;在数据库中返回ename和job在同一个字段
SELECT CONCAT(CONCAT(ename,':'),job) FROM myempq_liuwenshou;在数据中返回ename和job在同一个字段,并且中间用:连接
SELECT ename||‘:’||sal FROM myempq_liuwenshou;在数据中返回ename和sal在同一个字段,并且中间用:连接
SELECT ename, LENGTH(name) FROM emp; 将列出name和name的字符串长度
SELECT UPPER('hello') FROM myemp1_liuwenshou;将字符转换为大写形式
SELECT LOWER('HELLO WORLD') FROM DUAL;将字符转换为小写形式
SELECT INITCAP('hello world') FROM DUAL;将字符串中每个单词的首字符大写,其它字符小写,单词之间用空格和非字母字符分隔
SELECT TRIM('e' from 'elite')FROM DUAL;表示从elite的前后截去e,e只能为单个字符
SELECT RTRIM('eeeefuckeqeeeeeqqq','eq') FROM DUAL;表示从eeeefuckeqeeeeeqqq右边截去e/q/eq/qe字符
SELECT LTRIM('eqqqeeeefuckeqeeee','eq') FROM DUAL;表示从eeeefuckeqeeeeeqqq左边截去e/q/eq/qe字符
SELECT ename,LPAD(sal,6,‘¥’) FROM emp_liuwenshou;把sal变成6个字符,不足的话用左边的¥补齐6,右边只能为单个字符
SELECT ename,RPAD(sal,6,‘¥’) FROM emp_liuwenshou;把sal变成6个字符,不足的话用右边的¥补齐6,左边只能为单个字符
SELECT SUBSTR('Doctor Who travels in TARDIS', 8, 3)FROM DUAL;//Who 在一个字符串中第8位开始连续截取3个数子串,8可以为负数
SELECT INSTR('think in java in my life','in',2,3)FROM DUAL;//15//从第2个字符开始检索in第3次出现的位置
数值函数
ROUND(n[, m])//SELECT ROUND(45.678,2) FROM DUAL //用于将参数n按照m的数字要求四舍五入,m可取(正,0,负)(- .+)
TRUNC(n[, m])//SELECT TRUNC(45.51,-1)FROM DUAL//的功能是截取,其中n和m的定义和ROUND(n[, m])相同
MOD(m, n)是取模函数//SELECT ename,sal,MOD(sal,1000)FROM myemp1_liuwenshou//返回m除以n后的余数,如果n为0则直接返回m
CEIL(n),//SELECT CEIL(45.678) FROM DUAL; --46/取大于n的最小整数
FLOOR(n)//SELECT FLOOR(45.678) FROM DUAL;//,取小于n的最大整数
日期类型
LECT SYSDATE FROM DUAL;//显示当前时间//将显示“03-MAY-14”的形式,如果是中文环境,将显示“03-5月-14”的形式。
SELECT TO_CHAR(SYSDATE,'yyyy-mm-dd day hh24:mi:ss') FROM DUAL;//显示当前时间//年-月-日 星期1 13:57:32
SELECT SYSTIMESTAMP FROM DUAL;//显示当前时间,精确到毫秒
SELECT TO_CHAR(SYSTIMESTAMP,'SSSS.FF') FROM DUAL;
日期转换函数
TO_DATE(char[, fmt[, nlsparams]]);//SELECT ename, TO_CHAR(hiredate, 'YYYY"年"MM"月"DD"日"') FROM emp;L//08-8月 -08
SELECT ename,sydate-hiredate FROM emp;//计算员工入职到现在多少天
SELECT sysdate-TO_DATE('1990-06-03','YYYY-MM-DD')FROM DUAL//计算出生多少天
SELECT TO_CHAR(sysdate,'YYYY-MM-DD')FROM DUAL//将当前时间以指定格式输出('YYYY-MM-DD'==2015-05-18)('YYYY"年"MM"月"DD"日"'==2015年05月18日)
SELECT TO_CHAR(TO_DATE('09-05-20','RR-MM-DD'),'YYYY-MM-DD')FROM DUAL//显示给定时间的世纪
SELECT LAST_DAY('20-2月-09') FROM DUAL;//查询09年2月的最后一天
SELECT ename, ADD_MONTHS(hiredate, 20 * 12) "20周年" FROM emp;//返回日期date加上i个月后的日期值//计算职员入职20周年纪念日:
SELECT ename,MONTH_BETWEEN(date1, date2) FROM emp://计算date1和date2两个日期值之间间隔了多少个月
SELECT NEXT_DAY(SYSDATE, i) FROM DUAL;//查询下个星期i是几号
SELECT LLEAST(expr1[, expr2[, expr3]]…) FROM DUAL//返回结果是参数列表中最小值
SELECT GREATEST(expr1[, expr2[, expr3]]…) FROM DUAL//返回结果是参数列表中最大值
SELECT EXTRACT(YEAR FROM SYSDATE) FROM DUAL;//取出当前日期的年
SELECT EXTRACT(HOUR FROM SYSTIMESTAMP) FROM DUAL;//取出当前日期的小时
SELECT EXTRACT(HOUR FROM TIMESTAMP '2008-10-10 10:10:10') FROM DUAL;取出指定时间的小时
空值操作
UPDATE student SET gender = NULL; //全表gender都被更新为null
SELECT * FROM mystudent_liuwenshou WHERE gender IS NULL;//用“列名 IS NOT NULL”来查询空数据。
SELECT * FROM mystudent_liuwenshou WHERE gender IS NOT NULL;//用“列名 IS NOT NULL”来查询非空数据。
空值函数
NVL(expr1, expr2):将NULL转变为非NULL值
SELECT ename, sal, comm, sal + NVL(comm, 0) FROM emp;//将取NULL值的comm列转换为0再进行运算,结果就不会为NULL了
SELECT ename,NVL2(comm,'有奖金','没奖金') FROM myemp1_liuwenshou//comm值不为NULL返回有奖金,为NULL返回没奖金
WHERE子句
在SELECT语句中使用WHERE子句可以添加过滤条件,当我们添加了WHERE后,数据库在检索对应的表时,会将表中每一条数据取出后使用WHERE进行判断,查看这条记录
中的字段值是否满足WHERE的要求,满足的话,这条记录将被查询出来,不满组就忽略。
WHERE是在第一次查询表中数据时进行过滤。***********************************************************************************************
所以表中有多少条数据,WHERE就会被执行几次,WHERE是在查询表中数据的时候被使用的
>:大于
< :小于
>= :大于等于
<=:小于等于
< >:不等于(!=,)数据库不等于常用< >,
= :等于
AND :相当于java中的 && 且
OR : 相对于java中的 || 或
AND的优先级是高于OR的
LIKE条件
%:表示0到多个字符
_:标识单个字符
eg:SELECT ename, job FROM emp WHERE ename LIKE '_A%';//查询职员姓名中第二个字符是‘A’的员工信息
IN和NOT IN 可以理解为一个范围比较操作符
SELECT ename, job FROM emp WHERE job IN ('MANAGER', 'CLERK');//查询职位是MANAGER或者CLERK的员工
IN通常被利用在子查询中,所以IN的功能不能被OR完全代替
SELECT ename, job FROM emp WHERE deptno NOT IN (10, 20);//查询不是部门10或20的员工
BETWEEN…AND…操作符用来查询符合某个值域范围条件的数据
SELECT ename, sal FROM emp WHERE sal BETWEEN 1500 AND 3000;//查询薪水在1500-3000之间的职员信息
ANY和ALL条件
> ANY(list):大于列表中最小的即可
< ANY(list):小于列表中最大的即可
> ALL(list):大于列表中最大的即可
< ALL(list):小于列表中最小的即可
ANY与ALL通常是用在判断一个子查询结果,几乎不会在列表中给定值,否则没什么意思
eg:查看比20号部门工资都高的员工有谁
SELECT ename,sal,deptin
FROM lwsemp
WHERE sal > ALL(SELECT sal FROM lwsemp WHERE deptin=20)
查询条件中使用表达式和函数
select ename,sal from myemp1_liuwenshou where UPPER(ename) = upper('ward')//名字为WARD的
SELECT ename,sal FROM myemp1_liuwenshou WHERE sal*12>50000//年薪大于50000的
DISTINCT过滤重复,会将其后定义的字段中重复的记录去除掉
SELECT DISTINCT job FROM myemp1_liuwenshou --查看公司有哪些职位
多列去重:当DISTINCT 后面有多个重复的时候,后面字段值没有的重复的输出
SELECT DISTINCT job,deptin FROM myemp1_liuwenshou//eg:1,1~2,2-3,3,3~2,3~3,3~4
DISTINCT只与SELECT连接
ORDER BY字句 :询出的数据按一定规则进行排序操作 NULL为最大值
ASC用来指定升序排序,DESC用来指定降序排序
SELECT <*, column [alias], …> FROM table [WHERE condition(s)] [ORDER BY column [ASC | DESC]] ;默认ASC,
eg:SELECT ename,sal FROM myemp1_liuwenshou ORDER BY sal//按工资升序排列 最后面加DESC按照将需排列
ORDER BY 也可以按照多个字段排序,每个字段都需要单独指定升序将需(有优先级的,第一次排列相同字段再拍第二级排列)
eg:SELECT ename,deptin,sal FROM myemp1_liuwenshou ORDER BY deptin DESC,sal
聚合函数:又叫做分组函数,多行函数。可以将一组数据进行统计然后得出一个结果。
MAX和MIN:取该列的最大值,最小值 只能操作数字类型,忽略NULL值
SELECT MAX(sal) max_sal, MIN(sal) min_sal FROM myemp1_liuwenshou;//获取机构下的最高薪水和最低薪水
AVG和SUM求平均值和总和 忽略null值的,如果有null值的,求平均值的时候需转换为0
SELECT AVG(NVL(sal,0)),SUM(sal) FROM myemp1_liuwenshou
COUNT函数用来计算表中的记录条数,同样忽略NULL值
SELECT COUNT(ename) FROM myemp1_liuwenshou//为了避免null值,ename用*代替可准确的查看表中有多少条目
SELECT COUNT(*) FROM myemp1_liuwenshou
分组
GROUP BY子句:需要把整个数据表按部门划分成一个个小组,每个小组中包含一行或多行数据,在每个小组中再使用分组函数进行计算,每组返回一个结果
通常GROUP BY子句中出现的字段应当是重复值较多的,否则分组没有意义
SELECT AVG(sal),deptin FROM myemp1_liuwenshou GROUP BY deptin--按部门计算平均工资 (前面能加deptin是因为该分组中deptin值相同)
HAVING字句,必须跟在GROUP BY后面
SELECT deptno, MAX(sal) max_sal FROM emp GROUP BY deptno HAVING MAX(sal) >4000;
//查询每个部门的最高薪水,只有最高薪水大于4000的记录才被输出显示
SELECT AVG(sal),deptin FROM myemp1_liuwenshuou GROUP BY deptin HAVING MAX(sal)>4500//按照部门最高工资大于4500的部门的平均工资
当一条查询语句中包含所有的子句,执行顺序依下列子句次序:
FROM 子句:执行顺序为从后往前、从右到左。数据量较少的表尽量放在后面。
WHERE子句:执行顺序为自下而上、从右到左。将能过滤掉最大数量记录的条件写在WHERE 子句的最右。
WHERE语句中不能限制分组结果
GROUP BY:执行顺序从左往右分组,最好在GROUP BY前使用WHERE将不需要的记录在GROUP BY之前过滤掉。
HAVING 子句:消耗资源。尽量避免使用,HAVING 会在检索出所有记录之后才对结果集进行过滤,需要排序等操作。
SELECT子句:少用*号,尽量取字段名称。ORACLE 在解析的过程中, 通过查询数据字典将*号依次转换成所有的列名, 消耗时间。
ORDER BY子句:执行顺序为从左到右排序,消耗资源。
关联的概念
eg:查看SALES部门工作的员工的所有名字
SELECT e.ename,d.dname
FROM myemp1_liuwenshou e,mydep1_liuwenshou d --标名太长,可在FROM语句中取别名便于其他代码中书写
WHERE e.deptin=d.depton
AND d.dname='SALES'
查询时,若使用N张表联合查询,那么必须只要有N-1个连接条件(WHERE后面的语句),若不添加连接条件,将出现笛卡尔积
笛卡尔积:A表中每条数据与B表每条数据连接生成的结果,对系统的资源占用大的破坏是严重的
内连接
SELECT e.ename, d.dname
FROM emp e JOIN dept d
ON(e.deptno = d.deptno);
WHERE d.dname='SALES'//效果同上 。查看SALES部门工作的员工的所有名字
外连接
当进行关联查询时,不满足连接条件的数据不会被显示在结果中,我们需要将不满足连接条件的记录也显示出来,就需要使用到外连接
外连接分为左外连接,右外连接,全外连接
左外连接:以左面的表作为驱动表,会将该表中所有记录都显示出来,对于不满足连接条件的记录,结果都集中若包含右面的表中的字段时,
这些字段的值全部填写为NULL
SELECT e.ename,e.deptin,d.depton,d.dname,d.loc
FROM myemp1_liuwenshou e LEFT JOIN mydep1_liuwenshou d
ON( e.deptin=d.depton)
||
也可以写成
SELECT e.ename, d.dname
FROM myemp1_liuwenshou e LEFT JOIN mydep1_liuwenshou d
WHERE e.deptin=d.depton(+)//+号加在相反的位置
右外连接:以右面的表作为驱动表
全外连接:两面的数据都要显示,不满足连接条件的记录哪边不满足哪边的字段补NULL
SELECT table1.column, table2.column
FROM table1 [ LEFT | RIGHT | FULL] JOIN table2
ON table1.column1 = table2.column2;
自连接
自己表中的记录对应自己表中的其他记录,自己表与自己表及你想那个关联查询,这种设计通常是为了解决不知道层级数的树状结构数据的保存
例如:淘宝的宝贝分类:类别下面还有类别
公司的员工设计:员工可能管理其他员工
SELECT e.empno,e.ename,m.ename,m.empno
FROM myemp1_liuwenshou e,myemp1_liuwenshou m
WHERE e.mgr=m.empno(+)
子查询:子查询可以被引用的地方很多
外层查询的SELECT子句中可以嵌套子查询
外层查询的FROM子句中可以嵌套子查询
外层查询的WHERE子句中可以嵌套子查询(最常见)
DDL语句也可以嵌入子查询
DML语句也可以嵌入子查询
eg:查找和SCOTT同职位的员工
SELECT ename,job,deptin
FROM lwsemp
WHERE deptin=(SELECT deptin FROM lwsemp WHERE ename='FORD')
将查询结果作为表创建出来:CREATE TABLE+新表名+AS+查询结果
CREATE TABLE newname
AS
SELECT ...
子查询根据查询结果分为:
单行单列:查询的结果只有一行且只有一列
单行多列:查询的结果有多行但是只有一列
多行多列:查询结果有多列,单行多行无所谓
单列子查询用于WHERE
多列子查询用于FROM
当子查询的结果为多行单列的,那么判断“=”时要使用“IN”,判断等于列表中一项
eg:和职位是MANAGER相同部门的员工
SELECT ename,job
FROM lwsemp
WHERE deptin IN(SELECT deptin FROM lwsemp WHERE job='MANAGER')
AND job <> 'MANAGER'
若子查询结果为多行单列,那么判断“=”
EXISTS后面根一个子查询,EXISTS会判断查询是否能查处至少一条记录,能查询就返回true,否则返回false
eg:查询有员工的部门 /没有员工的部门只需在EXISTS前加NOT
SELECT depton,dname FROM lwsdept d
WHERE
EXISTS(SELECT * FROM lwsemp e WHERE e.deptin=depton)
子查询在HAVING部分
eg:查看最低薪水高于30号部门最低薪水的部门信息
SELECT MIN(sal),deptin
FROM lwsemp
GROUP BY deptin
HAVING MIN(sal)>(SELECT MIN(sal) FROM lwsemp WHERE deptin=30)
子查询在FROM部分
eg:查看那些比自己比自己部门的平均工资高的员工信息
SELECT e.ename,e.sal
FROM lwsemp e,(SELECT AVG(sal) sa,deptin
FROM lwsemp
GROUP BY deptin) s
WHERE e.deptin=s.deptin
AND e.sal>s.sa
子查询在SELECT部分可以认为是外连接的另一种表现形式
SELECT e.ename, e.sal, e.deptno,
(SELECT d.deptno FROM dept d
WHERE d.deptno = e.deptno) deptno
FROM emp e;
分页查询
ROWNUM是伪列,用于返回标识行数据顺序的数字。本身不存在任何一张表上,但是在查询任何一张表时
都可以查询该列,该列的值是行号
在编号的过程中,不要使用ROWNUM做 > 判断,否则查不到数据
利用ROWNUM截取结果集中的部分数据
eg:查看4-6行字段
SELECT *
FROM (SELECT ROWNUM rn,ename,sal,deptin
FROM lwsemp)
WHERE rn BETWEEN 4 AND 6
在分页时,需要结果按照某个字段进行排序时,要注意,由于使用ROWNUM编号是在查询数据的过程中进行的,而
排序是在查询结果之后进行的,这会导致编号后在进行排序,使得编号错乱
为此,要有排序工作时,我们先排序,再编号,做后根据编号取范围
使用子查询进行分页
每一页显示4条,显示第2页
pageSize=4
page=2
start=(page-1)*pageSize+1
end=page*pageSize
DECODE函数
DECODE (expr, search1, result1[, search2, result2…][, default])
用于比较参数expr的值,如果匹配到哪一个search条件,就返回对应的result结果,可以有多
组search和result的对应关系,如果任何一个search条件都没有匹配到,则返回最后default的
值。default参数是可选的,如果没有提供default参数值,当没有匹配到时,将返回NULL
eg:查询职员表,根据职员的职位计算奖励金额,当职位分别是’MANAGER’、’ANALYST’、’SALESMAN’时,
奖励金额分别是薪水的1.2倍、1.1倍、1.05倍,如果不是这三个职位,则奖励金额取薪水值
SELECT ename, job, sal,
DECODE(job, 'MANAGER', sal * 1.2,
'ANALYST', sal * 1.1,
'SALESMAN', sal * 1.05,
sal
) bonus
FROM lwsemp;
DECODE函数功能相似的有CASE语句,实现类似于if-else的操作
SELECT ename, job, sal,
CASE job WHEN 'MANAGER' THEN sal * 1.2
WHEN 'ANALYST' THEN sal * 1.1
WHEN 'SALESMAN' THEN sal * 1.05
ELSE sal END
bonus
FROM emp;
若希望将给定字段不同的值看作一组,其他作为另一组统计结果
eg:job中MANNAGER,ANALYST两种职位看作一组,其他看作一组
由于GROUP BY只能根据后面给定的内容值相容的记录分为一组,所以我们需要将MANAGER,ANALYST转换为相同的值才能被分为一组
这时我们可以使用DECODE函数来实现
SELECT DOUNT(*),DECODE(jpb,
'MANAGER','VIP',
'ANALYST','VIP',
'OTHER')
FROM lwsemp
GROUP BY DECODE(job,
'MANAGER','VIP',
'ANALYST','VIP',
'OTHER')
按照自定义顺序排序
SELECT depton,dname,loc
FROM dept
ORDER BY
DECODE(dname,
'OPERATIONS',1,
'ACCOUNTING',2,
'SALES',3 )
排序函数:
可以根据给定的字段进行分组,再根据给定的另外的字段排序,给予组内编号
分组的字段可以是多个
排序的字段也可以是多个
ROW_NUMBER()
给予组内连续且唯一的编号
eg:统计每个部门的工资排名
SELECT
ename,deptin,sal,
ROW_NUMBER()
OVER(PARTITION BY deptin ORDER BY sal DESC) rank
FROM lwsemp
RANK()函数生成组内不连续不唯一的数字
组内记录中排序的字段值相同的生成的数字也相同
SELECT
ename,deptin,sal,
RANK()
OVER(PARTITION BY deptin ORDER BY sal DESC) rank
FROM lwsemp
DENSE_RANK()函数生成组内连续不唯一的数字
SELECT
ename,deptin,sal,
DENSE_RANK()
OVER(PARTITION BY deptin ORDER BY sal DESC) rank
FROM lwsemp
集合操作:两个查询结果集可以进行并集,交集,差集
查询的字段,顺序,数量必须完全一样
SELECT statement1
[UNION | UNION ALL | INTERSECT | MINUS]
SELECT statement2;
UNION和UNION ALL用来获取两个或两个以上结果集的并集:
UNION操作符会自动去掉合并后的重复记录。
UNION ALL返回两个结果集中的所有行,包括重复的行。
UNION操作符对查询结果排序,UNION ALL不排序
查看每天的销售总额
SELECT year_id,month_id,day_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY year_id,month_id,day_id
ORDER BY year_id,month_id,day_id
--每月的销售总额
SELECT year_id,month_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY year_id,month_id
ORDER BY year_id,month_id
--每年的销售总额
SELECT year_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY year_id
ORDER BY year_id
--总销售额
SELECT SUM(sales_value)
FROM lwssales_tab
ROLLUP()函数
ROLLUP BY ROLLUP(a,b,c)
等价于
ROLLUP BY a,b,c
UNION
ROLLUP BY a,b
UNION
ROLLUP BY a
UNION
全表
eg:把所有的分类放一张表上
SELECT year_id,month_id,day_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY ROLLUP(year_id,month_id,day_id)
ORDER BY year_id,month_id,day_id
CUBE()函数:GROUP BY CUBE(a, b, c)等价于 a, b, c & a, b & b, c & a , c & a & b & c & 全表
eg:SELECT year_id,month_id,day_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY CUBE(year_id,month_id,day_id)
ORDER BY year_id,month_id,day_id
GROUPING SETS()
可以根据给定的字段组合进行分组,将结果并在一起返回
eg:显示每天的销售额与每月的销售额
SELECT year_id,month_id,day_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY GROUPING SETS((year_id,month_id,day_id),(year_id,month_id))
ORDER BY year_id,month_id,day_id
视图与表一样,也是数据库对象,视图不是真实的表,但是在SQL语句中出现的位置与表相同
试图对应的是一条SQL语句,使用视图可以简化SQL的编写,重用子查询,或者限制数据访问
创建视图的语法:
CREATE [OR REPLACE] VIEW view_name[(alias[, alias…])]//创建或替换,建议加上OR REPLACE
AS subquery ;
eg:创建一个试图v_emp_10来显示部门10中的员工的编码,姓名,薪水
CREATE OR REPLACE VIEW lws_v_emp_10
AS
SELECT empno id,ename name,sal salary,deptno
FROM clc_emp
WHERE deptno=10
查看试图结构:DESC v_emp_10
简单视图可以进行DML操作,但是复杂试图不行,但通常不会对试图进行DML操作
视图对应的查询语句中的字段可以使用别名,这样视图中的该字段就用别名作为字段名了,在查询视图中对应字段的值时,需使用别名来查询
向视图中插入数据等于向基表中插入了数据。并且插入的这条记录中只有视图看得到的字段会有值,其他字段全部插入NULL。
这里就西药注意了,若视图看不见的字段在emp表中被定义为NOT NULL那么就会导致插入失败,因为会违反emp表的非空约束
修改或删除视图中的数据,只能修改或删除视图现在能看的到的数据
向emp中插入一条这个视图自己看不见的数据
删除视图中的数据实际上就是删除了emp表中的该条记录
CHECK OPTION约束的视图
语法如下:
CREATE [OR REPLACE] VIEW view_name[(alias[, alias…])]
AS subquery
[WITH CHECK OPTION];
其中:WITH CHECK OPTION短语表示,通过视图所做的修改,必须在视图的可见范围内
假设INSERT,新增的记录在视图仍可查看
假设UPDATE,修改后的结果必须能通过视图查看到
假设DELETE,只能删除现有视图里能查到的记录
eg:创建带有CHECK OPTION约束的视图:
CREATE OR REPLACE VIEW v_emp_10
AS
SELECT empno id, ename name, sal salary, deptno
FROM emp
WHERE deptno = 10
WITH CHECK OPTION;
READ ONLY约束的视图:只读选项
当一个视图被定义为只读的,那么该视图不允许执行DML操作
eg:创建带有READ ONLY约束的视图:只读选项
CREATE OR REPLACE VIEW v_emp_10
AS
SELECT empno id, ename name, sal salary, deptno
FROM emp
WHERE deptno = 10
WITH READ ONLY;
USER_VIEWS获取相关信息,数据字典
和视图相关的数据字典有:
USER_OBJECTS
USER_VIEWS
USER_UPDATABLE_COLUMNS
例一:在数据字典USER_OBJECTS中查询所有视图名称:
SELECT object_name FROM user_objects
WHERE object_type = 'VIEW';
例二:在数据字典USER_VIEWS中查询指定视图:
SELECT text FROM user_views
WHERE view_name = 'V_EMP_10';
例三:在数据字典USER_UPDATABLE_COLUMNS中查询视图:
SELECT column_name, insertable, updatable, deletable
FROM user_updatable_columns
WHERE table_name = 'V_EMP_10';
查看用户创建过的表
SELECT * FROM user_tables
/SELECT table_name FROM user_tables
查看 用户创建过的视图
SELECT * FROM user_views
SELECT test FROM user_views 查看视图对应的查询语句
查看用户创建过的所有数据库对象
SELECT object_name FROM user_objects
创建复杂视图:
复杂视图中对应的SELECT语句会出现表达式,函数,分组等操作
并且还有表达式,函数的字段必须给别名,复杂视图不允许执行DML,所以复杂函数不需加只读约束
eg:创建一个实现各部门薪水的视图
CREATE OR REPLACE VIEW v_emp_sal
AS
SELECT MAX(sal) max_sal,MIN(sal) min_sal,AVG(sal) avg_sal,SUM(sal) sun_sal,deptno
FROM emp
GROUP BY deptno
删除视图,只是将视图对应的SELECT语句删掉了,不会对基表产生影响
序列(SEQUENCE)是一种用来生成唯一数字值的数据库对象。序列的值由Oracle程序按递增或递减顺序自动生成,通常
用来自动产生表的主键值,是一种高效率获得唯一键值的途径。
语法:CREATE SEQUENCE [schema.]sequence_name
[ START WITH i ] [ INCREMENT BY j ]
[ MAXVALUE m | NOMAXVALUE ]
[ MINVALUE n | NOMINVALUE ]
[ CYCLE | NOCYCLE ][ CACHE p | NOCACHE ]
其中:
sequence_name是序列名,将创建在schema方案下序列的第一个序列值是i,步进是j
如果j是正数,表示递增,如果是负数,表示递减
序列可生成的最大值是m,最小值是n
如果没有设置任何可选参数,序列的第一个值是1,步进是1
CYCLE表示在递增至最大值或递减至最小值之后是否继续生成序列号,默认是NOCYCLE
CACHE用来指定先预取p个数据在缓存中,以提高序列值的生成效率,默认是20
创建序列:用来生成一组数字
CREATE SEQUENCE seq_emp_lws
START WITH 100
INCREMENT BY 10
序列有两个伪列
NEXTVAL:使序列生成下一个数字
CURRVAL:获取序列的当前值
需要注意,当序列刚创建完毕后,一定要先调用一次NEXTVAL使序列生成一个数(START WITH)之后才可以调用CURRAVL
每调用一次NEXTVAL,序列都会用当前生成的数字加上步长来生成下一个
所以若需要使用之前生成的数字而不希望序列增长,可以使用CURRVAL
SELECT seq_emp_id.NEXTVAL FROM dual -->110
SELECT seq_emp_id.CURRAVL FROM dual -->110
向表中插入主键
INSERT INTO clc_emp
(empno,ename,sal,job,deptno)
VALUES
(seq_emp_lws.NEXTVAL,'MARRY',5000,'CLERK',30)
删除序列emp_seq:
DROP SEQUENCE emp_seq;
索引的原理:索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是独立于表的对象,可以存
放在与表不同的表空间(TABLESPACE)中。索引记录中存有索引关键字和指向表中数据的指针(地址)。对索引进行的I/O操作
比对表进行操作要少很多
索引一旦被建立就将被Oracle系统自动维护,查询语句中不用指定使用哪个索引,是一种提高查询效率的机制。
ROWID: 伪列,唯一标识一条数据记录,可理解为行地址
创建索引的语法:
CREATE [UNIQUE] INDEX index_name
ON table(column[, column…]);
其中:
index_name表示索引名称
table表示表名
column表示列名,可以建立单列索引或复合索引
UNIQUE表示唯一索引
eg:为lwsemp表的ename字段添加索引
CREATE INDEX idx_emp_ename_lws ON lwsemp(ename)
复合索引也叫多列索引,是基于多个列的索引。
如果经常在ORDER BY子句中使用job和salary作为排序依据,可以建立复合索引:
CREATE INDEX idx_emp_job_sal ON emp(job, sal);
当做下面的查询时,会自动应用索引idx_emp_job_sal
SELECT empno, ename, sal, job FROM emp
ORDER BY job, sal;
创建基于函数的索引
如果需要在emp表的ename列上执行大小写无关搜索,可以在此列上建立一个基于UPPER函数的索引:
CREATE INDEX emp_ename_upper_idx
ON emp(UPPER(ename));
当做下面的查询时,会自动应用刚刚建立的索引:
SELECT * FROM emp
WHERE UPPER(ename) = 'KING';
修改和删除索引,如果经常在索引列上执行DML操作,需要定期重建索引,提高索引的空间利用率,
语法如下:ALTER INDEX index_name REBUILD;
重建索引idx_emp_ename:
ALTER INDEX idx_emp_ename REBUILD;
当一个表上有不合理的索引,会导致操作性能下降,删除索引的语法:
DROP INDEX index_name;
删除索引idx_emp_ename:
DROP INDEX idx_emp_ename;
********************************************************************************************************************
*合理使用索引提升查询效率
*1,不要在小表(数据量不大)上创建索引
*2,为经常出现在WHERE子句中的列创建索引
*3,为经常出现在ORDER BY、DISTINCT后面的字段建立索引。如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致
*4,为经常作为表的连接条件的列上创建索引
*5,不要在经常做DML操作的表上建立索引
*6,限制表上的索引数目,索引并不是越多越好
*7,删除很少被使用的、不合理的索引
*******************************************************************************************************************
约束:约束(CONSTRAINT)的全称是约束条件,也称作完整性约束条件。约束是在数据表上强制执行的一些数据校验规则,当执行DML操作时,
数据必须符合这些规则,如果不符合则无法执行。
约束条件可以保证表中数据的完整性,保证数据间的商业逻辑。
约束条件包括:
非空约束(Not Null),简称NN
唯一性约束(Unique),简称UK
主键约束(Primary Key),简称PK
外键约束(Foreign Key),简称FK
检查约束(Check),简称CK
1,非空约束(Not Null)
当执行INSERT操作时,必须提供这个列的数据
当执行UPDATE操作时,不能给这个列的值设置为NULL
eg:CREATE TABLE employees (
eid NUMBER(6),
name VARCHAR2(30) NOT NULL,
salary NUMBER(7, 2),
hiredate DATE CONSTRAINT employees_hiredate_nn NOT NULL //创建表的时候自定义约束名
);
修改表时添加非空约束
可以在建表之后,通过修改表的定义,添加非空约束:
ALTER TABLE employees
MODIFY (eid NUMBER(6) NOT NULL);
取消非空约束
如果业务要求取消某列的非空约束,可以采用重建表或者修改表的方式:
ALTER TABLE employees
MODIFY (eid NUMBER(6) NULL);
唯一性约束:唯一性(Unique)约束条件用于保证字段或者字段的组合不出现重复值。
当给表的某个列定义了唯一约束条件,该列的值不允许重复,但允许是NULL值
eg:在建表employees的同时,在eid、email列上创建唯一约束条件,并在建表后
在name列上建立一个名为employees_name_uk的唯一约束条件
CREATE TABLE employees (
eid NUMBER(6) UNIQUE,//唯一约束
name VARCHAR2(30),
email VARCHAR2(50),
salary NUMBER(7, 2),
hiredate DATE,
CONSTRAINT employees_email_uk UNIQUE(email)//创建的时候增加一个约束名
);
在建表之后增加唯一性约束条件:
ALTER TABLE employees
ADD CONSTRAINT employees_name_uk UNIQUE(name);
主键约束:主键(Primary Key)约束条件从功能上看相当于非空(NOT NULL)且唯一(UNIQUE)的组合。主键字段可以是单字
段或多字段组合,即:在主键约束下的单字段或者多字段组合上不允许有空值,也不允许有重复值。
主键可以用来在表中唯一的确定一行数据。一个表上只允许建立一个主键,而其它约束条件则没有明确的个数限制。
在建表时添加主键约束条件:
CREATE TABLE employees2 (
eid NUMBER(6) PRIMARY KEY,
name VARCHAR2(30),
email VARCHAR2(50),
salary NUMBER(7, 2),
hiredate DATE
);
建表后创建主键约束条件,并自定义约束条件名称:
ALTER TABLE employees3
ADD CONSTRAINT employees3_eid_pk PRIMARY KEY (eid);
外键约束:外键约束条件定义在两个表的字段或一个表的两个字段上,用于保证相关两个字段的关系。比如emp表的deptno列参照dept表
的deptno列,则dept称作主表或父表,emp表称作从表或子表。在实际开发当中几乎不用
添加外键约束:先建表,在建表后建立外键约束条件:
CREATE TABLE employees4 (
eid NUMBER(6),
name VARCHAR2(30),
salary NUMBER(7, 2),
deptno NUMBER(4)
);
ALTER TABLE employees4
ADD CONSTRAINT employees4_deptno_fk
FOREIGN KEY (deptno) REFERENCES dept(deptno);
检查约束:检查(Check)约束条件用来强制在字段上的每个值都要满足Check中定义的条件。当定义了Check约束的列新增或修改数据时,
数据必须符合Check约束中定义的条件。
添加检查约束:员工的薪水必须大于2000元,增加检查约束:
ALTER TABLE employees4
ADD CONSTRAINT employees4_salary_check
CHECK (salary > 2000);
当插入大于2000的数据,操作成功:
INSERT INTO employees4(eid, name, salary, deptno)
VALUES(1236, 'donna noble', 2500, 40);
*性能最好Oracle分页查询
*select * from (
* select a.*,rownum RN from (
* select * from lwsmoney
* ) A where rownum <=10
*) where RN >=6
1,数据定义语言(DDL) : Data Definition Language
CREATE TABLE创建表,
ALTER TABLE修改表,
DROP TABLE删除表等动作
2,数据操纵语言(DML) : Data Manipulation Language
INSERT语句用于将数据插入到数据库中,
UPDATE语句用于更新数据库中已存在的数据,
DELETE用于删除数据库中已存在的数据
3,事务控制语言(TCL):Transaction Control Language
COMMIT用来确认已经进行的数据库改变,
ROLLBACK语句用来取消已经进行的数据库改变
SAVEPOINT语句用来设置保存点,使当前的事务可以回退到指定的保存点,便于取消部分改变
4,数据查询语言(DQL):Data Query Language
SELECT用来查询所需要的数据。使用最广泛,语法灵活复杂。
5,数据控制语言(DCL) : Data Control Language
GRANT用于给用户或角色授予权限,
REVOKE用于收回用户或角色已有的权限。
CREATE USER语句
Oracle数据类型
NUMBER(6,2)表示数字类型/NUMBER(2)
CHAR(20)表示固定长度的字符类型
VARCHAR2(100);表示变长的字符类型
DATE定义日期时间的数据
创建表:CREATE TABLE emp()
查看表格结构:DESC emp
查看表中数据:SELECT * FROM emp1_liuwenshou 查看表中数据(把*号换成字段号,字段号可以查看指定字段的数据)
查看表中指定字段数据:SELECT ename,job,sal FROM myemp1_liuwenshou
删除表格:DROP TABLE emp
赋默认值:DEFAULT ‘M’
非空(NOT NULL)
修改表名:RENAME old_name TO new_name;
增加列:ALTER TABLE employee ADD (hiredate DATE DEFAULT sysdate);
删除列:ALTER TABLE employee DROP (hiredate);
修改列:ALTER TABLE employee MODIFY(job VARCHAR2(40) DEFAULT 'CLERK' );
插入列:INSERT INTO employee(id, name, job, birth)
VALUES(1003, 'donna', 'MANAGER', TO_DATE('1978-09-01', 'YYYY-MM-DD'))
更新记录:UPDATE employee SET salary = 8500,gender='F' WHERE name = 'ROSE';
删除记录:DELETE FROM employee WHERE job is null;
字符串类型
SELECT CONCAT(ename,job) FROM myemp1_liuwenshou;在数据库中返回ename和job在同一个字段
SELECT CONCAT(CONCAT(ename,':'),job) FROM myempq_liuwenshou;在数据中返回ename和job在同一个字段,并且中间用:连接
SELECT ename||‘:’||sal FROM myempq_liuwenshou;在数据中返回ename和sal在同一个字段,并且中间用:连接
SELECT ename, LENGTH(name) FROM emp; 将列出name和name的字符串长度
SELECT UPPER('hello') FROM myemp1_liuwenshou;将字符转换为大写形式
SELECT LOWER('HELLO WORLD') FROM DUAL;将字符转换为小写形式
SELECT INITCAP('hello world') FROM DUAL;将字符串中每个单词的首字符大写,其它字符小写,单词之间用空格和非字母字符分隔
SELECT TRIM('e' from 'elite')FROM DUAL;表示从elite的前后截去e,e只能为单个字符
SELECT RTRIM('eeeefuckeqeeeeeqqq','eq') FROM DUAL;表示从eeeefuckeqeeeeeqqq右边截去e/q/eq/qe字符
SELECT LTRIM('eqqqeeeefuckeqeeee','eq') FROM DUAL;表示从eeeefuckeqeeeeeqqq左边截去e/q/eq/qe字符
SELECT ename,LPAD(sal,6,‘¥’) FROM emp_liuwenshou;把sal变成6个字符,不足的话用左边的¥补齐6,右边只能为单个字符
SELECT ename,RPAD(sal,6,‘¥’) FROM emp_liuwenshou;把sal变成6个字符,不足的话用右边的¥补齐6,左边只能为单个字符
SELECT SUBSTR('Doctor Who travels in TARDIS', 8, 3)FROM DUAL;//Who 在一个字符串中第8位开始连续截取3个数子串,8可以为负数
SELECT INSTR('think in java in my life','in',2,3)FROM DUAL;//15//从第2个字符开始检索in第3次出现的位置
数值函数
ROUND(n[, m])//SELECT ROUND(45.678,2) FROM DUAL //用于将参数n按照m的数字要求四舍五入,m可取(正,0,负)(- .+)
TRUNC(n[, m])//SELECT TRUNC(45.51,-1)FROM DUAL//的功能是截取,其中n和m的定义和ROUND(n[, m])相同
MOD(m, n)是取模函数//SELECT ename,sal,MOD(sal,1000)FROM myemp1_liuwenshou//返回m除以n后的余数,如果n为0则直接返回m
CEIL(n),//SELECT CEIL(45.678) FROM DUAL; --46/取大于n的最小整数
FLOOR(n)//SELECT FLOOR(45.678) FROM DUAL;//,取小于n的最大整数
日期类型
LECT SYSDATE FROM DUAL;//显示当前时间//将显示“03-MAY-14”的形式,如果是中文环境,将显示“03-5月-14”的形式。
SELECT TO_CHAR(SYSDATE,'yyyy-mm-dd day hh24:mi:ss') FROM DUAL;//显示当前时间//年-月-日 星期1 13:57:32
SELECT SYSTIMESTAMP FROM DUAL;//显示当前时间,精确到毫秒
SELECT TO_CHAR(SYSTIMESTAMP,'SSSS.FF') FROM DUAL;
日期转换函数
TO_DATE(char[, fmt[, nlsparams]]);//SELECT ename, TO_CHAR(hiredate, 'YYYY"年"MM"月"DD"日"') FROM emp;L//08-8月 -08
SELECT ename,sydate-hiredate FROM emp;//计算员工入职到现在多少天
SELECT sysdate-TO_DATE('1990-06-03','YYYY-MM-DD')FROM DUAL//计算出生多少天
SELECT TO_CHAR(sysdate,'YYYY-MM-DD')FROM DUAL//将当前时间以指定格式输出('YYYY-MM-DD'==2015-05-18)('YYYY"年"MM"月"DD"日"'==2015年05月18日)
SELECT TO_CHAR(TO_DATE('09-05-20','RR-MM-DD'),'YYYY-MM-DD')FROM DUAL//显示给定时间的世纪
SELECT LAST_DAY('20-2月-09') FROM DUAL;//查询09年2月的最后一天
SELECT ename, ADD_MONTHS(hiredate, 20 * 12) "20周年" FROM emp;//返回日期date加上i个月后的日期值//计算职员入职20周年纪念日:
SELECT ename,MONTH_BETWEEN(date1, date2) FROM emp://计算date1和date2两个日期值之间间隔了多少个月
SELECT NEXT_DAY(SYSDATE, i) FROM DUAL;//查询下个星期i是几号
SELECT LLEAST(expr1[, expr2[, expr3]]…) FROM DUAL//返回结果是参数列表中最小值
SELECT GREATEST(expr1[, expr2[, expr3]]…) FROM DUAL//返回结果是参数列表中最大值
SELECT EXTRACT(YEAR FROM SYSDATE) FROM DUAL;//取出当前日期的年
SELECT EXTRACT(HOUR FROM SYSTIMESTAMP) FROM DUAL;//取出当前日期的小时
SELECT EXTRACT(HOUR FROM TIMESTAMP '2008-10-10 10:10:10') FROM DUAL;取出指定时间的小时
空值操作
UPDATE student SET gender = NULL; //全表gender都被更新为null
SELECT * FROM mystudent_liuwenshou WHERE gender IS NULL;//用“列名 IS NOT NULL”来查询空数据。
SELECT * FROM mystudent_liuwenshou WHERE gender IS NOT NULL;//用“列名 IS NOT NULL”来查询非空数据。
空值函数
NVL(expr1, expr2):将NULL转变为非NULL值
SELECT ename, sal, comm, sal + NVL(comm, 0) FROM emp;//将取NULL值的comm列转换为0再进行运算,结果就不会为NULL了
SELECT ename,NVL2(comm,'有奖金','没奖金') FROM myemp1_liuwenshou//comm值不为NULL返回有奖金,为NULL返回没奖金
WHERE子句
在SELECT语句中使用WHERE子句可以添加过滤条件,当我们添加了WHERE后,数据库在检索对应的表时,会将表中每一条数据取出后使用WHERE进行判断,查看这条记录
中的字段值是否满足WHERE的要求,满足的话,这条记录将被查询出来,不满组就忽略。
WHERE是在第一次查询表中数据时进行过滤。***********************************************************************************************
所以表中有多少条数据,WHERE就会被执行几次,WHERE是在查询表中数据的时候被使用的
>:大于
< :小于
>= :大于等于
<=:小于等于
< >:不等于(!=,)数据库不等于常用< >,
= :等于
AND :相当于java中的 && 且
OR : 相对于java中的 || 或
AND的优先级是高于OR的
LIKE条件
%:表示0到多个字符
_:标识单个字符
eg:SELECT ename, job FROM emp WHERE ename LIKE '_A%';//查询职员姓名中第二个字符是‘A’的员工信息
IN和NOT IN 可以理解为一个范围比较操作符
SELECT ename, job FROM emp WHERE job IN ('MANAGER', 'CLERK');//查询职位是MANAGER或者CLERK的员工
IN通常被利用在子查询中,所以IN的功能不能被OR完全代替
SELECT ename, job FROM emp WHERE deptno NOT IN (10, 20);//查询不是部门10或20的员工
BETWEEN…AND…操作符用来查询符合某个值域范围条件的数据
SELECT ename, sal FROM emp WHERE sal BETWEEN 1500 AND 3000;//查询薪水在1500-3000之间的职员信息
ANY和ALL条件
> ANY(list):大于列表中最小的即可
< ANY(list):小于列表中最大的即可
> ALL(list):大于列表中最大的即可
< ALL(list):小于列表中最小的即可
ANY与ALL通常是用在判断一个子查询结果,几乎不会在列表中给定值,否则没什么意思
eg:查看比20号部门工资都高的员工有谁
SELECT ename,sal,deptin
FROM lwsemp
WHERE sal > ALL(SELECT sal FROM lwsemp WHERE deptin=20)
查询条件中使用表达式和函数
select ename,sal from myemp1_liuwenshou where UPPER(ename) = upper('ward')//名字为WARD的
SELECT ename,sal FROM myemp1_liuwenshou WHERE sal*12>50000//年薪大于50000的
DISTINCT过滤重复,会将其后定义的字段中重复的记录去除掉
SELECT DISTINCT job FROM myemp1_liuwenshou --查看公司有哪些职位
多列去重:当DISTINCT 后面有多个重复的时候,后面字段值没有的重复的输出
SELECT DISTINCT job,deptin FROM myemp1_liuwenshou//eg:1,1~2,2-3,3,3~2,3~3,3~4
DISTINCT只与SELECT连接
ORDER BY字句 :询出的数据按一定规则进行排序操作 NULL为最大值
ASC用来指定升序排序,DESC用来指定降序排序
SELECT <*, column [alias], …> FROM table [WHERE condition(s)] [ORDER BY column [ASC | DESC]] ;默认ASC,
eg:SELECT ename,sal FROM myemp1_liuwenshou ORDER BY sal//按工资升序排列 最后面加DESC按照将需排列
ORDER BY 也可以按照多个字段排序,每个字段都需要单独指定升序将需(有优先级的,第一次排列相同字段再拍第二级排列)
eg:SELECT ename,deptin,sal FROM myemp1_liuwenshou ORDER BY deptin DESC,sal
聚合函数:又叫做分组函数,多行函数。可以将一组数据进行统计然后得出一个结果。
MAX和MIN:取该列的最大值,最小值 只能操作数字类型,忽略NULL值
SELECT MAX(sal) max_sal, MIN(sal) min_sal FROM myemp1_liuwenshou;//获取机构下的最高薪水和最低薪水
AVG和SUM求平均值和总和 忽略null值的,如果有null值的,求平均值的时候需转换为0
SELECT AVG(NVL(sal,0)),SUM(sal) FROM myemp1_liuwenshou
COUNT函数用来计算表中的记录条数,同样忽略NULL值
SELECT COUNT(ename) FROM myemp1_liuwenshou//为了避免null值,ename用*代替可准确的查看表中有多少条目
SELECT COUNT(*) FROM myemp1_liuwenshou
分组
GROUP BY子句:需要把整个数据表按部门划分成一个个小组,每个小组中包含一行或多行数据,在每个小组中再使用分组函数进行计算,每组返回一个结果
通常GROUP BY子句中出现的字段应当是重复值较多的,否则分组没有意义
SELECT AVG(sal),deptin FROM myemp1_liuwenshou GROUP BY deptin--按部门计算平均工资 (前面能加deptin是因为该分组中deptin值相同)
HAVING字句,必须跟在GROUP BY后面
SELECT deptno, MAX(sal) max_sal FROM emp GROUP BY deptno HAVING MAX(sal) >4000;
//查询每个部门的最高薪水,只有最高薪水大于4000的记录才被输出显示
SELECT AVG(sal),deptin FROM myemp1_liuwenshuou GROUP BY deptin HAVING MAX(sal)>4500//按照部门最高工资大于4500的部门的平均工资
当一条查询语句中包含所有的子句,执行顺序依下列子句次序:
FROM 子句:执行顺序为从后往前、从右到左。数据量较少的表尽量放在后面。
WHERE子句:执行顺序为自下而上、从右到左。将能过滤掉最大数量记录的条件写在WHERE 子句的最右。
WHERE语句中不能限制分组结果
GROUP BY:执行顺序从左往右分组,最好在GROUP BY前使用WHERE将不需要的记录在GROUP BY之前过滤掉。
HAVING 子句:消耗资源。尽量避免使用,HAVING 会在检索出所有记录之后才对结果集进行过滤,需要排序等操作。
SELECT子句:少用*号,尽量取字段名称。ORACLE 在解析的过程中, 通过查询数据字典将*号依次转换成所有的列名, 消耗时间。
ORDER BY子句:执行顺序为从左到右排序,消耗资源。
关联的概念
eg:查看SALES部门工作的员工的所有名字
SELECT e.ename,d.dname
FROM myemp1_liuwenshou e,mydep1_liuwenshou d --标名太长,可在FROM语句中取别名便于其他代码中书写
WHERE e.deptin=d.depton
AND d.dname='SALES'
查询时,若使用N张表联合查询,那么必须只要有N-1个连接条件(WHERE后面的语句),若不添加连接条件,将出现笛卡尔积
笛卡尔积:A表中每条数据与B表每条数据连接生成的结果,对系统的资源占用大的破坏是严重的
内连接
SELECT e.ename, d.dname
FROM emp e JOIN dept d
ON(e.deptno = d.deptno);
WHERE d.dname='SALES'//效果同上 。查看SALES部门工作的员工的所有名字
外连接
当进行关联查询时,不满足连接条件的数据不会被显示在结果中,我们需要将不满足连接条件的记录也显示出来,就需要使用到外连接
外连接分为左外连接,右外连接,全外连接
左外连接:以左面的表作为驱动表,会将该表中所有记录都显示出来,对于不满足连接条件的记录,结果都集中若包含右面的表中的字段时,
这些字段的值全部填写为NULL
SELECT e.ename,e.deptin,d.depton,d.dname,d.loc
FROM myemp1_liuwenshou e LEFT JOIN mydep1_liuwenshou d
ON( e.deptin=d.depton)
||
也可以写成
SELECT e.ename, d.dname
FROM myemp1_liuwenshou e LEFT JOIN mydep1_liuwenshou d
WHERE e.deptin=d.depton(+)//+号加在相反的位置
右外连接:以右面的表作为驱动表
全外连接:两面的数据都要显示,不满足连接条件的记录哪边不满足哪边的字段补NULL
SELECT table1.column, table2.column
FROM table1 [ LEFT | RIGHT | FULL] JOIN table2
ON table1.column1 = table2.column2;
自连接
自己表中的记录对应自己表中的其他记录,自己表与自己表及你想那个关联查询,这种设计通常是为了解决不知道层级数的树状结构数据的保存
例如:淘宝的宝贝分类:类别下面还有类别
公司的员工设计:员工可能管理其他员工
SELECT e.empno,e.ename,m.ename,m.empno
FROM myemp1_liuwenshou e,myemp1_liuwenshou m
WHERE e.mgr=m.empno(+)
子查询:子查询可以被引用的地方很多
外层查询的SELECT子句中可以嵌套子查询
外层查询的FROM子句中可以嵌套子查询
外层查询的WHERE子句中可以嵌套子查询(最常见)
DDL语句也可以嵌入子查询
DML语句也可以嵌入子查询
eg:查找和SCOTT同职位的员工
SELECT ename,job,deptin
FROM lwsemp
WHERE deptin=(SELECT deptin FROM lwsemp WHERE ename='FORD')
将查询结果作为表创建出来:CREATE TABLE+新表名+AS+查询结果
CREATE TABLE newname
AS
SELECT ...
子查询根据查询结果分为:
单行单列:查询的结果只有一行且只有一列
单行多列:查询的结果有多行但是只有一列
多行多列:查询结果有多列,单行多行无所谓
单列子查询用于WHERE
多列子查询用于FROM
当子查询的结果为多行单列的,那么判断“=”时要使用“IN”,判断等于列表中一项
eg:和职位是MANAGER相同部门的员工
SELECT ename,job
FROM lwsemp
WHERE deptin IN(SELECT deptin FROM lwsemp WHERE job='MANAGER')
AND job <> 'MANAGER'
若子查询结果为多行单列,那么判断“=”
EXISTS后面根一个子查询,EXISTS会判断查询是否能查处至少一条记录,能查询就返回true,否则返回false
eg:查询有员工的部门 /没有员工的部门只需在EXISTS前加NOT
SELECT depton,dname FROM lwsdept d
WHERE
EXISTS(SELECT * FROM lwsemp e WHERE e.deptin=depton)
子查询在HAVING部分
eg:查看最低薪水高于30号部门最低薪水的部门信息
SELECT MIN(sal),deptin
FROM lwsemp
GROUP BY deptin
HAVING MIN(sal)>(SELECT MIN(sal) FROM lwsemp WHERE deptin=30)
子查询在FROM部分
eg:查看那些比自己比自己部门的平均工资高的员工信息
SELECT e.ename,e.sal
FROM lwsemp e,(SELECT AVG(sal) sa,deptin
FROM lwsemp
GROUP BY deptin) s
WHERE e.deptin=s.deptin
AND e.sal>s.sa
子查询在SELECT部分可以认为是外连接的另一种表现形式
SELECT e.ename, e.sal, e.deptno,
(SELECT d.deptno FROM dept d
WHERE d.deptno = e.deptno) deptno
FROM emp e;
分页查询
ROWNUM是伪列,用于返回标识行数据顺序的数字。本身不存在任何一张表上,但是在查询任何一张表时
都可以查询该列,该列的值是行号
在编号的过程中,不要使用ROWNUM做 > 判断,否则查不到数据
利用ROWNUM截取结果集中的部分数据
eg:查看4-6行字段
SELECT *
FROM (SELECT ROWNUM rn,ename,sal,deptin
FROM lwsemp)
WHERE rn BETWEEN 4 AND 6
在分页时,需要结果按照某个字段进行排序时,要注意,由于使用ROWNUM编号是在查询数据的过程中进行的,而
排序是在查询结果之后进行的,这会导致编号后在进行排序,使得编号错乱
为此,要有排序工作时,我们先排序,再编号,做后根据编号取范围
使用子查询进行分页
每一页显示4条,显示第2页
pageSize=4
page=2
start=(page-1)*pageSize+1
end=page*pageSize
DECODE函数
DECODE (expr, search1, result1[, search2, result2…][, default])
用于比较参数expr的值,如果匹配到哪一个search条件,就返回对应的result结果,可以有多
组search和result的对应关系,如果任何一个search条件都没有匹配到,则返回最后default的
值。default参数是可选的,如果没有提供default参数值,当没有匹配到时,将返回NULL
eg:查询职员表,根据职员的职位计算奖励金额,当职位分别是’MANAGER’、’ANALYST’、’SALESMAN’时,
奖励金额分别是薪水的1.2倍、1.1倍、1.05倍,如果不是这三个职位,则奖励金额取薪水值
SELECT ename, job, sal,
DECODE(job, 'MANAGER', sal * 1.2,
'ANALYST', sal * 1.1,
'SALESMAN', sal * 1.05,
sal
) bonus
FROM lwsemp;
DECODE函数功能相似的有CASE语句,实现类似于if-else的操作
SELECT ename, job, sal,
CASE job WHEN 'MANAGER' THEN sal * 1.2
WHEN 'ANALYST' THEN sal * 1.1
WHEN 'SALESMAN' THEN sal * 1.05
ELSE sal END
bonus
FROM emp;
若希望将给定字段不同的值看作一组,其他作为另一组统计结果
eg:job中MANNAGER,ANALYST两种职位看作一组,其他看作一组
由于GROUP BY只能根据后面给定的内容值相容的记录分为一组,所以我们需要将MANAGER,ANALYST转换为相同的值才能被分为一组
这时我们可以使用DECODE函数来实现
SELECT DOUNT(*),DECODE(jpb,
'MANAGER','VIP',
'ANALYST','VIP',
'OTHER')
FROM lwsemp
GROUP BY DECODE(job,
'MANAGER','VIP',
'ANALYST','VIP',
'OTHER')
按照自定义顺序排序
SELECT depton,dname,loc
FROM dept
ORDER BY
DECODE(dname,
'OPERATIONS',1,
'ACCOUNTING',2,
'SALES',3 )
排序函数:
可以根据给定的字段进行分组,再根据给定的另外的字段排序,给予组内编号
分组的字段可以是多个
排序的字段也可以是多个
ROW_NUMBER()
给予组内连续且唯一的编号
eg:统计每个部门的工资排名
SELECT
ename,deptin,sal,
ROW_NUMBER()
OVER(PARTITION BY deptin ORDER BY sal DESC) rank
FROM lwsemp
RANK()函数生成组内不连续不唯一的数字
组内记录中排序的字段值相同的生成的数字也相同
SELECT
ename,deptin,sal,
RANK()
OVER(PARTITION BY deptin ORDER BY sal DESC) rank
FROM lwsemp
DENSE_RANK()函数生成组内连续不唯一的数字
SELECT
ename,deptin,sal,
DENSE_RANK()
OVER(PARTITION BY deptin ORDER BY sal DESC) rank
FROM lwsemp
集合操作:两个查询结果集可以进行并集,交集,差集
查询的字段,顺序,数量必须完全一样
SELECT statement1
[UNION | UNION ALL | INTERSECT | MINUS]
SELECT statement2;
UNION和UNION ALL用来获取两个或两个以上结果集的并集:
UNION操作符会自动去掉合并后的重复记录。
UNION ALL返回两个结果集中的所有行,包括重复的行。
UNION操作符对查询结果排序,UNION ALL不排序
查看每天的销售总额
SELECT year_id,month_id,day_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY year_id,month_id,day_id
ORDER BY year_id,month_id,day_id
--每月的销售总额
SELECT year_id,month_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY year_id,month_id
ORDER BY year_id,month_id
--每年的销售总额
SELECT year_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY year_id
ORDER BY year_id
--总销售额
SELECT SUM(sales_value)
FROM lwssales_tab
ROLLUP()函数
ROLLUP BY ROLLUP(a,b,c)
等价于
ROLLUP BY a,b,c
UNION
ROLLUP BY a,b
UNION
ROLLUP BY a
UNION
全表
eg:把所有的分类放一张表上
SELECT year_id,month_id,day_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY ROLLUP(year_id,month_id,day_id)
ORDER BY year_id,month_id,day_id
CUBE()函数:GROUP BY CUBE(a, b, c)等价于 a, b, c & a, b & b, c & a , c & a & b & c & 全表
eg:SELECT year_id,month_id,day_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY CUBE(year_id,month_id,day_id)
ORDER BY year_id,month_id,day_id
GROUPING SETS()
可以根据给定的字段组合进行分组,将结果并在一起返回
eg:显示每天的销售额与每月的销售额
SELECT year_id,month_id,day_id,SUM(sales_value)
FROM lwssales_tab
GROUP BY GROUPING SETS((year_id,month_id,day_id),(year_id,month_id))
ORDER BY year_id,month_id,day_id
视图与表一样,也是数据库对象,视图不是真实的表,但是在SQL语句中出现的位置与表相同
试图对应的是一条SQL语句,使用视图可以简化SQL的编写,重用子查询,或者限制数据访问
创建视图的语法:
CREATE [OR REPLACE] VIEW view_name[(alias[, alias…])]//创建或替换,建议加上OR REPLACE
AS subquery ;
eg:创建一个试图v_emp_10来显示部门10中的员工的编码,姓名,薪水
CREATE OR REPLACE VIEW lws_v_emp_10
AS
SELECT empno id,ename name,sal salary,deptno
FROM clc_emp
WHERE deptno=10
查看试图结构:DESC v_emp_10
简单视图可以进行DML操作,但是复杂试图不行,但通常不会对试图进行DML操作
视图对应的查询语句中的字段可以使用别名,这样视图中的该字段就用别名作为字段名了,在查询视图中对应字段的值时,需使用别名来查询
向视图中插入数据等于向基表中插入了数据。并且插入的这条记录中只有视图看得到的字段会有值,其他字段全部插入NULL。
这里就西药注意了,若视图看不见的字段在emp表中被定义为NOT NULL那么就会导致插入失败,因为会违反emp表的非空约束
修改或删除视图中的数据,只能修改或删除视图现在能看的到的数据
向emp中插入一条这个视图自己看不见的数据
删除视图中的数据实际上就是删除了emp表中的该条记录
CHECK OPTION约束的视图
语法如下:
CREATE [OR REPLACE] VIEW view_name[(alias[, alias…])]
AS subquery
[WITH CHECK OPTION];
其中:WITH CHECK OPTION短语表示,通过视图所做的修改,必须在视图的可见范围内
假设INSERT,新增的记录在视图仍可查看
假设UPDATE,修改后的结果必须能通过视图查看到
假设DELETE,只能删除现有视图里能查到的记录
eg:创建带有CHECK OPTION约束的视图:
CREATE OR REPLACE VIEW v_emp_10
AS
SELECT empno id, ename name, sal salary, deptno
FROM emp
WHERE deptno = 10
WITH CHECK OPTION;
READ ONLY约束的视图:只读选项
当一个视图被定义为只读的,那么该视图不允许执行DML操作
eg:创建带有READ ONLY约束的视图:只读选项
CREATE OR REPLACE VIEW v_emp_10
AS
SELECT empno id, ename name, sal salary, deptno
FROM emp
WHERE deptno = 10
WITH READ ONLY;
USER_VIEWS获取相关信息,数据字典
和视图相关的数据字典有:
USER_OBJECTS
USER_VIEWS
USER_UPDATABLE_COLUMNS
例一:在数据字典USER_OBJECTS中查询所有视图名称:
SELECT object_name FROM user_objects
WHERE object_type = 'VIEW';
例二:在数据字典USER_VIEWS中查询指定视图:
SELECT text FROM user_views
WHERE view_name = 'V_EMP_10';
例三:在数据字典USER_UPDATABLE_COLUMNS中查询视图:
SELECT column_name, insertable, updatable, deletable
FROM user_updatable_columns
WHERE table_name = 'V_EMP_10';
查看用户创建过的表
SELECT * FROM user_tables
/SELECT table_name FROM user_tables
查看 用户创建过的视图
SELECT * FROM user_views
SELECT test FROM user_views 查看视图对应的查询语句
查看用户创建过的所有数据库对象
SELECT object_name FROM user_objects
创建复杂视图:
复杂视图中对应的SELECT语句会出现表达式,函数,分组等操作
并且还有表达式,函数的字段必须给别名,复杂视图不允许执行DML,所以复杂函数不需加只读约束
eg:创建一个实现各部门薪水的视图
CREATE OR REPLACE VIEW v_emp_sal
AS
SELECT MAX(sal) max_sal,MIN(sal) min_sal,AVG(sal) avg_sal,SUM(sal) sun_sal,deptno
FROM emp
GROUP BY deptno
删除视图,只是将视图对应的SELECT语句删掉了,不会对基表产生影响
序列(SEQUENCE)是一种用来生成唯一数字值的数据库对象。序列的值由Oracle程序按递增或递减顺序自动生成,通常
用来自动产生表的主键值,是一种高效率获得唯一键值的途径。
语法:CREATE SEQUENCE [schema.]sequence_name
[ START WITH i ] [ INCREMENT BY j ]
[ MAXVALUE m | NOMAXVALUE ]
[ MINVALUE n | NOMINVALUE ]
[ CYCLE | NOCYCLE ][ CACHE p | NOCACHE ]
其中:
sequence_name是序列名,将创建在schema方案下序列的第一个序列值是i,步进是j
如果j是正数,表示递增,如果是负数,表示递减
序列可生成的最大值是m,最小值是n
如果没有设置任何可选参数,序列的第一个值是1,步进是1
CYCLE表示在递增至最大值或递减至最小值之后是否继续生成序列号,默认是NOCYCLE
CACHE用来指定先预取p个数据在缓存中,以提高序列值的生成效率,默认是20
创建序列:用来生成一组数字
CREATE SEQUENCE seq_emp_lws
START WITH 100
INCREMENT BY 10
序列有两个伪列
NEXTVAL:使序列生成下一个数字
CURRVAL:获取序列的当前值
需要注意,当序列刚创建完毕后,一定要先调用一次NEXTVAL使序列生成一个数(START WITH)之后才可以调用CURRAVL
每调用一次NEXTVAL,序列都会用当前生成的数字加上步长来生成下一个
所以若需要使用之前生成的数字而不希望序列增长,可以使用CURRVAL
SELECT seq_emp_id.NEXTVAL FROM dual -->110
SELECT seq_emp_id.CURRAVL FROM dual -->110
向表中插入主键
INSERT INTO clc_emp
(empno,ename,sal,job,deptno)
VALUES
(seq_emp_lws.NEXTVAL,'MARRY',5000,'CLERK',30)
删除序列emp_seq:
DROP SEQUENCE emp_seq;
索引的原理:索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是独立于表的对象,可以存
放在与表不同的表空间(TABLESPACE)中。索引记录中存有索引关键字和指向表中数据的指针(地址)。对索引进行的I/O操作
比对表进行操作要少很多
索引一旦被建立就将被Oracle系统自动维护,查询语句中不用指定使用哪个索引,是一种提高查询效率的机制。
ROWID: 伪列,唯一标识一条数据记录,可理解为行地址
创建索引的语法:
CREATE [UNIQUE] INDEX index_name
ON table(column[, column…]);
其中:
index_name表示索引名称
table表示表名
column表示列名,可以建立单列索引或复合索引
UNIQUE表示唯一索引
eg:为lwsemp表的ename字段添加索引
CREATE INDEX idx_emp_ename_lws ON lwsemp(ename)
复合索引也叫多列索引,是基于多个列的索引。
如果经常在ORDER BY子句中使用job和salary作为排序依据,可以建立复合索引:
CREATE INDEX idx_emp_job_sal ON emp(job, sal);
当做下面的查询时,会自动应用索引idx_emp_job_sal
SELECT empno, ename, sal, job FROM emp
ORDER BY job, sal;
创建基于函数的索引
如果需要在emp表的ename列上执行大小写无关搜索,可以在此列上建立一个基于UPPER函数的索引:
CREATE INDEX emp_ename_upper_idx
ON emp(UPPER(ename));
当做下面的查询时,会自动应用刚刚建立的索引:
SELECT * FROM emp
WHERE UPPER(ename) = 'KING';
修改和删除索引,如果经常在索引列上执行DML操作,需要定期重建索引,提高索引的空间利用率,
语法如下:ALTER INDEX index_name REBUILD;
重建索引idx_emp_ename:
ALTER INDEX idx_emp_ename REBUILD;
当一个表上有不合理的索引,会导致操作性能下降,删除索引的语法:
DROP INDEX index_name;
删除索引idx_emp_ename:
DROP INDEX idx_emp_ename;
********************************************************************************************************************
*合理使用索引提升查询效率
*1,不要在小表(数据量不大)上创建索引
*2,为经常出现在WHERE子句中的列创建索引
*3,为经常出现在ORDER BY、DISTINCT后面的字段建立索引。如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致
*4,为经常作为表的连接条件的列上创建索引
*5,不要在经常做DML操作的表上建立索引
*6,限制表上的索引数目,索引并不是越多越好
*7,删除很少被使用的、不合理的索引
*******************************************************************************************************************
约束:约束(CONSTRAINT)的全称是约束条件,也称作完整性约束条件。约束是在数据表上强制执行的一些数据校验规则,当执行DML操作时,
数据必须符合这些规则,如果不符合则无法执行。
约束条件可以保证表中数据的完整性,保证数据间的商业逻辑。
约束条件包括:
非空约束(Not Null),简称NN
唯一性约束(Unique),简称UK
主键约束(Primary Key),简称PK
外键约束(Foreign Key),简称FK
检查约束(Check),简称CK
1,非空约束(Not Null)
当执行INSERT操作时,必须提供这个列的数据
当执行UPDATE操作时,不能给这个列的值设置为NULL
eg:CREATE TABLE employees (
eid NUMBER(6),
name VARCHAR2(30) NOT NULL,
salary NUMBER(7, 2),
hiredate DATE CONSTRAINT employees_hiredate_nn NOT NULL //创建表的时候自定义约束名
);
修改表时添加非空约束
可以在建表之后,通过修改表的定义,添加非空约束:
ALTER TABLE employees
MODIFY (eid NUMBER(6) NOT NULL);
取消非空约束
如果业务要求取消某列的非空约束,可以采用重建表或者修改表的方式:
ALTER TABLE employees
MODIFY (eid NUMBER(6) NULL);
唯一性约束:唯一性(Unique)约束条件用于保证字段或者字段的组合不出现重复值。
当给表的某个列定义了唯一约束条件,该列的值不允许重复,但允许是NULL值
eg:在建表employees的同时,在eid、email列上创建唯一约束条件,并在建表后
在name列上建立一个名为employees_name_uk的唯一约束条件
CREATE TABLE employees (
eid NUMBER(6) UNIQUE,//唯一约束
name VARCHAR2(30),
email VARCHAR2(50),
salary NUMBER(7, 2),
hiredate DATE,
CONSTRAINT employees_email_uk UNIQUE(email)//创建的时候增加一个约束名
);
在建表之后增加唯一性约束条件:
ALTER TABLE employees
ADD CONSTRAINT employees_name_uk UNIQUE(name);
主键约束:主键(Primary Key)约束条件从功能上看相当于非空(NOT NULL)且唯一(UNIQUE)的组合。主键字段可以是单字
段或多字段组合,即:在主键约束下的单字段或者多字段组合上不允许有空值,也不允许有重复值。
主键可以用来在表中唯一的确定一行数据。一个表上只允许建立一个主键,而其它约束条件则没有明确的个数限制。
在建表时添加主键约束条件:
CREATE TABLE employees2 (
eid NUMBER(6) PRIMARY KEY,
name VARCHAR2(30),
email VARCHAR2(50),
salary NUMBER(7, 2),
hiredate DATE
);
建表后创建主键约束条件,并自定义约束条件名称:
ALTER TABLE employees3
ADD CONSTRAINT employees3_eid_pk PRIMARY KEY (eid);
外键约束:外键约束条件定义在两个表的字段或一个表的两个字段上,用于保证相关两个字段的关系。比如emp表的deptno列参照dept表
的deptno列,则dept称作主表或父表,emp表称作从表或子表。在实际开发当中几乎不用
添加外键约束:先建表,在建表后建立外键约束条件:
CREATE TABLE employees4 (
eid NUMBER(6),
name VARCHAR2(30),
salary NUMBER(7, 2),
deptno NUMBER(4)
);
ALTER TABLE employees4
ADD CONSTRAINT employees4_deptno_fk
FOREIGN KEY (deptno) REFERENCES dept(deptno);
检查约束:检查(Check)约束条件用来强制在字段上的每个值都要满足Check中定义的条件。当定义了Check约束的列新增或修改数据时,
数据必须符合Check约束中定义的条件。
添加检查约束:员工的薪水必须大于2000元,增加检查约束:
ALTER TABLE employees4
ADD CONSTRAINT employees4_salary_check
CHECK (salary > 2000);
当插入大于2000的数据,操作成功:
INSERT INTO employees4(eid, name, salary, deptno)
VALUES(1236, 'donna noble', 2500, 40);
*性能最好Oracle分页查询
*select * from (
* select a.*,rownum RN from (
* select * from lwsmoney
* ) A where rownum <=10
*) where RN >=6
相关文章推荐
- SQLServer删除/重建/禁用/启用外键约束
- 小贝_mysql 存储引擎及事务概念
- 高并发系统中,数据库相关知识
- 往数据库添加的时候(只添加以前未添加的记录的写法)c#
- mysql乱码问题
- SQL C 接口
- 打开MySQL数据库远程访问的权限
- SQL集合运算
- 《Memcache技术学习》系列技术文章整理收藏
- 关于SQL server 2012无法打开物理文件“某某某”,操作系统错误5 :"(拒绝访问)"。(Microsoft SQL Server,错误 5120)
- 初学JDBC,防SQL注入简单示例
- MySQL concat函数的使用
- MySQL备份还原——mysqldump工具介绍
- 程序识别MySQL数据库中文的问题
- MySql Host is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts' 解决方法
- navicat工具 快捷键 -- Mysql
- SQOOP连接SQLServer2005错误
- [原创] Xcode中使用sqlite3访问数据库
- sqlite第三方类库:FMDB使用(转载)
- 安装MySQLdb模块