oracle数据库是关系型数据库(二元数据表)拥有自己的结构化查询语言
database最为重要,是oracle数据库服务器
gateways为透明网关,提供oracle访问其他数据库系统的功能(跨域访问数据)
了解一下oracle11g的安装过程;字符编码一般使用GBK,看需求换utf-8
测试数据库是否成功:cmd命令tnsping orcl
注:orcl为oracle默认数据库
1.sys
2.system
3.sysman
4.dbsnmp
5.scott(测试用户)
sys拥有数据库超级管理员权限,可使用sysdba(系统数据库管理员),sysoper(系统数据库操作员),normal三种角色
system拥有dba权限,仅能使用默认角色(dba)
Oracle默认端口号为:1521
OracleDBConsoleocrl:浏览器使用的oracle企业管理器,用于图表绘制(?)
OracleJobScheduler:Oracle作业调度服务,
Oracle
Oracle
OracleService 数据库服务,这个服务会自动地启动和停止数据库。如果安装了一个数据库,它的缺省启动类型为自动。服务进程为ORACLE.EXE,参数文件initSID.ora,日志文件SIDALRT.log,控制台SVRMGRL.EXE、SQLPLUS.EXE。
cmd终端连接数据库命令:sqlplus 用户名/密码 as 角色名(sys一般使用sysdba)
示例:sqlplus sys/root as sysdba
在Oracle中一个用户只能对应一个数据库,但一个用户可以拥有多个表空间。
表空间的作用:规划数据表,也就是说,每个数据表都是某个表空间的子对象
(与mysql的区别:mysql一个用户可以有多个数据库,数据表建立在数据库上)
若在创建表时未指定表空间,都会自动创建于用户指定的默认表空间。
CREATE TABLESPACE "TS_HOPETARGLE"
LOGGING
--数据文件地址,大小
DATAFILE 'D:\ORACLE\ORADATA\TS_HOPETARGLE.ora' SIZE 5M
--自动扩展空间
AUTOEXTEND
--每次扩展的空间为10m,无限制,赋予管理员权限
ON NEXT 10M MAXSIZE UNLIMITED EXTENT MANAGEMENT LOCAL
--自动管理分段空间
SEGMENT SPACE MANAGEMENT AUTO ;
建用户的典型脚本:
--user用户名,profile为用户配置文件,一般为默认
CREATE USER "HIS3_JK" PROFILE "DEFAULT"
--indentified密码,默认表空间为什么
IDENTIFIED BY "hisjk" DEFAULT TABLESPACE "TS_YYGL"
--不锁定该用户
ACCOUNT UNLOCK;
--授予用户dba权限
GRANT "DBA" TO "HIS3_JK";
注意在创建表空间和用户时,需要用sys用户的sysdba角色使用最高权限,否则会因权限不足创建失败。
认识使用:
-- Create table
create table SCM_FUND
(
FUND_ID VARCHAR2(10) not null,
FUND_CODE VARCHAR2(50),
ORDER_NUM NUMBER(5) default 0,
HEADER VARCHAR2(10),
HAPPEN_AMOUNT NUMBER(14,4) default 0,
DELETE_FLAG NUMBER(1) default 0 not null,
DELETE_DATE DATE
) tablespace TS_HOPETARGLE_SCM ;
-- Add comments to the table
comment on table SCM_FUND is '供应链_经费项目';
-- Add comments to the columns
comment on column SCM_FUND.FUND_ID is '代码';
comment on column SCM_FUND.FUND_CODE is '编码';
comment on column SCM_FUND.ORDER_NUM is '排序序号';
comment on column SCM_FUND.HEADER is '经费负责人';
comment on column SCM_FUND.HAPPEN_AMOUNT is '发生金额';
comment on column SCM_FUND.DELETE_FLAG is '作废标志';
comment on column SCM_FUND.DELETE_DATE is '作废时间';
-- Create/Recreate primary, unique and foreign key constraints
alter table SCM_FUND add constraint PK_SCM_FUND primary key (FUND_ID)
using index tablespace TS_HOPETARGLE_SCM ;
Oracle中数据类型和mysql有所不同,注意甄别
Varchar2(4000) 字符型[4000为varchar2的上限大小] Number(1) 标志
Number(10) 整型 Number(14,4) 小数
Date 日期 Clob 大文本字段 Blob 二进制字段
了解即可
create or replace view oa_directory_va as
--Oracle中的||为拼接字符串的意思
select 'DIRECTORY-' || directory_id as pkey_id,
parent_id as pkey_parid,
directory_name as pkey_name,
'0' as pkey_type,
delete_flag,
type_flag,
from oa_directory;
普通视图为虚拟表,局限性大,任何对视图的查询都会转换为sql语句查询,对查询性能没有实际好处
物化视图为物理表,可以在视图中做直接查询,类型有ON DEMAND、ON COMMIT。 二者的区别在于刷新方法的不同。(根据名字知道触发刷新的条件)
了解,基本看懂意思就行
CREATE OR REPLACE PROCEDURE P_ROWTOCOL(AS_FROM VARCHAR2,AS_GROUPROW VARCHAR2,
AS_GROUPCOL VARCHAR2,AS_SUMCOL VARCHAR2,AS_SQL OUT VARCHAR2) IS
--动态行转列
V_SQL VARCHAR2(4000);
TYPE CUR_TYPE IS REF CURSOR;
CUR CUR_TYPE;
cursor cur_object is
select object_name from user_objects where object_name like 'V_ROWTOCOL_%' and object_type='VIEW' AND object_name NOT like LS_VIEWNAME
--2.列范围
V_COL := 'SELECT DISTINCT '||AS_GROUPCOL||' AS DM FROM '||AS_FROM||' ORDER BY '||AS_GROUPCOL;
OPEN CUR FOR V_COL;
--产生SELECT
V_SQL := 'SELECT '||AS_GROUPROW;
LOOP
FETCH CUR INTO LS_DM;
EXIT WHEN CUR%NOTFOUND ;
IF LS_DM IS NULL THEN
V_SQL := V_SQL||','||'SUM(CASE WHEN '||AS_GROUPCOL||' IS NULL THEN '||AS_SUMCOL||' ELSE 0 END) AS 空';
ELSE
V_SQL := V_SQL||','||'SUM(DECODE('||AS_GROUPCOL||','''||LS_DM ||''','||AS_SUMCOL||',0)) AS '||LS_DM;
END IF;
END LOOP;
CLOSE CUR;
AS_SQL := 'SELECT * FROM '||LS_VIEWNAME;
EXCEPTION
WHEN OTHERS THEN
AS_SQL := 'SELECT ''行转列出现异常错误:'||PKG_DB.GET_ERRORS()||''' AS COL FROM DUAL';
END;
另外,Oracle可以自定义函数查询,但用处不大,会把这个需求条件放在服务端开发
--示例:
creat or replace function 函数名(字段名 in 类型名?) return 类型名
as
--字段名 类型
begin
--函数体(查询操作等)
--可以定义异常退出
end 函数名
create or replace trigger 触发器名
--触发条件
before insert or update or delete of 字段名 on 表名
--没操作一行就会进行操作
for each row
declare
字段名 类型
begin
函数体
if 操作名(deleting) then ...
导出
•exp 用户名/密码@数据库名称(注意:如果未开启监听器,则无法使用@制定数据库) buffer=10000000 owner=需要导出数据表的用户名 file=导出的到的dmp文件名 log=日志文件名(txt文件)
示例:exp hopetargle/hopetargle@dev96 buffer=10000000 owner=hopetargle file=hopetargle.dmp log=ddd.txt
导出
示例imp hopetargle_yq/hopetargle buffer=10000000 full=y file=srm_yq.dmp log=hopetargle_yq.txt
注:数据导入时最好保证对象用户的表空间为空,或者对应表为空(可能会出现创建数据库报错情况)
闲聊一下in 和 exists两个子句:
从示例查询和资料搜索发现,两者在性能上并没有明显差别。下面为解释计划显示的数据:
此图为in
此图为exists
其实不用看统计结果就可知道,两个子句的查询分解操作是一样的,原理就是两张表做HASH JOIN SEMI。也可以通过时间看到两条sql语句最终转换成同一条sql。
两者的查询更倾向于使用HASH JOIN,但是当外表非常小,内表非常大的情况下,通过hint改变执行计划,filter的性能可以更优于HASH JOIN,也说明了not in不一定性能比not exists 差。
此为个人参考,且仅适用于Oracle11g环境
union运算实际是合并两个结果集中的所有记录,并将其中重复记录剔除(保证结果集中的记录唯一)
union all运算可看做并集,不剔除重复记录
intersect 交集运算,及同时存在于两张表的相同记录
minus减法运算,返回的是前一个集合中存在,且第二个集合中不存在的记录
这些联合运算可以进行混合使用,且优先级相同,从左至右顺序依次进行
这些运算子句放在两个查询语句的中间
示例:
select student_name from a_students
intersect
select student_name from a_students
union all
select student_name from b_students
分为以下五种连接:
1.cross join(笛卡尔积)指两个表中所有的数据组合可能。基本不用
2.inner join 内连接 指两张表中同时满足判断语句条件的且两张表都存在的数据
此链接写法可以直接省略,以逗号隔开两个表,条件语句将on改为where即可。
3.left outer join 前一张表的所有行和后一张表满足条件的行,因此后面连接部分可能为空(null)
4.right outer join 后一张表的所有行和后一张表满足条件的行,因此牵连连接部分可能为空(null)。此链接会以left代替,交换两表顺序,避免关系混淆。
5.full outer join 所有行的超集,符合条件的所有行,因此两边数据都可能为空(null)
左外连接示例:
select a.site_id, b.site_name from test1 a left outer join test2 b on a. id = b. id
--如果a.id在b中查不到,则后面连接部分补充为null。这样说明应该能够理解上面右连接和全连接的意思了吧
插入操作(经常忘记写法)
insert into 表名(列名1,列名2…) values(值1,值2…)
若插入的列为全表,则可以将列名省略
批量插入操作
insert into 表名(列名1,列名2…) select 列名1,列名2… from 表名…
两表之间列名可以不同,但数量和字段类型必须相同
更新操作
单列省略
多列:
update 表名 set 列名1 = 列名1+1,列名2 = upper(列名2)…
业务需求基本较少
删除操作
delete from students where student_id>10;
删除操作需要注意条件问题!务必检查where条件判断是否加上
delete table可以写条件(where),可以进行回滚(undolog,flashback),需要进行提交commit
truncate table不能写条件,速度快,无法进行回滚,直接删除,不需要commit
**timestamp:**当前时间戳
instr()函数:对特定字符串进行定位
instr(目标字符串,需要匹配的字符串)例:instr(‘test.txt’,’.’),返回值为5
**substr()**函数:对数值进行截取
substr(字符串,起始位置,长度)注意,在oracle中数据起始位置为1
instr和substr可以进行联用
ltrim() rtrim() trim()
删除左、右,两端空格
trunc()函数:对数值或者日期进行截取
数值:trunc(数值,保留小数位)
日期:trunc(日期,日期格式)
对数值进行四舍五入操作
round(2.33,1) ->2.3
round(2.56,1) ->2.6
round(2.47)->2
round(2.3389,1)->2.3
四个示例应该可以看出规则吧
ceil()向上取整
floor()向下取整
以上两种泛用性不强
**mod()**函数的求余操作:mod(3,2)->1
**chr()函数与ascii()**函数:实现ascii码和字符之间的相互转换
decode()函数
示例:
select employee_id,last_name,job_id,salary
, decode(salary/2,1,10,2,20,60) as salary_pos
from hr.employees
解释:传入值为salary,当salary除2时,若结果为1,则返回10,若为2,则返回20,如果都不符合则返回60
case when的作用和decode相似,但是decode只能根据具体值判断,case when适用于范围判断
示例:
select employee_id,last_name,job_id,salary
,(case when salary>10000 then '高'
when salary>5000 then '中'
else '低' end) as salary_pos
from hr.employees
函数运算max,min,avg,sum一般与group by联用
在空值查询上需要使用is null判断
to_char(日期,日期格式),to_date(字符串,日期格式)
nvl(’’,‘空!’)空值处理,将空值转化为显示的空值
rownum在取最值的数据时,使用select嵌套查询
或者可以使用max函数进行嵌套查询。后者的局限性较大,只能对单条记录进行查询
逻辑运算问题:>,<,=,!=,not,and,or
exp.exe导出较慢,属于逻辑导出(导出逻辑操作,增加语句和表创建语句),支持跨域操作
expdb.exe导出快,属于物理导出(直接导出表结构和数据记录结构),不支持跨域操作
排序的操作最好用一下三种函数,使用rownum字段的话需要进行表的嵌套查询,造成查询性能问题
SELECT t.*
,row_number() over(partition by t.type order by t.name) as px FROM STUDY_BAK20210102 T;
--[row_number() over(表达式) as 自定义列名]函数取得的排序为唯一排次
--partition by:用于分组内排序
--order by 按某列值大小排序
--asc升序,desc降序
SELECT t.*
,rank() over(partition by t.type order by t.name) as px FROM STUDY_BAK20210102 T ;
--[rank() over(表达式) as 自定义列名]函数取得的排序为可重复排次,且占据原始排次(例子:1,1,3,3,5)
SELECT t.*
,dense_rank() over(partition by t.type order by t.name) as px FROM STUDY_BAK20210102 T ;
--[dense_rank() over(表达式) as 自定义列名]函数取得的排序为可重复排次,不占据原始排次(例子:1,1,2,2,3)