ORACLE数据库-TNS协议分析详解

ORACLETNS协议分析

1TNS介绍

TNS协议是ORACLE服务端和客户端通讯的协议。TNS协议传输可以使用TCP/IP 协议、使用SSL的TCP/IP协议、命名管道和IPC协议传输,其中TCP/IP协议传输是使用明文传送。这里我们只分析基于TCP/IP协议上的TNS数据。

ORACLE网络通讯协议TNS有许多版本,并且大部分向下兼容,我们主要oracle 9.2.0.1.0客户和服务间的传输协议,他的协议版本号为312,其兼容到300。

TNS协议有一个通用的头,通用头包含一个请求数据类型。不同的服务请求和数据传输使用不同的请求数据类型。对于通常意义的查询操作一般使用数据类型,当出现错误或其他情况时可能使用其他类型。在分析过程中发现以下类型数据:

●查询语句出错会用标记(marker)类型

●客户端向服务器请求失败(如不存在的服务ID),服务器会发送拒绝(refuse)

类型

●客户机登陆会发送连接类型,而服务器返回一个重定向类型数据

●当重定向端口连接完成后客户端重现发送连接类型数据,服务器返回接受类型

数据,然后能够正常通讯。

2TNS数据格式

TNS数据包含一个通用的包头,这个包头包含包校验,包长度和包类型等信息。

不同的类型的数据实现不同功能的数据传输。

Common Packet Header 8 通用包头

Data 可变数据

2.1 通用包头格式

每个TNS完整数据都包含一个通用包头,他说明接受数据的长度及其相关校验和解析的信息。

Length 2 包的长度,包括通用包头

Packet check sum 2 包的校验和

Type 1 TNS类型

Flag 1 状态

Header check sum 2 通用头的校验和

注:

Length:包长度(包括包头)

Type:数据包的类型

类型号类型说明

1 连接(CONNECT)

2 接受(ACCEPT)

3 确认(ACK)

4 拒绝(REFUTE)

5 重定向(REDIRECT)

6 数据(DATA)

7 NULL

8

9 中止(ABORT)

10

11 重新发送(RESEND)

12 标记(MARKER)

13 ATTENTION

14 控制(CONTROL)

2.2 连接包结构(0x01)

在客户端和ORACLE要建立连接时,客户端首先发送一个连接结构,然后服务器返回重定向包(参见2.5)。

typedef struct TNS_CONNECT_header{

UCHAR NS_ver[2];

UCHAR Compatible_ver[2];

UCHAR ser_opt1;

UCHAR ser_opt2;

UCHAR SDU_size[2];

UCHAR TDU_size[2];

UCHAR NT_protocol_ch1;

UCHAR NT_protocol_ch2;

UCHAR Max_packets[2];

UCHAR Hardware_1[2];

UCHAR data_length[2];

UCHAR Offset[2];

UCHAR Max_data[4];

UCHAR flag0;

UCHAR flag1;

/*java thin interface has no items and id,

if it is not jdbc thin, use offset to override these 有些版本TNS协议中没有下面几项*/

UCHAR item1[4];

UCHAR item2[4];

UCHAR ID[8];

UCHAR unknown[8];

/*followed by decode_des_conn_data */

//连接字符串

}TNS_CONNECT_HEADER;

连接字符串格式:

如:

数据库一般的连接,即ESTABLISH的连接字符串为:

(DESCRIPTION=

(ADDRESS=

(PROTOCOL=TCP)

(HOST=topsec-syangjp)

(PORT=1521)

)

(CONNECT_DATA=

(SID=test)

(SERVER=DEDICATED)

(CID=

(PROGRAM=D:\oracle\ora92\bin\sqlplusw.exe)

(HOST=TOPSEC-MYANGJP)

(USER=myangjp)

)

)

)

2.3 接受包结构(0x02)

用户重定向之后,需要用重定向端口向服务器发送连接,客户端发送连接包,服务器连接成功则返回接受包,否则返回refuse包

struct TNS_ACCEPT_header{

unsigned char NS_ver[2];

unsigned char ser_opt1;

unsigned char ser_opt2;

unsigned char SDU_size[2];

unsigned char TDU_size[2];

unsigned char Hardware_1[2];

unsigned char data_length[2];

unsigned char Offset[2];

unsigned char flag0;

unsigned char flag1;

//unsigned char unknown[8];

/*no following data*/

};

2.4 拒绝包结构(0x04)

typedef struct TNS_REFUSE_header{ UCHAR uUserRefuseReason;

UCHAR uSysRefuseReason;

unsigned short int data_length;

//拒绝字符串

}TNS_REFUSE_HEADER;

拒绝字符串:

2.5 重定向包结构(0x05)

typedef struct TNS_REDIRECT_header{ UCHAR data_length[2];

UCHAR data; //长度为data_length;

//重定向数据

}TNS_REDIRECT_HEADER;

重定向数据:

2.6 标记包结构(0x0c)

typedef struct TNS_MARKER_header{

UCHAR data_length[3];

}TNS_REDIRECT_HEADER;

注:

当请求命令出错时,服务器会返回三个标记包

2.7 控制包结构(0x0d)

暂时没有发现该结构

2.8 数据包结构(0x06)

数据包负责传输数据库客户端和服务端的各种操作。每个操作由一个或几个命令组成,可以是在同一个数据包中有几个命令结构组合起来,也可以分开传输一些命令。

Common Header 8 通用包头

Data flag 2 状态

Command packet 可变数据

Command packet 可变数据

………

Command packet 可变数据

具体各种操作命令的组成和转换现在还不能完全确定,但是对于一些基本的SQL查询我们是可以分析的,下面我们主要分析一些命令结构和相关ORACLE操作的命令组成序列。

有些有许多结构和它的具体字节不影响ORACLE基本命令的分析,所以只做了简单的分析,对于SQL的一般查询语句TNS协议主要通过数据包的0x0303和0x035e命令来传输数据,返回结果主要是通过0x06和0x08命令传输数据,0x06主要传输数据,0x08主要传输系统配置相关数据。

2.8.1数据包通用结构

数据包有一个2字节的状态包和多个命令包组成:

Data flag 2 状态

Command packet 可变命令包

………

Command packet 可变命令包

注:

Data_flag一般情况为零,分析发现退出时为0x0040

Send token 0x0001

Request Confirmation 0x0002

Confirmation 0x0004

Reserved 0x0008

UNKNOWN 0x0010

More Data to Come 0x0020

End of File 0x0040

Do Immediate Confirmation 0x0080

Request to send 0x0100

Request Nt Trailer 0x0200

命令包(Command packet)结构如下:

Command 1 命令

Sub command 1 子命令

Data 可变命令包数据

注:

命令(Command)说明(以下命令为主命令的基本功能,但是还不能完全确认):0x01 Set Protocol

0x02 Set Data Type Representation

0x03 User to Oracle Request

0x04 Return Status

0x05 Access User Address Space

0x06 Raw Transfer Header

0x07 Raw Transfer Data

0x08 Return OPI(Oracle Program Interface) Parameter

0x09 Oracle Function Complete

0x0a N Error Return Definition

0x0b Sending I/o Vector only for fast UPI(User Program Interface)

0x0c Sending Long for Fast UPI

0x0d Invoke User Callback

0x0e Network Service

0x0f Data Intergrity

0x10 Supervisor

0x11

0x12

通过分析具体的包和一些其他相关软件,得到以下相关命令和子命令,许多命令还需要进一步确认

命令子命令类型说明使用

0x01 0x05 请求CLIENT TYPE

0x01 0x06 Set Protocol

0x01 0x2c IDENT

0x02 0x00 RESET

0x02 0x01 CHAR_MAP

0x02 0x54

0x03 0x01

0x03 0x02 SQL_OPEN

0x03 0x03 QUERY

0x03 0x04 QUERY SECOND

0x03 0x05 FETCH MORE

0x03 0x08

0x03 0x09 DISCONNECT

0x03 0x0E

0x03 0x27 SET_LANG

0x03 0x2B DESC_COLS

0x03 0x3B DB VERSION

0x03 0x47 FETCH

0x03 0x51 Set password

0x03 0x52 Set user

0x03 0x54 HANDSHAKE4

0x03 0x5E SQL

0x03 0x73 AUTH2

0x03 0x76 AUTH1

0x03 0x77 查询表结构信息DESC

0x04 0x01 ACK

0x04 0x02 ACK

0x04 0x05 ACK

0x06 0x00 More Row Result Info

0x06 0x01 First Row Result Info

0x08 0x01

0x08 0x05

0x08 0x08

0x08 0x9c Db version

0x10 0x19 Field Info SELEC返回

0x11 0x69

0x11 0x6b

0x11 0x78

2.8.2Data Format(length+data)

对于ORACLE的TNS协议结构中数据传输,其主要采用以下方式,即用一个标志和长度字符来传输数据。具体格式如下

●如果开始的大数据标志为0xfe,则结构如下

Big Data Identify 1

Data Length 1 返回列数

Data Data Length

………

Data Length 1 如果

Data Data Length

Data Length 1 0

●如果开始的大数据标志不为0xfe,则结构如下:

Data Length 1 返回列数

Data Data Length

2.8.2.1 字符串格式

(1)Char(n),nchar

Data 可变实际数据

Data1 可变空格

注:数据和数据1总长度为n

(2)Varchar(n)

Data 可变(<=n)实际数据

2.8.2.2 数字格式

(1)正数

Id 1 C0+整数部分长度整数部分Intlength=Id-c0

小数部分DecLength=length-intlength-1

注:

●数据的第一位标志整数部分长度

●整数部分长度+小数部分长度=数据总长度-1

●整数部分从后向前每两位(代表0到100)用一个字节(十六进制)表示,

且为十六进制值-1

●小数部分从后向前每两位(代表0到100)用一个字节(十六进制)表示,

且为十六进制值-1

●如果没有小数部分,Intlength+1〉length(为数字长度),则后面有

(Intlength+1-length)位(只传输位)值为0的数据没有传输

(2)负数

Id 1 3f-整数部分长度整数部分Intlength=3f-id

小数部分DecLength=length-intlength-1

Magic 1 0x66

●数据的第一位标志整数部分长度

●整数部分长度+小数部分长度=数据总长度-2

●整数部分从后向前每两位(代表0到100)用一个字节(十六进制)表示,

且为101-十六进制值

●小数部分从后向前每两位(代表0到100)用一个字节(十六进制)表示,

且为101-十六进制值

●如果没有小数部分,Intlength+2〉length(为数字长度),则后面有

(Intlength+2-length)位(只传输位)值为0的数据没有传输

2.8.2.3 日期格式

Year1 1 Year1-100

Year2 1 Year2-100

Month 1 Month

Day 1 Day

Hour 1 Hour-1

Minute 1 Minute-1

Second 1 Second-1

注:

●Year1为年前两位,值为year1-100

●Year2为年后两位,值为year2-100

●Month为月,值为month

●Day为月,值为Day

●Hour为月,值为Hour-1

●Minute为月,值为Minute-1

●Second为月,值为Second-1

2.8.30x03 0x02 SQL_OPEN

发现当进行0x0303命令查询时

Request id 1

Magic 8

2.8.40x03 0x03 QUERY

该命令也传输一些SQL查询请求,不能确定什么时候使用0x0303命令进行查询,在分析过程中,发现在登陆之后进行一些系统请求用到了该命令。

Request id 1

Magic 12

Data Format 可变查询语句

2.8.50x03 0x04 QUERY SECOND

很少出现这个包,也没具体分析

Request id 1

2.8.60x03 0x05 FETCH MORE

用户查询是通过0x035e命令来请求数据的返回的结果不能一次传输完成,客户端会不断发送该命令向服务器请求数据,直到服务器告诉客户端数据传送完成。

Request id 1

Magic 8

2.8.70x03 0x08 HANDSHAKE7

Request id 1

Magic 4

2.8.80x03 0x09 DISCONNECT

当客户端断开连接时,客户端发送请求到服务器(用0x0309),服务器发送0x0901确认。

Request id 1

2.8.90x03 0x3B DB VERSION

请求ORACLE数据库版本信息,通过0x089c返回结果。

Request id 1

Magic 16

2.8.100x03 0x47 FETCH

Request id 1

2.8.110x03 0x51 Set password

当用户使用GRANT更改密码时,客户先通过0x0352发送用户信息,然后通过0x0351发送密码信息。

Request id 1

Magic1 4

User name length 1 用户名长度

Magic2 99

Username User

name

length

Session key 32

Host info 可变

2.8.120x03 0x52 Set user

当用户使用GRANT更改密码时,客户先通过0x0352发送用户信息,然后通过0x0351发送密码信息。

Request id 1

Magic1 4

User name length 1 用户名长度

Magic2 99

Username User

name

length

Host info 可变

2.8.130x03 0x5E SQL

一般的SQL查询语句是封装在0x035e命令结构中,用该命令请求数据时,服务器

返回数据和确认命令数据。

●如果查询命令错误,则返回错误代码和错误消息。

●如果查询正常,服务器返回执行结果数据和确认命令。

它的结构如下:

Request id 1

Magic1 80 返回列数

Data Format 可变SQL查询语句

Magic3 48 总是为0x07

2.8.140x03 0x73 AUTH2

用户登录过程发送用户密码和用户信息,包括用户名,终端名称,客户端程序,机器,客户端进程号。

2.8.150x03 0x76 AUTH1

用户登录过程发送用户相关信息,包括用户名,会话密钥,终端名称,客户端程序,机器,客户端进程号和对服务器一些设置(语言,时区等)。

2.8.160x03 0x77 desc table

当用户通过DESC TABLE tablename命令查询用户表属性信息时,客户端发送0x0377命令到ORACLE服务器。

Request id 1

Magic1 4 返回列数

Table name length 1 表名长度

Magic2 16

Data Format 可变SQL查询语句

2.8.170x04 0x01 ACK

各种数据库操作会通过0x04命令来返回结果,如是否正常运行,影响行数,影响的表格,操作类型等,如果错误还要返回错误消息,以下0x0402,0x0405均为数据库查询

返回,但是还不知道什么情况适用这三种应答。

数据应答报结构如下:

Magic1 4

Record num 4 记录数,该操作影响记录数

Error num 2 返回错误代码

Magic2 8

Type 1 操作类型(如select,insert,create等)

Magic3 2

Obj Id 2 操作对象ID,如表的对象ID

Magic4 19

Ack id 1 确认号(为该请求号+1)

Magic5 46

Msg length 1 消息长度

Msg Msg

消息

length

2.8.180x04 0x02 ACK

同0x0401

2.8.190x04 0x05 ACK

同0x0401

2.8.200x06 0x00 行结果信息

如果0x06 01命令传送数据未完成则后续数据用0x06 00命令传输,且每行只传输和前一行不同的列。

行结果数据结构信息

Magic1 2

Column Num 2 返回列数

Magic2 23

Column distributing 可变等于[Column Num/8]

Magic3 1 总是为0x07

Row Data 可变

Row Split 可变

Row Data 可变

Row Split 可变

………

Row Data 可变

行数据(Row Data)结构信息

Data Format 可变列数据

Data Format 可变列数据

………

Data Format 可变列数据

注:

●对于第一行列数为Column Num

●非第一行,每行列数和列分布信息根据行分隔结构获取

行分隔结构信息

Id 1 总是0x15

Column Num 2 返回列数

Column distributing 可变等于[Column Num/8]

Magic3 1 总是为0x07

注:

●Column distributing 为该行列分布信息,如果第i列不为空,则Column

distributing的第I bit为1

2.8.210x06 0x01开始行结果信息

SQL查询语句返回结果主要包括字段信息和数据,其中字段数据用0x1019传输,数据有0x0601和0x0600传输。

对于0x0601命令只返回开始几行数据(一般为一行),第一行显示所有的列,以后每行传输和前一行不同的列,即如果和前一行数据相同,则不传送数据,如果多行的某一列都相同,则只传送最开始一行的该列数据。

Magic1 2

Column Num 2 返回列数

Magic2 23

Column distributing 1 总是为0x00

Magic3 1 总是为0x07

2.8.220x08 0x01

经分析发现验证密钥、查询表的结构、0x033b、0x0302命令返回结果用命令0x0801,不过其格式非常不规则,很难分析。

2.8.230x08 0x05

当用户查询请求时,有时返回结果之后会出现这个命令,具体怎么使用还不是很清楚。

Magic1 23

Value Num 2 返回列数

Data Format 数据

Data Format 数据

………

Data Format 数据

2.8.240x08 0x08

当用户发送密钥成功后服务器返回响应的一些消息,如会话密钥,主机名,程序等。

Magic 1

Data length 4

Data Format 可变数据

Data length 4

Data Format 可变数据

………

Data length 4

Data Format 可变数据

注:

如果data length 为0 则后面数据为

2.8.250x08 0x20 Session Key

当当前用户使用grant命令更改当前用户密码之后,系统需要重新发送用户名(0x0352)和密码(0x0351),并更新会话密钥。

Magic 1

Session key 32 会话密钥

2.8.260x08 0x9c Db version

当用户请求数据库版本信息(0x033b)时通过本命令返回版本信息。

Magic 1

Data Format 可变数据库版本信息

Data Format 可变数据库版本信息

Data Format 可变数据库版本信息

2.8.270x09 0x01

当ORACLE服务器收到用户关闭连接的消息时通过本命令确认关闭操作,然后断开TCP/IP连接。

Magic1 1 总是0

Magic2 2

2.8.280x10 0x19 Field Info

SQL查询语句如果有数据返回(如SELECT语句),则先返回各字段信息,然后在返回数据信息。

字段信息结构:

Magic1 29

Field num 2 字段个数

Magic2 3

Field Info 可变字段信息

Field Info 可变字段信息

………

Field Info 可变字段信息

Magic3 12 07 00 00 00 07 78 6a

05 1a 0f 0b 0c

注:字段信息个数为field num

单个字段信息结构:

Magic1 1

Type 1 字段类型

Magic2 1

Precision 1

Scale 1

Magic3 20

Charsetid 2

Charsetform 2

Spare3 2

Magic4 2

Is null 1

length 1

length 4

Data Format 可变

2.8.290x11 0x69

当用户查询数据时,即使用0x035e命令时通常会先发送0x1178和0x1169命令。

Request id 1

Magic 12

2.8.300x11 0x6b

Request id 1

Magic 12

2.8.31 0x11 0x78

当用户查询数据时,即使用0x035e 命令时通常会先发送0x1178和0x1169命令。

Request id 1 Magic

12

3 典型的使用序列

3.1 数据库登陆

3.2 数据结构内部命令序列

请求

操作 响应 序列 请求包

响应包

说明

Select

无记录 1 0x1169+0x035e 0x1019+0x06010 +x0401

errcode=1403

Select

1条记录

1

0x1169+0x035e

0x1019+0x0601 +0805+0x0401 errcode=0 2

0x3e

0x0600+0x0401 (errcode=1403) Select

多条记录

1

0x1169+0x035e 0x1019+0x0601 +0805+0x0402 errcode=0 2 0x3e 0x0600+0x0401 (errcode=1403) 3

0x0305 0x0600+0x0401 Insert 正确 1 0x1169+0x035e 0x0805+0x0402

Insert

错误

1

0x1169+0x035e Mark

请求操作

响应 序列 请求包 响应包 说明 正常连接 无记录 1 连接包 重定向包 正常连接

2 连接包 接受包

不正常连接 无记录

1

连接包

拒绝包

不正常连接

Oracle中分析函数用法小结

Oracle中分析函数用法小结 一.分析函数适用场景: ○1需要对同样的数据进行不同级别的聚合操作 ○2需要在表内将多条数据和同一条数据进行多次的比较 ○3需要在排序完的结果集上进行额外的过滤操作 二.分析函数语法: FUNCTION_NAME(,...) OVER () 例: sum(sal) over (partition by deptno order by ename) new_alias sum就是函数名 (sal)是分析函数的参数,每个函数有0~3个参数,参数可以是表达式,例如:sum(sal+comm) over 是一个关键字,用于标识分析函数,否则查询分析器不能区别sum()聚集函数和sum()分析函数 partition by deptno 是可选的分区子句,如果不存在任何分区子句,则全部的结果集可看作一个单一的大区 order by ename 是可选的order by 子句,有些函数需要它,有些则不需要.依靠已排序数据的那些函数,如:用于访问结果集中前一行和后一行的LAG和LEAD,必须使用,其它函数,如AVG,则不需要.在使用了任何排序的开窗函数时,该子句是强制性的,它指定了在计算分析函数时一组内的数据是如何排序的. 1)FUNCTION子句 ORACLE提供了26个分析函数,按功能分5类 分析函数分类 等级(ranking)函数:用于寻找前N种查询 开窗(windowing)函数:用于计算不同的累计,如SUM,COUNT,AVG,MIN,MAX等,作用于数据的一个窗口上 例: sum(t.sal) over (order by t.deptno,t.ename) running_total, sum(t.sal) over (partition by t.deptno order by t.ename) department_total 制表(reporting)函数:与开窗函数同名,作用于一个分区或一组上的所有列 例: sum(t.sal) over () running_total2, sum(t.sal) over (partition by t.deptno) department_total2 制表函数与开窗函数的关键不同之处在于OVER语句上缺少一个ORDER BY子句! LAG,LEAD函数:这类函数允许在结果集中向前或向后检索值,为了避免数据的自连接,它们是非常有用的. VAR_POP,VAR_SAMP,STDEV_POPE及线性的衰减函数:计算任何未排序分区的统计值 2)PARTITION子句 按照表达式分区(就是分组),如果省略了分区子句,则全部的结果集被看作是一个单一的组 3)ORDER BY子句

oracle数据库笔记001

如果出现协议器出错,我们就用这样的命令: 先用exit跳出sqlplus,再用net start(stop) oracleserviceORCL, 我们在启动oracleserviceORCL 分配的空间我们称之为实例服务,监听服务的启动:命令LSNRCTL START Oracle服务器:oracle实例(内存sid)oracle数据库(物理数据库)多个实例对应一个数据库:ops 和ras(多个sga) 一个实例对应一个数据库:单点数据库(通常情况) 一个实例只能访问一个数据库 Oracle的 Show parameter instance name 查询实例服务 Show parameter db_name 查询查询数据库名字 Select name from v$database 查询数据库名字 Show sga 查询sga 大小 Desc v$tablespace 查询表空间 Spool D:/oracel317.txt 指定文件存放位置执行完之后就要执行spool off Spool off 输出结束 Oracle数据库存储的结构 数据库逻辑结构:实例

数据库物理存储结构:数据文件(data file)控制文件(control file)日志文件(log file)归档文件() 查询数据文件:select name,bytes from v$datafile; 启动一个数据库步骤: (1)申请一个实例 (2)读取控制文件 (3)根据控制文件提供的信息找,关联物理数据库,就能连接数据库 查询各类数据文件夹desc v$datafile ; 数据的操作: 一个表(tablespace)有多个Segment 数据段 一个段(Segment)有多个区(extent) 一个区(extent)有多个块(data block) 数据块(data block)是有多个系统块组成(OS block) 单个表对应单个数据文件 查询select file_name,tablespace 创建表空间:create tablespace testtp datafile ‘d:/testtp01.dbf’size 1m autoextend on next 1m maxsize 10m; 但表空间已存在的时候,会报表空间已存在我们需要增加一个 Alter tablespace testtp add datafile ‘h:/testtp02.dbf’size 10m

Oracle 分析函数(Analytic Functions) 说明

Oracle 分析函数(Analytic Functions)说明一. Analytic Functions 说明 分析函数是oracle 8中引入的一个概念,为我们分析数据提供了一种简单高效的处理方式. 官方对分析函数的说明如下: Analytic functions compute an aggregate value based on a group of rows. They differ from aggregate functions in that they return multiple rows for each group. The groupof rows is called a window and is defined bythe analytic_clause. For each row, a sliding window of rows is defined.The window determines the range of rows used to perform the calculations forthe current row. Window sizes can be based on either a physical number of rowsor a logical interval such as time. Analytic functions are the last set of operations performed in a query except for thefinal ORDER BY clause. All joins and all WHERE, GROUP BY,and HAVING clauses are completed before the analytic functions areprocessed. Therefore, analytic functions can appear only in the select listor ORDER BY clause. Analytic functions are commonly used to compute cumulative, moving, centered, andreporting aggregates. From:Analytic Functions https://www.360docs.net/doc/c918400586.html,/cd/E11882_01/server.112/e26088/functions004.htm#S QLRF06174 分析函数是对一组查询结果进行运算,然后获得结果,从这个意义上,分析函数非常类似于聚合函数(Aggregate Function)。区别是在调用分析函数时,后面加上了开窗子句over()。 聚合函数是对一个查询结果中的每个分组进行运算,并且对每个分组产生一个运算结果。分析函数也是对一个查询结果中的每个分组进行运算,但每个分组对应的结果可以有多个。产生这个不同的原因是分析函数中有一个窗口的概念,一个窗口对应于一个分组中的若干行,分析函数每次对一个窗口进行运算。运算时窗口在查询结果或分组中从顶到底移动,对每一行数据生成一个窗口。 Oracle 聚合函数(Aggregate Functions)说明 https://www.360docs.net/doc/c918400586.html,/tianlesoftware/article/details/7057249

(Oracle数据库管理)玩转实战教程学习笔记最全版

(O管理)玩转实战教程(韩顺平)学习笔记

韩顺平—玩转oracle视频教程笔记 一:Oracle认证,与其它数据库比较,安装 oracle的卸载 1.停止所有与ORACLE相关的服务。 2. 使用OUI(Oracle Universal Installer)卸载Oracle软件。 “开始”->“程序”->“Oracle-OraDb110g_home1|Oracle installation product|Universal installer. 3.删除注册表内容。运行regedit命令,删除下面内容:HKEY_LOCAL_MACHINE|SOFTWARE|ORACLE注册表键,删除此键。 HKEY_LOCAL_MACHINE|SYSTEM|CurrentControlSet|Services,删除Services键下所有以oracle为首的键。 HKEY_LOCAL_MACHINE|SYSTEM|CurrentControlSet|Services|Eventlog|Application,删除此键下所有以oracle为首的键。 HKEY_CLASSES_ROOT,删除此键下所有以Ora,Oracle,Orcl,EnumOra 为前缀的键。 HKEY_CURRENT_USER|Software| Microsoft|Windows|CurrentVersion|Explorer|MenuOrder|Start Menu|Programs,删除此键下所有以oracle为首的键。 HKEY_LOCAL_MACHINE|SOFTWARE|ODBC|ODBCINST.INI注册表键,删除了

ORACLE排序与分析函数

--已知:两种排名方式(分区和不分区):使用和不使用partition --两种计算方式(连续,不连续),对应函数:dense_rank,rank 语法: rank()over(order by排序字段顺序) rank()over(partition by分组字段order by排序字段顺序) 1.顺序:asc|desc名次与业务相关: 示例:找求优秀学员:成绩:降序迟到次数:升序 2.分区字段:根据什么字段进行分区。 问题:分区与分组有什么区别? ·分区只是将原始数据进行名次排列(记录数不变), ·分组是对原始数据进行聚合统计(记录数变少,每组返回一条),注意:聚合。rank()与dense_rank():非连续排名与连续排名(都是简单排名) ·查询原始数据:学号,姓名,科目名,成绩 select*from t_score; S_ID S_NAME SUB_NAME SCORE 1张三语文80.00 2李四数学80.00 1张三数学0.00 2李四语文50.00 3张三丰语文10.00 3张三丰数学 3张三丰体育120.00 4杨过JAVA90.00 5mike c++80.00 3张三丰Oracle0.00 4杨过Oracle77.00 2李四Oracle77.00 ·查询各学生科目为Oracle排名(简单排名) select sc.s_id,sc.s_name,sub_name,sc.score,rank()over(order by score desc)名次from t_score sc where sub_name='Oracle'; S_ID S_NAME SUB_NAME SCORE名次 4杨过Oracle77.001 2李四Oracle77.001 3张三丰Oracle0.003 ·对比:rank()与dense_rank():非连续排名与连续排名(都是简单排名) S_ID S_NAME SUB_NAME SCORE名次

ORACLE笔记

1.Oracle 工具:sqlplus Sqlplus / as sysdba Shutdown immediate(关闭数据库) Startup(启动数据库) 注意:数据库开启才可以进行操作 Select username,account_status from dba_users;(查询数据库中所有的用户名称与用户状态) Alter user scott identified by tiger account unlock;(scott用户解锁) Sqlplus scott/tiger(使用SCOTT 密码为tiger登陆ORACLE数据库) Connect scott/tiger (在SQL>中直接使用SCOTT用户连接数据库) Show all;(看所有变量) Set sqlprompt “_user>”(设置sqlplus环境下面的提示符用自身用户显示) 注意:如要变量下次重启生效必须把变量写入 /u01/app/oracle/product/10.2.0/db_1/sqlplus/admin/glogin.sql中 Host(回到系统) Help index(查看所有命令) Help+命令(类似于LINUX中的MAN,查看命令的格式与用法) Disconnect(关闭SQLPLUS工具但是不离开数据库) Describe emp(查看EMP表) Define(定义变量,常用与写脚本用) 如:DEFINE _EDITOR =”vi” (CHAR) (定义VI编辑器用于保存最后一条执行的SQL语句) Save /u01/app/oracle/aa.sql (保存SQL语句) Get /u01/app/oracle/aa.sql (调用保存的SQL语句) 2.select(select 查询语句是ORACLE中最常用的语句) DML语句包括(insert 写入,update改变,delect删除,merge两张表同步) 注意:merge常用在ETL(数据仓库)底下 DDL数据定义语句包括(create创建对象,alter修改,drop删除对象,rename改名,truncate 删除整个表) TCL事务处理语句(commit提交立刻生效,rollback回滚,savepoint保存点,savepoint(保存点) DCL权限语句(grant赋予权限,revoke(收回权限) ORACLE的表称之为堆表(keep table) SELECT (1) writing basic SQL select statemanes 1. selecting all columns SCOTT>select * from dept; SCOTT>select dname,deptno,loc from dept; Basic SELECT Statement SELECT *|{[DISTINCT] column|expression [alias],...} FROM table;

Oracle分析函数sum over介绍

分析函数sum over() 介绍 报送单位:审核人: 类型:业务应用 关键字:分析函数 1、引言 运维中,常常需要通过SQL语句对单行数据进行查询,同时又需要对结果集进行汇总,通常的方法是通过两个SQL语句分别进行查询汇总,这样效率低下。 2、现象描述 本节介绍一种ORACLE提供的全新的函数sum over(),该类函数称为分析函数,这类函数功能强大,可以通过一个SQL语句对数据进行遍历的同时又进行汇总,而且一张表只进行一次扫描,极大地提高SQL的执行效率。 3、处理过程 语法: FUNCTION_NAME(,,...) OVER() NAME:可以是SUM,AVG,MAX,MIN,COUNT等其它,这些函数单独使用称为聚集函数,与OVER子句一起使用使称为分析函数。在当分析函数使用时,SQL语句中不需要使用GROUP BY子句。

执行计划: 下图说明分析函数只对表进行一次扫描 4、举例说明 下面分别举例来说明分析函数的使用,原始数据如下表

示例1:查询单行数据同时对所有数据工资进行汇总求和 示例2:查询所有数据,同时对第各部门工资进行汇总,汇总范围取值为第一行所在部门至当前部门所有数据。

示例3:查询所有数据,并且每一行汇总值按ENAME排序后取第一行至当前行ENAME所在行。 示例4:查询所有数据,并且每一行汇总值按EMPNO排序后取第一行至当前行EMPNO所在行

示例5:查询所有数据,同时每行对各部门分别进行按EMPNO排序后从各组第一行至当前行汇总求和。 示例6:查询所有数据,同时每行对从当前上两行数据范围的工资进行汇总求和。 示例7:查询所有数据,同时每行对从当前向前一行数据向后两行数据范围的工资进行汇总求和。

oracle学习笔记

●PLSQL控制台输出语句 SET serveroutput ON; --打开控制台输出服务 dbms_output.put_line('values2='||var_val); --输出语句 ●PLSQL动态变量 var_str := '&input'; ●创建表空间和用户 --创建表空间 CREATE TABLESPACE "BCPBS" LOGGING DATAFILE 'D:\app\E430\oradata\orcl\BCPBS_01.ora' SIZE 2048M AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED, 'D:\app\E430\oradata\orcl\BCPBS_02.ora' SIZE 2048M AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO ; --建立用户 CREATE USER "BCPBS" PROFILE "DEFAULT" IDENTIFIED BY "bcpbs123" DEFAULT TABLESPACE "BCPBS" TEMPORARY TABLESPACE "TEMP" ACCOUNT UNLOCK; GRANT "CONNECT" TO "BCPBS"; GRANT "DBA" TO "BCPBS"; GRANT "RESOURCE" TO "BCPBS"; ●删除表空间和用户 drop user bcpbs cascade ; drop tablespace BCPBS including contents and datafiles cascade constraints ; ●自定义函数 CREATE OR REPLACE FUNCTION fun_level_value(level_value number) RETURN number IS return_value number:=null; BEGIN CASE level_value WHEN 0 THEN return_value:='0'; WHEN 1 THEN return_value:='1'; WHEN 2 THEN return_value:='2'; WHEN 3 THEN return_value:='3'; WHEN 6 THEN return_value:='8'; ELSE

Oracle学习笔记

Oracle的四个主要用户 1.超级管理员sys/change_on_install 2.普通管理员system/manager 3.普通用户scott/tiger 4.大数据用户sh/sh 简单查询 1.查询表结构 DESC 表名 2.简单查询SELECT [DISTINCT] *|[字段 [别名]] [,字段 [别名]] … FROM 表名 [别名] (1)查询时也可以使用四则运算,如:SELECT (字段*x)+y FROM 表名 (2)可以使用“||”连接字段与字符串,如: select '工作与工资:' || job || sal 工作工资 from emp 执行结果: 3.限定查询SELECT [DISTINCT] *|[字段 [别名]] [,字段 [别名]] … FROM 表名 [别名] [WHERE 条件(s)] (1)Where字句后可以增加多个条件,最常见的条件就是最基本关系运算:>、<、>=、<=、!=(<>)、BE TWEEN…AND、LIKE、IN(指定范围)、IS NULL(为空)、AND(且)、OR(或)、NOT(非)。 (2)多个条件可以使用AND与OR连接。 例如:select * from emp where sal>1300 and sal<4000 (3)范围判断BE TWEEN…AND:BETWEEN 最小值 AND 最大值(大于等于最小值,小于等于最大值),BE TWEEN…AND 对数字、日期都可以使用!!! 例如:select * from emp where sal between 1300 and 4000 例如:select * from emp where hiredate between '01-1月-1981' and '31-12月-1981' (4)判断为空IS (NOT) NULL 例如:select * from emp where comm is null 例如:select * from emp where comm is not null 例如:select * from emp where not comm is null (5)指定范围的判断(NOT) IN 例如:select * from emp where empno in(7369,7566,7799)

Oracle分析函数

Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是 对于每个组返回多行,而聚合函数对于每个组只返回一行。 一、开窗函数 开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化。 例如: 1)over(order by salary)按照salary排序进行累计,order by是个默认的开窗函数 2)over(partition by department_id)按照部门分区 3)over(order by salary range between 50 preceding and 150 following) 每行对应的数据窗口是之前行幅度值不超过50,之后行幅度值不超过150 4)over(order by salary rows between 50 preceding and 150 following) 每行对应的数据窗口是之前50行,之后150行 5)over(order by salary rows between unbounded preceding and unbounded following) 每行对应的数据窗口是从第一行到最后一行,等效: 6) over(order by salary range between unbounded preceding and unbounded following) 其中: 第一行是unbounded preceding 当前行是current row 最后一行是unbounded following 二、分析函数的概念 分析函数是在整个SQL查询结束后(SQL语句中的ORDER BY的执行比较特殊)再进行的操作, 也就是说 SQL语句中的ORDER BY也会影响分析函数的执行结果。 分析函数中包含三个分析子句:分组(Partition By), 排序(Order By), 窗口(Window) 当省略窗口子句时: 1) 如果存在Order By则默认的窗口是unbounded preceding and current row 2) 如果同时省略Order By则默认的窗口是unbounded preceding and unbounded following 如果省略分组,则把全部记录当成一个组 a) 如果SQL语句中的Order By满足分析函数分析时要求的排序,那么SQL语句中的排序将先执行,分析 函数分析时就不必再排序 b) 如果SQL语句中的Order By不满足分析函数分析时要求的排序,那么SQL语句中的排序将最后在分 析函数分析结束后执行排序 三、分析函数 1)AVG

Oracle数据库学习笔记

Oracle数据库学习笔记 作者:高达 第一天: DBMS--数据库管理系统: Date base Manage System 数据模型: (1)层次模型类似于“倒树”型的结构 (2)网状模型 (3)关系模型RDBMS--Relation Date base System 记录和记录之间通过属性之间的关系来进行连接,保证数据独立性,并形成数据集之间的关系。 主键:关键词--PRIMARY KEY 用于行的区分,不会重复。主键可以由两列组成,叫做组合键。主键非空。如果为空则失去实体完整性。 外键:关键词--FOREIGN KEY 外键表示两个表之间的相关联系。外键的范围不能超过主键的范围,如果超过则失去引用完整性。 完整性: 是为保证数据库中数据的正确性和一致性。 (1).实体完整性: 数据行不能存在重复,也不能为空。即PK不重复不为空。

(2).引用完整性: 指建立两个关系建立联系的主外键的约束 1.要求子表中的相关项必须在主表中存在。 2.如果建立了主表和子表的关系,则:a.子表中的相关项目的数据,在主表中必须存在;b.主表中相关项的数据更改了,则子表对应的数据项也应当随之更改;c.在删除子表之前,不能够删除主表。 (3).域完整性: 保证表中数据的合理性 check 检查 default 默认 not null 不为空 unique 唯一约束 (4).自定义完整性: 根据用户需要自己定义。除了上述关键字,可以使用触发器来编写约束。 约束:关键词--CONSTRAINT 在创建表的时候添加约束。 目的: 确保表中数据的完整型 常用约束类型: 主键约束(Primary Key Constraint):要求主键列数据唯一,并且不允许为空。 唯一约束(Unique Constraint):要求该列唯一,允许为空,但只能出现一个空值。 检查约束(Check Constraint):某列取值范围限制、格式限制等,如有关年龄的约束。 默认约束(Default Constraint):某列的默认值,如我们的男性学员较多,性别默认为“男”。外键约束(Foreign Key Constraint):用于两表间建立关系,需要指定引用主表的哪列。 不为空(not null):不可以为空。

Oracle自定义聚合函数-分析函数

自定义聚合函数,分析函数 --from GTA Aaron 最近做一数据项目要用到连乘的功能,而Oracle数据库里没有这样的预定义聚合函数,当然利用数据库已有的函数进行数学运算也可以达到这个功能,如: selectexp(sum(ln(field_name))) from table_name; 不过今天的重点不是讲这个数学公式,而是如何自己创建聚合函数,实现自己想要的功能。很幸运Oracle 允许用户自定义聚合函数,提供了相关接口,LZ研究了下,留贴共享。 首先介绍聚合函数接口: 用户可以通过实现Oracle的Extensibility Framework中的ODCIAggregate interface 来创建自定义聚合函数,而且自定义的聚合函数跟内建的聚合函数用法上没有差别。 通过实现ODCIAggregaterountines来创建自定义的聚合函数。可以通过定义一个对象类型(Object Type),然后在这个类型内部实现ODCIAggregate 接口函数(routines),可以用任何一种Oracle支持的语言来实现这些接口函数,比如C/C++, JAVA, PL/SQL等。在这个Object Type定义之后,相应的接口函数也都在该Object Type Body内部实现之后,就可以通过CREATE FUNCTION语句来创建自定义的聚合函数了。 每个自定义的聚合函数需要实现4个ODCIAggregate 接口函数,这些函数定义了任何一个聚合函数内部需要实现的操作: 1. 自定义聚合函数初始化操作,从这儿开始一个聚合函数。初始化的聚合环境(aggregation context)会以对象实例(object type instance)传回给oracle. static function ODCIAggregateInitialize(varIN OUTagg_type ) return number 2. 自定义聚合函数,最主要的步骤,这个函数定义我们的聚合函数具体做什么操作,self 为 当前聚合函数的指针,用来与前面的计算结果进行关联。这个函数用来遍历需要处理的

oracle-database-11g-plsql-编程实战笔记

Chap1 DML语句是select 、insert、update、delete和merge DDL语句是create、alter、drop、rename、truncate、comment DCL语句是grant、revoke TCL语句是commit、rollback和savepoint sql16个基本命令——参考书《OCA认证考试指南(IZ0-051)》清华大学出版社 《oracle database sql language reference 11g》有非遵循格式字符串依赖于格式掩码 chap2 2.1.3 关于语句中有多个单引号时处理: 1、 select'It''s a bird,no plan can''t be 'as pharse from dual; 此处两个单引号即为一个单引号 2、只能用q 再加’(语句)’ select q'(It's a bird,no plan can't be)'as pharse from dual; 均输出 PHARSE ---------------------------- It's a bird,no plan can't be 2.1.4 定义变量与申明变量的区别: 定义变量即为变量分配名称并指定数据类型;申明变量首先需要定义变量,然后为其赋值。(赋值也称为初始化) 替代变量前面要加&前缀且若替代变量为字符型时要加两个单引号如’&a’ declare lv_whom varchar2(20);/*lv-whom为申明变量,a为替代变量,a没有变量类型*/ begin lv_whom := '&a'; end; 或者 declare lv_whom varchar2(20); begin lv_whom := &a; end;但是要在输入框中字符加两个单引号 替代变量用define申明,且定义时不可以指定类型,默认为char型 ①Define x=emp; Select * from &x; /*调用要用&,此处不加单引号,解析后即为emp表*/

oracle数据库学习笔记心得

select* |字段表名 from 表名 where 布尔表达式【条件】 externalcandidate 职员相关信息 contractrecruiter 猎头公司 查看表里所有字段 describe[描述] contractrecruiter select cname,nperecentagecharge from contractrecruiter 不显示原来名字,显示现在名字【用AS】 select cname as "Recruiter Name",nperecentagecharge as "Hire Fees" from contractrecruiter 不显示原来名字,显示现在名字【可不用AS】 select cname "Recruiter Name",nperecentagecharge "Hire Fees" from contractrecruiter 【双引号是否写】 双引号是为了区分大小写 职位表 position select *from position 缺额运算:[想减] select VDESCRIPTION , nbudgetedstrength, NBUDGETEDSTRENGTH -NCURRENTSTRENGTH , NYEAR from position

select VDESCRIPTION "Potion", nbudgetedstrength "Budgeted Strength" , NBUDGETEDSTRENGTH -NCURRENTSTRENGTH "Vacancies", NYEAR "Year" from position 显示非重复运行 查询来源地的人数 describe externalcandidate 查看职员城市名字 select ccity from externalcandidate 查看职员城市名字【名字不重复,插入一个关键字:distinct】select distinct ccity,cstate from externalcandidate 运算符: 两列 select vfirstname,vlastname from externalcandidate 字段拼接 select vfirstname||vlastname from externalcandidate select vfirstname||' '||vlastname from externalcandidate 学校 describe college 查看所有学校 select *from college 查看只是加利福尼亚的学校 select * from college where cstate='California' 一个条件 select vfirstname,vlastname,dbirthdate,ntestscore from externalcandidate where dbirthdate>='01-1月-70'

oracle高级分析函数使用实例

oracle高级分析函数使用实例 2014年11月26日10:26:55 ?标签: ?oracle ?1744 ORACLE的分析函数,发现大家写SQL的时候有些功能写的比较麻烦或者不知道复杂的功能怎么通过SQL实现,ORACLE自带的分析函数有很多相应的功能: 它是Oracle分析函数专门针对类似于"经营总额"、"找出一组中的百分之多少" 或"计算排名前几位"等问题设计的。 分析函数运行效率高,使用方便。 分析函数是基于一组行来计算的。这不同于聚集函数且广泛应用于OLAP环境中。 Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是 对于每个组返回多行,而聚合函数对于每个组只返回一行。 语法: (,,...) over( ) 其中: 1 over是关键字,用于标识分析函数。 2 是指定的分析函数的名字。Oracle分析函数很多。 3 为参数,分析函数可以选取0-3个参数。 4 分区子句的格式为: partition by[,value_expr]... 关键字partition by子句根据由分区表达式的条件逻辑地将单个结果集分成N

组。这里的"分区partition"和"组group" 都是同义词。 5 排序子句order-by-clause指定数据是如何存在分区内的。其格式为:order[siblings]by{expr|position|c_alias}[asc|desc][nulls first|nulls last] 其中: (1)asc|desc:指定了排列顺序。 (2)nulls first|nulls last:指定了包含空值的返回行应出现在有序序列中的第一个或最后一个位置。 6窗口子句windowing-clause 给出一个固定的或变化的数据窗口方法,分析函数将对这些数据进行操作。在一组基于任意变化或固定的窗口中, 可用该子句让分析函数计算出它的值。 格式: {rows|range} {between {unbounded preceding|current row |{preceding|following} }and {unbounded preceding|current row |{preceding|following} }|{unbounded preceding|current row |{preceding|following }} (1)rows|range:此关键字定义了一个window。 (2)between...and...:为窗品指一个起点和终点。 (3)unbounded preceding:指明窗口是从分区(partition)的第一行开始。 (4)current row:指明窗口是从当前行开始。 create table emp( deptno varchar2(20),--部门编码 ename varchar2(20),--人名 sal number(10));--工资 insert into emp values('10','andy1',2000); insert into emp values('10','andy2',3000); insert into emp values('10','andy3',2000); insert into emp values('20','leno1',4000); insert into emp values('20','leno2',8000);

oracle GoldenGate学习笔记

Oracle GoldenGate测试文档1.Oracle GoldenGate介绍 GoldenGate TDM(交易数据管理)软件是一种基于日志的结构化数据复制软件,它通过解析源数据库在线日志或归档日志获得数据的增删改变化,再将这些变化应用到目标数据库,实现源数据库与目标数据库同步、双活。GoldenGate TDM 软件可以在异构的IT基础结构(包括几乎所有常用操作系统平台和数据库平台)之间实现大量数据亚秒一级的实时复制,其复制过程简图如下: 如上图所示,GoldenGate TDM的数据复制过程如下: 利用捕捉进程(Capture Process)在源系统端读取Online Redo Log或Archive Log,然后进行解析,只提取其中数据的变化如增、删、改操作,并将相关信息转换为GoldenGate TDM自定义的中间格式存放在队列文件中。再利用传送进程将队列文件通过TCP/IP传送到目标系统。捕捉进程在每次读完log中的数据变化并在数据传送到目标系统后,会写检查点,记录当前完成捕捉的log位置,检查点的存在可以使捕捉进程在中止并恢复后可从检查点位置继续复制; 目标系统接受数据变化并缓存到GoldenGate TDM队列当中,队列为一系列临时存储数据变化的文件,等待投递进程读取数据; GoldenGate TDM投递进程从队列中读取数据变化并创建对应的SQL语句,通过数据库的本地接口执行,提交到数据库成功后更新自己的检查点,记录已经完成复制的位置,数据的复制过程最终完成。 由此可见,GoldenGate TDM是一种基于软件的数据复制方式,它从数据库的日志解析数据的变化(数据量只有日志的四分之一左右)。GoldenGate TDM将数据变化转化为自己的格式,直接通过TCP/IP网络传输,无需依赖于数据库自身的传递方式,而且可以通过高达9:1的压缩率对数据进行压缩,可以大大降低带宽需求。在目标端,GoldenGate TDM可以通

Oracle高级查询总结

高级查询总结 A.层次查询:start with……connec by prior…….. select lpad(' ',3*level)||ename,job,level from emp start with mgr is null connect by prior empno=mgr; 从根结点向下查,lpad()为左添加,level为第几层,prior为查找的方向;此句若省掉start with….则表示要遍历整个树型结构;若出现level,则后面一定要跟connect by B.交叉报表(case when then end 与decode()) select ename,case when sal>=1500then sal*1.01 else sal*1.1 end工资 from emp; select姓名, max(case课程when'语文'then分数end) 语文, max(case课程when'数学'then分数end) 数学, max(case课程when'历史'then分数end) 历史 from学生group by姓名;------(交叉报表与函数一起使用) select ename,sum(decode(sal,'sal',comm,null)) 奖金from emp group by ename;--可实现分支 decode(条件,(值),(返回值),…………,(默认值)) 部门 select sal,decode(sign(sal-1500),-1,1.1*sal,0,1.1*sal,1,1.05*sal) from emp; C.连接查询 1.等值: select * from emp,dept where emp.deptno(+)=dept.deptno; ‘+’在左则以右表为主,反之亦然 2.非等值:where的运算符不是等号 3.自然连接: select * from emp natural join dept 4.99乘法: select * from emp e full join dept d using (deptno) where deptno=10; --where必须放在using(on)的后面 D集合查询: 1.A Union B:消除重复行,有all则可以重复,默认第一列升序select ename,sal from deptno=20 union select ename,sal from job=’CLERK’; 2.A intersect B:A与B的交集 select ename,sal from deptno=20 intersect select ename,sal from job=’CLERK’; 3.A minus B:在A中减去既属于A又属于B的一部分

相关文档
最新文档