数据库总结

本文详细介绍了Oracle和MySQL数据库的基本操作,包括SQL语句的使用、事务处理、表的管理等内容,并对比了两种数据库的特点。
数据库:
oracle数据库,操作PGA(program global area) PGA操作SGA(system global are) 再反应磁盘上 所以有闪回机制 手动提交 
mysql数据3库:用户操作内存 内存反应磁盘 事物默认提交 每执行一条sql就自动提交一次 
集群RAC(real application clusters):好处:负载均衡 ,互为备份,失败迁移
接下来就是select语句: 
组函数group by 分组过滤 having 
多表查询 外连接 自连接 
select嵌套:单行子查询 多行子查询
接下来是数据增删改查:
大美玲 多大了 打错了 
接下来就是事物的概念和隔离级别(默认可重复读)
原一隔持 只要没有提交commit和回滚rollback,操作都在一个事务中。
最后表的增删改查和约束条件:
create alter drop rename 
除了表外的其他数据库对象:
索引 序列 同义词 
-----------------------------------------------------------------------------------------------------------------
oracle数据库
一般装在linux操作系统下(安装过程非常复杂);windows下默认的Pro Files安装大多软件 但中间有个空格会出现致命错误
全局数据库名orcl 码11  解锁HR和SCOTT用户 密码tiger 11 
    管理员模式登录sqlplus / as sysdba 可以解锁更多用户;
SQL Development可以连接linux的数据库
服务里设置:OraclServiceORCL启动 自动。之后即可通过sqlplus字符终端工具连接到Oracle Database
TNSlistener(用于远程登录:即图形终端登录)启动 自动。
甲骨文收购SUN收购mysql  稳定压倒一切9i 10g 11g
关系型数据库还有:微软的SQL Server IBM的DB2 sqlite
数据库加载到内存上就是实例:数据库位于硬盘上,实例位于内存中
集群RAC(real application clusters):好处:负载均衡 ,互为备份,失败迁移
mysql数据库:用户操作内存 内存反应磁盘
orcal数据库:操作PGA(program global area) PGA操作SGA(system global are) 再反应磁盘上 所以有闪回机制
Oracl表空间(PGA SGA 实例上 内存上)和数据文件(.dbf 磁盘上) 
数据库-》表空间-》段-》区间-》块
sqlplus链接数据库:sqlplus scott/11
看都有什么表:select *from tab; 看表:desc bonus;  日期格式从select sysdate from dual;可以看出来 或从数据字典看格式
看用户:show user;  conn hr/11练到hr
set linesize/pagesize 100 
/ 上一次的sql语句
col sal for 99999
col emal for a10 修改所占的空间大小 10个字符宽度


select:选择显示
select *from emp;显示emp所有    效率低 有*得查找   select empno,ename,job,mgr from emp; 效率高
select empno,ename,job,sal*12 from emp;
select empno,ename,job,sal*12 as "年  薪" from emp;as可省 “”有时也可省 ‘’单引号为 字符串 而 ""别名
select empno,ename,job,sal*12 as "年薪",sal*12+comm "年收入" from emp;结果不正确 
sal*12+comm 这个表达式包含NULL 所以表达式为NULL得改为nvl(comm,0)
面试时别忘了 福利待遇 年薪福利1000 15薪水没有问年终奖没有问餐补车补 出差旅游 定期培训
NULL!=NULL(没有)
× select *from emp where comm=NULL; 表达式里不能用=NULL匹配空
所以用select *from emp where comm is NULL;
c /form/from 可以修改  /再执行
ed修改  cs保存 alt+f4退出 /再执行

distinct:
select job from emp;则显示很多  select distinct job from emp;显示很少
select distinct deptno,sal from emp  注意distinct作用域是后面的所有列 作用是滤重  
||和concat:
select 'hello' || 'world' from dual; select 'hello' || 'world' "你好世界" from dual;
select enamel || ' is a ' || job from emp; 
今年917 15:01响了防空警报
select concat('hello','world') from dual;  orcal中concat只能有两个参数
select concat(ename,concat('的年薪',sal)) from emp;
sql语句是语言:select delete insert 符合ansi标准
sqlplus命令是:ed set col 
sqlplus → Oracle提供的工具,可在里面执行SQL语句,
它配有自己的命令(ed、c、set、col) 特点是缩写关键字。
where:where:(from where =/and/or或()/between and ) (from where like '正则')
select *from emp where comm is not NULL; where效率不高
select *from emp where deptno=10;严格匹配!! 模糊查询也是严格匹配 select *from emp where ename='KING';而不能写成ename='king'
select *from emp where hiredate='17-11月-81'; 注意格式 而不能写成hiredate= '1981-11-17 ' 得先看当前格式 
select sysdate from dual  查看系统当前的日期 (注意其格式)。
alter session set NLS_DATE_FORMAT='YYYY-MM-DD'更改日期格式  alter session set NLS_DATE_FORMAT='yyyy-mm-dd hh24:mi:ss'

select *from emp where sal!=3000 或 select *from emp where sal<>3000;
select *from emp where sal>1000 and sal<2000  
select *from emp where sal between 1000 and 2000  这是>=和<=   注意小值必须在前
select *from emp where hiredate between '1-2月-81' and ‘28-2月-82’  

select *from emp where deptno=10 or deptno=20; 10或20号部门信息 
或select *from emp where deptno in(10,20);
select *from emp where deptno not in(10,20)????????????????????????????????????????????

select *from emp where ename like 'S%' 以S开头的人名 严格匹配!!
like:模糊查询‘%’匹配任意多个或0个字符。‘_’匹配一个字符。
‘____'四个字母的  ’%ER‘ 以er结尾的
'%x_%' escape 'x' 或 '%\_%' escape '\'?????????????????????????? 
select * from emp where ename like '%\_% ' escape '\'  
想显示单引号 需再写一个单引号对其转义
SQL在解析where的时候,是从右至左解析的。所以:and时应该将易假的值放在右侧or时应该将易真的值放在右侧


order by:通常后面只接一个 记住删除完一个用户提交!!!!!!!!!!!!
order by 子句应放在select的结尾 order by会同时作用于多列 desc只作用于一列
select *from emp order by deptno, sal;两者都排序先排deptno 后排sal

select *from emp order by sal desc;降序排工资 只作用于前面紧挨着的
select *from emp order by sal desc,deptno desc;desc必须写两个
select *from emp order by comm desc;但是空值排前面了 可改为  select *from emp order by comm desc nulls last;
select empno,ename,sal,sal*12 年 from emp order by 年或者4 desc

select * from emp order by deptno, sal; order by会同时作用于多列。上例的运行结果会在同一部门内升序,部门间再升序。


单行函数:
lower、upper、initcap(开头转大写)
select lower('HSLDKF') 转小写
select sbustr('helloworld',3)from dual 从第三位取到结尾  从1开始计数
select sbustr('helloworld',3,5)from dual 从第三位取 取5个
select length('helloworld')字符数,lengthb('hello world') 字节数 from dual;汉语占2个字节
instr返回下标 简单 select instr('hello world', 'llo') from dual   
select ipad('abcd',10,’*‘) from dual 左填充6个*
select trim('h' from 'hello worldh') from dual; 只能删除开头 结尾的一个字符
replace('hello world','l','') 删除l
数字操作:
round(45.9323,2)保留两位小数 45.93 
runc(45.9322,2)截取2位小数
mod(1600,600) 求余
to_char/date/number: to_char里面只用一个‘’ to_date两个参数都用‘’
select sysdate from dual;看系统日期格式 不包含时间
select to_char(sysdate,'yyyy-mm-dd') from dual;
select to_char(sysdate,'day') from dual; 星期1
sysdate操作:
select sysdate-1 昨天,sysdate 今天 from dual;
select to_char(sysdate-1,'yyyy-mm-dd') 昨天,sysdate 今天,(sysdate + 1) 明天 from dual;注意有,
select sysdate + '12-12月-2000' from dual 日期只能加减日 日期不能加日期(与指针一样)
select empno,ename,hiredate,sysdate-hiredate "工龄" from emp;结果为天数
select ename,hiredate,months_between(sysdate,hiredate) from emp
select add_month(sysdate,108) from dual 108个月后的时间
员工入职时间:
select ename, hiredate, (sysdate - hiredate) 天, (sysdate - hiredate)/7 星期, (sysdate - hiredate)/30 月, (sysdate - hiredate)/365 年 from emp  

select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss "今天是" day') from dual  这里双引号不是别名的意思
select to_date('2015-05-11 15:17:06 今天是 星期一', 'yyyy-mm-dd hh24:mi:ss "今天是" day')from dual   

select ename,to_char(sal,'L9,999.99') from emp
select ename,to_number('¥1,600.00','L9,999.99') from emp

select sal*12+nvl2(comm,comm,0) from emp;有点象三目:nvl2(a, b, c)   当a = null 返回 c, 否则返回b
select nullif('hello','hello') from dual;当 a = b 时返回null, 不相等的时候返回a值。
coalesce(expr1, expr2, ..., exprn)找到第一个不为空的输出
case-when/decode分支: 
select empno,ename,sal as "涨前薪水",case job when 'PRESIDENT' then sal+1000 
 when 'MANAGER' then sal+800
 else sal+100 
 end 
as "涨后薪水" from emp 

select ename,job,sal 涨前薪水,decode(job,'PRESIDENT',sal+1000,
'MANAGER',sal+800,
sal+400) as 涨后薪水 from emp
**********************************************************************
组函数:组函数有缕空功能:avg会自动缕空
select sum/avg(sal) from emp; 对sal列求总和
select count(*) from emp;  count() 统计指定列的非空行数。


方式一select sum(comm)/count(*) 方式二:sum(comm)/count(comm) 方式三:avg(comm)    
方式一结果不同,方式二 和 方式三结果一样。
select count(*) from emp; 统计非空的个数 自动缕空
count(nvl(comm,0)) 屏蔽缕空
求emp表中的工种:select count(distinct job) from emp;  
select count(distinct mgr) from emp; 去重 有多少不同的个数


group by:求某个部门的平均工资
注意:所有没有包含在组函数中的列,都应该出现在group by之后
select  deptno, avg(sal) from emp group by deptno; 而select  deptno, avg(sal) from emp 这样写是错的
而select avg(sal) from emp 这样写是可以的
select deptno,sum(sal) from emp group by deptno; 每一组的总和
select deptno,sum(sal) from emp group by deptno order by deptno; 注意顺序!!!

select deptno, job, avg(sal)  from emp  group by deptno, job  order by 1; 
因为deptno, job 两列没有在组函数里面,所以必须同时在group by后面。
按部门,不同的职位统计平均工资。先按第一列分组,如果第一列相同,再按第二列分组。
   所以查询结果中,同一部门中没有重复的职位。
*************************************
顺丰无公害
SELECT column, group_function
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[HAVING group_condition]
[ORDER BY column];
*************************************
having:最好用在分好组的基础之上
使用 HAVING 过滤分组:
1. 行已经被分组。
2. 使用了组函数。
3. 满足HAVING 子句中条件的分组将被显示。
分组过滤 where子句不能用于组过滤avg sum count max...
查询平均薪水大于2000的部门 :
select deptno, avg(sal)  from emp  group by deptno  having avg(sal)>2000;

没有组函数时,既能使用where又能使用having:
求10号部门的平均工资:
select deptno, avg(sal)  from emp where deptno=10 group by deptno; having deptno=10也可以 因为没有组函数 
不能在 WHERE 子句中使用组函数;可以在 HAVING 子句中使用组函数。
where和having都是将满足条件的结果进行过滤。但是差别是where子句中不能使用组函数!

尽量采用where。如果有分组的话,where是先过滤再分组,而having是先分组再过滤。
当数据量庞大如1亿条,where优势明显。
group by增强:
select deptno,job,sum(sal) from emp group by rollup(deptno,job)
break on deptno skip 1设置格式 自己看 表达不出来 
break on null 取消设置

group by deptno,job
group by deptno
group by null
恰好是报表rollup函数 
**************************************************
多表查询:非常常用%80 即把不同表信息合成一个
从笛卡尔集中 滤除错误信息。
等值/不等值链接:
where子句后面的条件,是“=”为等值连接。不是“=”为不等值连接。
select e.empno,e.enmae,e.sal,d.dname from emp e,dept d where e.deptno=d.deptno
select e.empno,e.ename,e.sal,s.grade from emp e,salgrad, s where e.sal>=s.losal and e.sal <=s.hisal
左外/右外连接:
按部门统计员工人数:
select e.deptno,d.dname,count(e.empno) from emp e,dept d where e.deptno=d.deptno group by e.deptno,d.dname;
由于使用了组函数count(),所以组函数外的......
但发现40号部门没有显示出来,原因是40号部门没有员工
要显示40号(应该在40号部门位置显示0) 所以where要想满足 得用外连接:在最后的结果中,包含某些对于where条件来说
不成立的记录
where d.deptno=e.deptno(+) 左外连接 即保留等号左边的东西自连接 (e表中无40号部门的信息)
自连接:将同一张表视为多张表 xxx的老板是 yyy
select e.ename || '的上司是' ||nvl(b.ename,'himself'或写成e.ename) from emp e,emp b where e.mgr=b.empno(+)   b表中无老板信息
或 select concat( e.ename, concat(' 的老板是 ',  nvl(b.ename, '他自己' )) ) from emp e,  emp b where e.mgr = b.empno(+)


connect by prior empno = mgr 
start with mgr is null 
伪列:level 查则有,不查则无
select empno,ename,mgr,sal from emp connect by piror empno=mgr start with mgr is null order by 1
申通 顺丰 
子查询:select 语句的嵌套
例如求出工资比scott(人名)高的
select sal from emp where ename='SCOTT';结果是3000 然后select *from emp where sal>3000;
上2条语句可以合并select *from emp where sal>(select sal from emp where ename='SCOTT');
子查询注意事项:......
select *from emp 等价于 select *from (select *from emp)
子查询的结果仅仅是个集合 有无顺序 分组 都无所谓 因为还得对此集合进行筛选

查询部门名称是“SALES”的员工信息:
主查询:查询员工信息。select * from emp;
子查询:负责得到部门名称(在dept表中)、部门号对应关系。select deptno from dept where dname='SALES'    
select *from emp where deptno=(select deptno from dept where dname='SALES')?????????????????????
或多表查询也可以:
select e.* from emp e,dept d where e.deptno=d.deptno and d.dname='SALES
当子查询也行,多表查询也行时,就用多表查询。子查询有多个from效率低 设计物理操作
oracle对子查询有优化 效率高于多表查询 还是用子查询
单行子查询:子查询可以放在select后,但,要求该子查询必须是 单行子查询
select empno,ename,sal from emp;可以
但是select empno,(select dname from dept where deptno=20),ename,sal from emp;也可以 
因为select dname from dept where deptno=20 只有一行(一行一列)结果 单行
但是select empno,(select dname from dept where deptno=20 or deptno=10)ename,sal from emp;不行
在 having 后 和 where 类似。但需注意在where后面不能使用组函数!!!!!!!!!!!!!!!
select ename,sal,sal*12 from emp; 等价于 select * from (...)   即from后放的是一个集合 select本身就是一个集合
单行子查询只能使用单行操作符;多行子查询只能使用多行操作符
=><!是单行操作符 即这些operator后面的表达式只能有1行结果 能放组函数但结果必须是一行,上面的例子
多行子查询:子查询返回2条记录以上就叫多行
多行操作符: 
in列表中的任意一个;not in;all和子查询返回的所有值比较;ANY和子查询返回的任意一个值比较 
查询部门名称为SALES和ACCOUNTING的员工信息:
多行子查询 select *from emp e,dept d where e.deptno=d.deptno and (d.name='SALES' or d.dname ='account')或
多表查询 select e.* from emp e where deptno in (select deptno from dept where dname='SALES' or dname='account')或
select e.* from emp e where deptno in (select deptno from dept where dname in ('SALES','account')
any:
查询薪水比30号部门任意一个员工高的员工信息:
select * from emp where sal > (select sal from emp where deptno=30);错 
select * from emp where sal > any(select sal from emp where deptno=30);正确 
或者单行子查询:select e.* from emp e where sal>(select min(sal) from emp where deotno=30)
all: any/all 没有明确的区别
查询薪水比30号部门所有员工高的员工信息:
Select * from emp where sal > all (select sal from emp where deptno=30); 
或单行子查询:Select * from emp where sal > (select max(sal) from emp where deptno=30); 
子查询中的NULL问题:
查询是老板的员工信息:select * from emp where empno in (select mgr from emp ); 
查询不是老板的员工信息:select * from emp where empno not in (select mgr from emp);  然而返回无结果
如果集合中有NULL值,不能使用not in。如:a not in (10, 20, NULL),等价于 (a != 10) and (a != 20) and (a != NULL)
Null值并不是一个值,而是表示特定含义,其所表示的含义是“Unknow”,可以理解为未定义或者未知 最后一个表达式恒为错
select * from emp where empno not in (select mgr from emp where mgr is not null);
一般不在子查询中使用order by
一般情况下,子查询使用order by或是不使用order by对主查询来说没有什么意义。子查询的结果给主查询当成集合来使用,
所以没有必要将子查询order by。但,在Top-N分析问题中,必须使用order by
一般先执行子查询,再执行主查询
含有子查询的SQL语句执行的顺序是,先子后主。但,相关子查询例外
eg:
1------------------
找到员工表中工资最高的前三名,按如下格式输出:
select rownum,empno from emp where rownum <=3 order by sal desc;
select rownum,empno,ename,sal from emp where rownum <=3 order  by rownum 
select rownum,empno,ename,sal from emp where rownum <=4 and rownum>=1 order  by rownum 
select rownum,empno,ename,sal from emp where rownum <=8 and rownum>=5 order  by rownum 这样不行 用子查询
rownum排序的是最原先的 要想结果是顺序的就得必须用子查询,先把顺序排好
select rownum ,r.* from (select empno,ename,sal from emp order by sal desc) r where rownum<3;
分页显示:在上一步的基础上 根据rownum进行筛选即可
select *from (select rownum r,r1.* from (select empno,ename,sal from emp order by sal desc) r1 where rownum<8;)where r<=8 
and r>=4
r1改成r也可以
总结:求工资前三名非常简单,但是加上rownum就麻烦了。分页显示又是由于rownum的原因又得子查询
2------------------
找到员工表中薪水大于本部门平均薪水的员工:
select e.empno,e.ename,e.sal,d.avg(sal) 
from emp e,(select deptno,avg(sal) avgsal from emp group by deptno)d
where e.deptno=d.deptno and e.sal>d.avg(sal)  为什么不行
因为1where后面不能有组函数 2>是单行操作符 avg(sal)是多行值
多表查询最好起别名 起别名最好要用
so:
select e.empno, e.ename, e.sal, d.avgsal
    from emp e, (select deptno, avg(sal) avgsal  from emp group by deptno) d
where e.deptno=d.deptno and e.sal > d.avgsal;
用相关子查询法:


3------------------
统计每年入职的员工个数:
select to_char(hiredate ,'yyyy'), count(*) from emp group by to_char(hiredate ,'yyyy')
*************************************************************
集合运算
交集、并集、差集
union关键字将多条 select 语句联合在一起。
查询部门号是10和20的员工信息:
select * from emp where deptno in(10, 20) 等价于 select * from emp where deptno=10 or deptno=20  
select * from emp where deptno=10 unionselect * from emp where deptno=20 


按照部门统计不同工种的工资情况。要求显示deptno、job、和sum(sal)三列,有小计和总计:
select deptno, job, sum(sal) from emp group by rollup(deptno, job)

参与运算的各个集合,【必须】列数相同,且类型一致。  to_char/to_number/to_date(NULL)
set timing on/off 打开、关闭SQL语句执行时间监视。


数据处理
SQL语句分类:数据库中,称呼增删改查。为DML语句。
DML语句:有回滚机制(Data Manipulation Language 数据操纵语言)insert、update、delete、select这四个操作。
DDL语句:无回滚机制(Data Definition Language 数据定义语言)。如:truncate table(截断/清空 一张表)
create table(表)、create view(视图)、create index(索引)、create sequence(序列)、create synonym(同义词)、alter table、
drop table。
  DCL语句:(Data Control Language数据控制语言)如:commit(提交)、rollback(回滚) 
插入的时候可写NULL 此为显示的插入
values(&empno,...可以通过键盘输入)

insert单行插入:insert into values
1. insert into 表名 values(所有列的值); 
desc emp;
insert into emp values(1000,'as','clerk'/null,7698/null,sysdate,3000,20,10);
insert into emp values(1005,'Bone','Raphea', 7829, to_date('17-12月-82', 'DD-MON-RR'),NULL, 300, 20);

2. insert into 表名(指定列) values(对应指定列的值); 
insert into emp(empno, ename, sal, deptno) values(1002, 'Marry', 6000, 20);  
&符号:
insert into 表名(指定列) values(&对应指定列的变量值); 
批量插入:
待插入的表结构要与源数据表结构一致。
insert into 表名 select 语句。------子查询可以用于DML语句

update单行修改:update set where
update 表名 set  列名=新列值 [ , 列名=新列值]  where deptno=100;
update emp10 set sal=4000, comm=300 where ename = 'CLARK';

delete删除:
delete from 表名 where 过滤某行、某几行
delete from emp10 where empno=7782;

delete 和 truncate:
1. delete ---DML , truncate:DDL   delete支持rollback、闪回。 truncate:不支持。
2. delete 删除后表空间不释放。truncate,释放表空间。
3. delete 逐行删除表数据。truncate,先将表摧毁,按表结构重建。
4. delete 逐行删除,会产生碎片。 truncate,没有碎片产生。 Oracle delete优化后没有碎片。


事务:
数据库操作序列组成的逻辑执行单元(那三种语句组成的命令集合),要么都成功,要么都失败。
四大特性:原子性、一致性、隔离性当数据库被多个客户端并发访问时,隔离它们的操作。持久性。
开启标志:一个DML语句。执行一个增删改查语句,只要没有提交commit和回滚rollback,操作都在一个事务中。
结束的标志:
显示的提交回滚:commit、rollback
隐式的commit:create、truncate、drop、alter、quit、exit
隐式的rollback:掉电、宕机、异常终止。

保存点:
savepoint 保存点名称
rollback to savepoint 保存点名称

隔离级别:
SQL99: --- 4种 mysql均支持。
Oracle:--- 3种。  1. 读已提交。 2. 串行化 3. 只读 read only
脏读:事务B读取了事务A尚未提交的数据
不可重复读:事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。
幻读:与时间有关系
序列化:
一般默认可重复读级别:一旦系统开始读取工资卡信息(即事务开始),singo的老婆就不可能对该记录进行修改,
也就是singo的老婆不能在此时转账。
创建和管理表:
create:
1. create table 表名(列名 列类型[, 列名 列类型]);
2. create table 表名 as select 某一张表 where 
3. create table 表名 as select 多张表 where 
create table test1 (tid number, tname varchar2(20), hiredate date default sysdate) 
insert into test1(tid, tname) values(11, 'wangwu')   插入时没有指定Hiredate列,取当前时间。

alter:
添加列: alter table 表名 add 列名 列类型
alter table test1 add image blob
修改列属性: alter table 表名 modify  列名 新列类型 alter table test1 modify tname varchar2(40)
删除列:alter table 表名 drop column 列名
改列名:alter table 表名 rename  column 旧列名 to 新列名

drop:
drop table 表名;   ---表被删至回收站 (show recyclebin 查看, purge recyclebin 清空)
drop table 表名 purge;  ---删除表不经过回收站。

rename:
rename 表名 to 新表名


约束:
1. 非空 not null 人的名字 id
2. 唯一 unique 电子邮件地址,不可以重复。
3. 主键 primary  key 通过这个列的值可以唯一的确认一行记录,主键约束隐含Not null + Unique
4. 检查 check  gender只能是男或者女 check (gender in ('男', '女'))
5. 外键 foreign key 
级联置空:ON DELETE set null 但删除父表时 将子表外键一列设置为NULL值,断开引用关系,然后删除父表
级联删除:ON DELETE CASCADE 当删除父表时,如发现父表内容被子表引用,级联删除子表引用记录
建议:constraint给约束其别名。

create table student 
( sid number constraint student_PK primary key,  学生Id主键约束
sname varchar2(20) constraint student_name_notnull not null,学生姓名非空约束
email varchar2(20) constraint student_email_unique unique学生邮件唯一约束
    constraint student_email_notnull not null,同时邮件可再设非空,没有“,”
age number constraint student_age_min check(age > 10),学生年龄设置check约束
gender varchar2(6) constraint gender_female_or_male check(gender in ('男', '女')), 
deptno number constraint student_FK references dept (deptno) ON DELETE SET NULL 
)   


其他数据库对象

视图 
1. 将创建表的关键字 tale -- view
2. 优点1: 简化复杂查询逻辑
  优点2: 限制数据的访问
3. 注意事项:
1. 视图不能提高数据检索的性能
2. 不建议使用视图修改表数据。
序列
create sequence 序列名;
序列名.nextval
弊端:
1. 多表公用序列,可能造成主键不连续
2. rollback, 可能造成序列不连续
3. 意外断电、宕机, 可能造成主键不连续。
drop sequence 序列名;  
索引:
create index 索引名 on 表名(列名)
索引由Orale数据库自动维护。
drop index 索引名。
同义词
给表起别名。
Create synonym 同义词名 for 表名
drop synonym 同义词名
认证


**************************************************************
启动Oracle数据库:sqlplus /nolog
当看到 SQL> 后    connect /as sysdba
输入 show user 查看, 提示USER is "SYS"
输入 startup(up前没有“空格”)启动数据库。
select * from scott.emp;可以查看scott用户下的emp表信息。由于当前是sys用户,所以要scott.emp
quit
lsnrctl start/stop/status可以启动监听/停止/查看服务状态。
使用scott用户连接数据库 sqlplus scott/tiger  密码不是tiger我的就是11






proc编程:借助c语言和oracle提供的语法,将c程序和oracle数据连接。即通过c访问数据库
proc简介:
静态SQL
gcc hello.c -o test -L/home/oracle_11/app/oracle/product/11.2.0/db_1/lib     指定库目录
-I/home/oracle_11/app/oracle/product/11.2.0/db_1/precomp/public  指定头文件""
-lclntsh 指定库名 libclnish.so
oerr ora 1234 即根据错误号1234看具体的错误
locate stddef.h 比find找文件更吊!看到是linux/4.4.4/  所以得修改proc的配置文件;从错误入手 分析思路

curd:insert/update/delete
oracle数据类型:宿主变量就是用来接 或者 设置数据库的传的信息
Oracle数据类型及转换
proc ---> orcle
宿主变量c数据类型: int、char、char[]、varchar
外部数据类型:   宿主变量数据类型和内部数据类型 并集。
内部orcle数据类型:varchar2、date、number
结论:当编写proc/c++应用程序,只会使用到宿主变量数据类型。

自动转换: varchar  ---> struct { len, con } 这个简单,但显示的时候得有.arr所以可读性不强
手动数据类型转换:得借助EXEC SQL TYPE
typedef char dname_t[20];  定义新数据类型 dname_t (字符数组)

EXEC SQL TYPE dname_t is string(20);
dname_t dname;
然后就可以直接显示了
宿主变量和指示变量:“跟班”== 指示变量  (short _ind)
宿主变量 有一个小跟班,跟班用来描述 宿主变量存储的值,是否为 null。
当 跟班为 -1 时,无论宿主变量存何值,写入数据库的一定是 null值
当数据库存储的为null时,select从数据库查询数据时,跟班一定为 -1。
typedef varchar例子;指示变量例子 -1 NULL;通讯区例子 判断错误;
错误处理和通讯区:
sqlca { ....
sqlcode = 0 错误码
sqlerrm { sqlerrml, sqlerrmc }; 错误信息
sqlerrd[2]} select查询的行数
EXEC SQL whenever sqlerror do/continue/stop sqlerr();  //注册错误处理回调函数
void sqlerr(void) {
exec sql whenever sqlerror continue;//防递归
printf("%.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
exec sql rollback release;
exit(1);}
宿主数组:一下接10个源数据库的数据
char dname[10][20];    dnameType dname[10];
short dname_ind[10];
exec sql select deptno,dname, loc into :deptno, :dname, :loc:loc_ind from dept
返回行数: int num = sqlca.sqlerrd[2];
for (i = 0; i < num; i++)
exec sql for :num insert into dept(deptno, dname, loc) values(:deptno, :dname, :loc:loc_ind);
普通游标:单行单行的获取数据 游标一定是为某一次select查询而生的。
1. 创建游标 -----  游标一定是为某一次查询而生的。
exec sql decleare 游标名 couser for select deptno, dname, loc from dept;
2. 打开游标:
标志着两件: 1. 查询数据集,保存内存中。
2. 游标指向数据集首行。
exec sql open 游标名
3. 提取数据:fetch  into 提取一行
while (1) {
exec sql fetch 游标 into :deptno, :dname, :loc;
if (sqlca.sqlcode == 100 || 1403) 
break}
处理数据。
4. 关闭游标
exec sql close 游标名。
滚动游标:......相对 绝对的概念
Makefile:写百遍了
动态proc:即实现自己的sqlplus工具
动态proc1:可以insert update delete 
动态proc2:prepare一个有空的(a,b占位)sql语句 再通过using填充上空(类似&填充)   人机交互\(^o^)/~
上面是非select语句 无返回值 下面有返回值所以得用宿主变量接
动态proc3:通过游标指向填充好的第一行数据 若有数据用宿主变量接
动态proc4:既可以处理select语句 又可处理非select语句
ansi标准:对select返回空间的大小 进行动态扩容
 很复杂 思想是:                                                       ↑是oracle
====================================================================================================
看是否安装了mysql:命令是 rpm -aq | grep mysql                            ↓是mysql
MYSQL:
安装启动关闭连接:首屈一指是开源 分布式源于mysql的开源 ui颓势 前端还行 
社区版:精简(linux(32,64位) windows) 通用(常用5.6.20) 完整 源码 
商业版
su - root 
mysql的服务器是个守护进程 ps -u mysql 
mysql -uroot -p123456-->show databases-->
show create database mydb1(看存储格式)-->
use mysql-->show tables-->desc student--->
看引擎事物自动提交show create table student(看存储格式 为什么我的后面是latin别人后面没有,可能一开始建的时候设置成其他了)
-->select *From user\G;

#service mysql start 
数据库的curd
create database mydb1;创建一个数据库
create/alter database mydb1 character set utf8;指定数据库字符集
show create database mydb1
drop database mydb1;删除一个数据库
表的curd(r是查询显示的意思)
在use 一个数据库后才能进行下面的
create table teacher(tid int,tname varchar(20));在数据库中创建teacher表
show tables; show create t1;desc teacher;

rename table teacher to worker 修改表名为worker;
alter table worker add height double;再增加一个属性列  desc worker;
alter table worker drop height;删除一个属性列
alter table worker modify ename varchar(40)修改列属性
alter table worker character set gb2312 修改字符集;show create table worker

drop table worker;删除 没有闪回机制
表数据curd--insert/update/delete/select
insert into worker employee values ..............
update worker set salary=salary+400 where id=2;
delete from worker where name='王五'
truncate worker;直接清空所有 删除大量数据效果明显

常用函数
where后不能用组函数 别名也不行
select now()+-1 from dual;加减1s 既有日期又有时间
select date_asdd(now(),INTERVAL -1 day)
select date_add(now(), INTERVAL -1 day) 昨天, now() 今天, date_add(now(), INTERVAL 1 day)  明天 from dual;
concat()这里不用嵌套 
多表查询:这里反而比子查询效率高
左外右外连接
内连接:
方法1:   from emp e, dept d where e.deptno = d.deptno;
方法2:   from emp e inner join dept d on e.deptno = d.deptno  
“,” ----》 inner join
“where” ----> on
左外链接、右外链接。
“,” ----》  left/right outer join 
“where” ----> on
左外: from dept d left outer join emp e on d.deptno = e.deptno  
(表达式 的 左右 不是决定性因素, 表的顺序是决定性因素)
右外: from emp e right outer join dept d on d.deptno = e.deptno 
自连接:
将一张表当成多张表看待。
ifnull(a, b)  ----> nvl(a, b)
nullif(a, b) : 判断两个字符串是否 一样 。 相等--》 null 否则 返回 
中文mysql处理
那个图
按什么方式存的表就按什么方式查看表 


cat /etc/sysconfig/i18n 看本机的默认存储是utf8 环境变量
改当前用户的环境变量vi .bash_profile 改成C source .bash_profile 生效 注销
数据库中按照utf8插入 插入的是???
**********************************************
文档读懂%20--30就可以写了 读写同时进行
makefile:gcc hello.c -o hello -I /usr/include/mysql -lmysqlclient -L/usr/lib64/mysql/ -lstdc++ -ldl -lpthread -lrt
基础的Mysql API函数:
MYSQL *mysql;
mysql_init(mysql);初始化一个mysql句柄
mysql_real_connect(mysql, ip, user, passwd, db, port, NULL, 0);连接数据库
mysql_errno(mysql); mysql_error(mysql);错误处理
mysql_close(mysql);关闭连接
mysql_query(mysql, “任意SQL语句”);  执行sql语句
MYSQL_RES *result = mysql_store_result(mysql);  获取结果集
mysql_num_fields(result); mysql_field_count(mysql);获取列数
MYSQL_ROW row = mysql_fetch_row(result); while() fetch一行数据  typedef char ** MYSQL_ROW ;
row[i]
MYSQL_FIELD *field = mysql_fetch_fields(result);获取行中所有列
field[i].name
表数据的访问:
curd:insert/update/delete
实现一个mysql的工具
init()
connect();
while (1) {
fgets(); 接收用户输入的sql语句;
mysql_query();  执行sql语句  ---- 有结果集 -- 无结果集 
if () {
获取结果集
获取列数
打印表头
打印行数据。
} else {
mysql_affected_row();  sql影响多少行。}}
desc  show  
预处理类的API 函数
MYSQL_MYSQL_STMT *stmt;
stmt = mysql_stmt_init(mysql);初始化预处理句柄
mysql_stmt_prepare(stmt, sql语句,length)带有占位符 的sql
MYSQL_BIND bind[N];
bind[0].is_null  ...... 初始化
mysql_stmt_bind_param(stmt, bind);  绑定 占位符变量
mysql_stmt_execute(stmt);
相较于 基础类API 预处理API优势,对于多次执行的 sql来说,只解析一次。
日期类的API函数
多查询执行API
mysql_real_connect(mysql, ip, user, passwd, db, port, NULL, CLIENT_MULTI_STATEMENTS);
mysql_next_result();
mysql事物
事物:是一个或者多个sql语句的组合 要么都成功要么都失败
如果提交到了数据库里,rollback的话则不会成功的
原子性、一致性、持久性、隔离性。
mysql_query():   执行select语句
执行非select语句  insert... create  drop
设置中文 set names utf8
启动事务
修改事务属性
默认: mysql的事务  自动提交 ---- ENGINE=InnoDB 
修改 autocommit 来设置为 手动。


在线安装mysql:
sudo apt-get install mysql-server mysql-client









































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值