oracle数据库笔记(自用)

oracle数据库是关系型数据库(二元数据表)拥有自己的结构化查询语言

安装介质:

database最为重要,是oracle数据库服务器

gateways为透明网关,提供oracle访问其他数据库系统的功能(跨域访问数据)

了解一下oracle11g的安装过程;字符编码一般使用GBK,看需求换utf-8

测试数据库是否成功:cmd命令tnsping orcl

注:orcl为oracle默认数据库

oracle的五个默认用户名:

1.sys

2.system

3.sysman

4.dbsnmp

5.scott(测试用户)

sys拥有数据库超级管理员权限,可使用sysdba(系统数据库管理员),sysoper(系统数据库操作员),normal三种角色

system拥有dba权限,仅能使用默认角色(dba)

Oracle默认端口号为:1521


数据库服务:

OracleDBConsoleocrl:浏览器使用的oracle企业管理器,用于图表绘制(?)

OracleJobScheduler:Oracle作业调度服务,

OracleiSQLPlus 是isqlplus的服务,要使用isqlplus,必须开启该服务

OracleTNSListener 监听器服务,服务只有在数据库需要远程访问时才需要(无论是通过另外一台主机还是在本地通过 SQL*Net 网络协议都属于远程访问),不用这个服务就可以访问本地数据库,它的缺省启动类型为自动。服务进程为TNSLSNR.EXE,参数文件 Listener.ora,日志文件listener.log,控制台LSNRCTL.EXE,默认端口1521、1526。

OracleService 数据库服务,这个服务会自动地启动和停止数据库。如果安装了一个数据库,它的缺省启动类型为自动。服务进程为ORACLE.EXE,参数文件initSID.ora,日志文件SIDALRT.log,控制台SVRMGRL.EXE、SQLPLUS.EXE。


sqlplus使用:

cmd终端连接数据库命令:sqlplus 用户名/密码 as 角色名(sys一般使用sysdba)

示例:sqlplus sys/root as sysdba


Oracle表空间

在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 ;

Oracle用户

建用户的典型脚本:

--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角色使用最高权限,否则会因权限不足创建失败。


Oracle表

认识使用:

-- 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 二进制字段


Oracle视图

了解即可

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。 二者的区别在于刷新方法的不同。(根据名字知道触发刷新的条件)


Oracle存储过程

了解,基本看懂意思就行

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包和包体:懒得看就不看了,感觉用处不大

另外,Oracle可以自定义函数查询,但用处不大,会把这个需求条件放在服务端开发

--示例:
creat or replace function 函数名(字段名 in 类型名?) return 类型名
as
--字段名 类型
begin
--函数体(查询操作等)
--可以定义异常退出
end 函数名

Oracle触发器Trigger,表示对数据库的进行某种操作时会执行触发器中的内容
create or replace trigger 触发器名
--触发条件
	before insert or update or delete of 字段名 on 表名
--没操作一行就会进行操作
	for each row
declare
	字段名 类型
begin
	函数体
	if 操作名(deleting) then ...

Oracle导出与导入

导出

•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

oracle数据库笔记(自用)_第1张图片

此图为exists

oracle数据库笔记(自用)_第2张图片

其实不用看统计结果就可知道,两个子句的查询分解操作是一样的,原理就是两张表做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


常见函数 **sysdate**:获取当前时间

**timestamp:**当前时间戳

instr()函数:对特定字符串进行定位

instr(目标字符串,需要匹配的字符串)例:instr(‘test.txt’,’.’),返回值为5

**substr()**函数:对数值进行截取

substr(字符串,起始位置,长度)注意,在oracle中数据起始位置为1

instr和substr可以进行联用


ltrim() rtrim() trim()

删除左、右,两端空格


trunc()函数:对数值或者日期进行截取

数值:trunc(数值,保留小数位)

日期:trunc(日期,日期格式)


**round()函数**

对数值进行四舍五入操作

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导出快,属于物理导出(直接导出表结构和数据记录结构),不支持跨域操作


Oracle排序问题:

排序的操作最好用一下三种函数,使用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)

你可能感兴趣的:(oracle数据库,数据库,oracle,database)