ORACLE官方SQL语言参考笔记之伪列篇(第二章)

Posted 二次猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORACLE官方SQL语言参考笔记之伪列篇(第二章)相关的知识,希望对你有一定的参考价值。

本文简述

中文名:《SQL语言参考笔记》

英文名:《SQL Language Reference》

时间:阅读于2018年3月21日

注意事项:跳过基本概念和非重要内容,重点举例说明,并且加粗,部分内容可能在其他章节会再次详细介绍,表格如果排版不美观,可以复制到excle进行直观展示,代码部分根据实际情况注释和说明


本文包括如下内容:

2.1 分层(分级)查询伪列

需要注意两点:

(1) 层次查询伪列仅在层次查询中有效

(2)若要在查询中定义层次关系,必须使用CONNECT BY子句

对分层(分级)查询伪列分为三类:
  • 2.1.1 CONNECT_BY_ISCYCLE

  • 2.1.2 CONNECT_BY_ISLEAF

    • 2.1.2.1 举例

  • 2.1.3 LEVEL

2.1.1 CONNECT_BY_ISCYCLE

(1)如果当前行有一个子行,则CONNECT_BY_ISCYCLE伪列返回1,也是它的默认(初始)值。否则返回0

(2)只有在指定了NOCYCLE参数时,才能指定CONNECT_BY_ISCYCLE连接BY子句的。NOCYCLE使Oracle能够返回以下查询的结果否则会失败,因为数据中有CONNECT BY循环。

2.1.2 CONNECT_BY_ISLEAF

如果当前行是末端,则由条件连接定义的CONNECT_BY_ISLEAF伪列返回1,否则,它将返回0。此信息表明是否可以进一步展开给定行以显示更多的层次结构。

2.1.2.1举例
--只限于级别小于或等于3且department_id = 80且LEVEL <= 3范围内的数据
--从按employee_id = 100的数据行开始,employee_id = manager_id且LEVEL <= 4进行分层查询
--执行SQL后,不难看出LEVEL=3是最末端,所以connect_by_isleaf返回1,而LEVEL<3的connect_by_isleaf返回的则是0SELECT last_name "Employee",
   connect_by_isleaf "IsLeaf",
   LEVEL,
   sys_connect_by_path(last_name, '/') "Path"
  FROM employees
 WHERE LEVEL <= 3
   AND department_id = 80
 START WITH employee_id = 100CONNECT BY PRIOR employee_id = manager_id   AND LEVEL <= 4
 ORDER BY "Employee", "IsLeaf";
2.1.3 LEVEL

对于分层查询返回的每一行,级别LEVEL列返回1根行,2为子根,以此类推。根行是倒置树。子行是任何非根行。父行是具有子行。子行是指没有子的任何一行


倒置树及其水平值

2.2 序列伪列

序列是可以生成唯一顺序值的架构对象。这些值通常用于主键和唯一约束
一个序列可以被许多用户并发访问,而不需要等待或锁定

对序列伪列分为四个部分说明
  • 2.2.1 分类

  • 2.2.2 使用情况(三种使用情况)

  • 2.2.3 使用序列值的位置(跳过,具体细节可以参考书中内容)

  • 2.2.4 如何使用序列值

    • 2.2.4.1 查找Sequen的下一个值

    • 2.2.4.2 将值插入表中

    • 2.2.4.3 重用Sequen的当前值

2.2.1 分类

您可以使用这些伪列引用sql语句中的序列值。

  • CURRVAL:返回序列的当前值

  • NEXTVAL:递增序列并返回下一个值

2.2.2 使用情况(三种使用情况)
  • (1).本地库查询
    您必须用序列的名称限定CURRVAL和NEXTVAL

    • sequence.CURRVAL

    • sequence.NEXTVAL

  • (2).引用另一个用户的序列
    若要引用另一个用户架构中序列的当前或下一个值,必须授予您在序列上选择对象特权或选择任意序列系统特权,您必须用包含它的模式对序列进行限定

    • schema.equence.CURRVAL

    • schema.equence.NEXTVAL

  • (3).远程数据库的访问
    要引用远程数据库上序列的值,必须限定具有数据库链接完整或部分名称的序列

    • schema.equence.CURRVAL@dblink

    • schema.equence.NEXTVAL@dblink

2.2.3 使用序列值的位置(跳过,具体细节可以参考书中内容)
2.2.4 如何使用序列值
对如何使用序列值分为三部分说明:
  • 2.2.4.1 查找Sequen的下一个值

  • 2.2.4.2 将值插入表中

  • 2.2.4.3 重用Sequen的当前值

2.2.4.1 查找Sequen的下一个值
--此示例在示例模式hr中选择员工序列的下一个值。SELECT employees_seq.nextval FROM dual;
2.2.4.2将值插入表中
--此示例将增加Employee序列,并将其值用于插入示例表hr.Employees中的新员工。
INSERT INTO hr.employees
VALUES
  (hr.employees_seq.nextval,   'John',   'Doe',   'jdoe',   '555-1212',
   to_date(SYSDATE),   'PU_CLERK',   2500,   NULL,   NULL,   30);
--查询hr.employees_seq.nextval新增的数据
--本例可以通过first_name 和last_name 查找新增的数据
SELECT *
  FROM hr.employees s
 WHERE s.first_name = 'John'
   AND s.last_name = 'Doe';
2.2.4.3 重用Sequen的当前值
--此示例向主订单表添加具有下一个订单号的新订单。然后,它将具有此数字的子订单添加到详细订单表中。
INSERT INTO oe.orders
  (order_id, order_date, customer_id)
VALUES
  (oe.orders_seq.nextval, to_date(SYSDATE), 106);
INSERT INTO oe.order_items
  (order_id, line_item_id, product_id)
VALUES
  (oe.orders_seq.currval, 1, 2359);--重用Sequen的当前值
INSERT INTO oe.order_items
  (order_id, line_item_id, product_id)
VALUES
  (oe.orders_seq.currval, 2, 3290);--重用Sequen的当前值
INSERT INTO oe.order_items
  (order_id, line_item_id, product_id)
VALUES
  (oe.orders_seq.currval, 3, 2381);--重用Sequen的当前值
--查询oe.orders_seq.currval当前值--本例为1000
SELECT * FROM oe.orders s WHERE s.order_id = 1000;
SELECT * FROM oe.order_items s WHERE s.order_id = 1000;

2.3 版本查询伪列

版本查询伪列仅在Oracle闪回版本查询中有效,该版本查询是Oracle闪回查询的一种形式。

对版本查询伪列分为四类
  • 2.3.1 VERSIONS_STARTSCN和VERSIONS_STARTTIME

  • 2.3.2 VERSIONS_ENDSCN和VERSIONS_ENDTIME

  • 2.3.3 VERSIONS_XID

  • 2.3.4 VERSIONS_OPERATION

2.3.1 VERSIONS_STARTSCN和VERSIONS_STARTTIME
  • 在创建行版本时启动系统更改号(SCN)或TIMESTAMP(时间)戳。

  • 此伪列标识数据首次有值的时间,会记录在行版本中。使用此伪列标识Oracle闪回表或Oracle闪回查询的过去目标时间。如果此伪列为空,那么行版本是在开始之前就创建了。

2.3.2 VERSIONS_ENDSCN和VERSIONS_ENDTIME

当行版本过期时,SCN或TIMESTAMP(时间)戳,如果伪列为空,那么在查询时,行版本要么是当前的,要么行对应于一个删除操作。

2.3.3 VERSIONS_XID

创建行版本的事务的标识符(原始编号)

2.3.4 VERSIONS_OPERATION

事务执行的操作:I插入,D删除,或U更新。版本是已插入、删除或更新的行的版本;即插入操作后的行、删除操作之前的行或受更新操作影响的行。

2.4 COLUMN_VALUE伪列

返回的是一个XML格式的数据

对COLUMN_VALUE伪列分为三个部分说明
  • 2.4.1 XMLTable构造情况使用COLUMN_VALUE伪列

  • 2.4.2 XMLTABLE上下文情况使用COLUMN_VALUE伪列

  • 2.4.3 举例

2.4.1 XMLTable构造情况使用COLUMN_VALUE伪列

当您引用没有列子句的XMLTable构造时,或者当您使用表集合表达式引用标量嵌套表类型时,数据库将返回一个虚拟表一列。此伪列的名称为COLUMN_VALUE。

2.4.2XMLTABLE上下文情况使用COLUMN_VALUE伪列

在XMLTABLE上下文,返回值的数据类型XMLType。
下面两个查询结果是一样的,并对输出结果列值的列的名称

SELECT * FROM xmltable('<a>123</a>');SELECT column_value FROM (xmltable('<a>123</a>'));
2.4.3 举例
CREATE TYPE phone AS TABLE OF NUMBER; 
/
CREATE TYPE phone_list AS TABLE OF phone;
/
--下一条语句使用COLUMN_VALUE从PHONE类型中选择
SELECT t.column_value FROM TABLE(phone(1, 2, 3)) t;
--在嵌套类型中,可以在SELECT列表和表集合表达式中使用COLUMN_VALUE伪列:
SELECT t.column_value FROM TABLE(phone_list(phone(1, 2, 3))) p, TABLE(p.column_value) t;
--关键字COLUMN_VALUE也是ORACLE数据库为没有列或属性名称的嵌套表的标量值生成的名称,
--如下面的示例所示。在它的上下文,COLUMN_VALUE不是伪列,而是一个实际的列名。CREATE TABLE my_customers(cust_id NUMBER, NAME VARCHAR2(25), phone_numbers phone_list, credit_limit NUMBER) NESTED TABLE phone_numbers store AS outer_ntab(NESTED TABLE column_value store AS inner_ntab);INSERT INTO my_customers (cust_id, NAME, phone_numbers, credit_limit)VALUES (1,  'towoapes',  phone_list(phone(1, 2, 3)),  to_number(to_char(SYSDATE, 'yyyymmdd')));
COMMIT;
SELECT * FROM my_customers;

2.5 OBJECT_ID伪列

OBJECT_ID伪列返回对象表或视图的列的对象标识符。ORACLE将此伪列用作对象表的主键。OBJECT_ID在在视图和识别对象表中的一行的ID替代触发器。

注意:在以前的版本中,这个会话被称为 SYS_NC_OID$. 该名称仍然支持向后兼容。然而,ORACLE建议你用更直观的名称OBJECT_ID

2.6 OBJECT_VALUE伪列

OBJECT_VALUE伪值返回对象表、XMLTYPE表、对象视图或XMLTYPE视图的列的系统生成名称。

此伪列用于标识对象表中可替换行的值,并使用WITH OBJECT IDENTIFIER(对象标识)子句创建对象视图。

注意:在早期版本中,这个伪列被称为SYS_NC_ROWINFO$.为了向后兼容性,仍然支持该名称。但是,Oracle建议您使用更直观的名称OBJECT_VALUE

2.7 ORA_ROWSCN伪列

ORA_ROWSCN反映了系统更改号(SCN)最近对一行的更改。此更改可以位于块(粗)或行(细粒度)级别。后者是专业的按行级依赖跟踪

对ORA_ROWSCN伪列分为两个部分说明
  • 2.7.1 使用和限制

  • 2.7.2 举例

2.7.1 使用和限制

(1)你不能在查询视图使用ORA_ROWSCN会话。但是,您可以在创建视图时使用它来引用基础表。还可以在UPDATE或DELETE语句的WHERE子句中使用此伪列。

(2)闪回查询不支持ORA_ROWSCN。相反,使用版本查询伪列,这些伪列是为闪回查询显式提供的。

(3)对ORA_ROWSCN的限制:外部表不支持此伪列。

2.7.2 举例
--下面的第一条语句使用ORA_ROWSCN伪列获取employees表上最后一个操作的系统更改号。
--第二个语句使用带有SCN_TO_TIMESTAMP函数的伪列来确定操作的时间戳。
SELECT ora_rowscn, last_name FROM hr.employees WHERE employee_id = 188;SELECT scn_to_timestamp(ora_rowscn), last_name FROM hr.employees WHERE employee_id = 188;

2.8 ROWID伪列

对ROWID伪列分为四个部分说明
  • 2.8.1 返回值

  • 2.8.2 用途

  • 2.8.3 举例

2.8.1 返回值

通常,rowid值唯一地标识数据库中的一行。但是,存储在同一个集群中的不同表中的行可以具有相同的rowid.

主要返回值如下:

  • 对象的数据对象号。

  • 行所在的数据文件中的数据块。

  • 数据块中该行的位置(第一行为0)

  • 行所在的数据文件(第一个文件为1)。文件号相对于表空间。

2.8.2 用途
  • 访问单行的最快方式

  • 可以告诉你如何在一个表中的行存储

  • 为表中的行的唯一标识符
    不应将ROWID用作表的主键。例如,如果您删除并重新插入带有Import and Export实用程序的行,则其rowid可能会更改。如果删除一行,则Oracle可以将其rowid重新分配到稍后插入的新行

2.8.3 举例
--此语句选择包含在部门20中的雇员的数据的所有行的数据。
SELECT ROWID, last_name FROM hr.employees WHERE department_id = 20;

2.9 ROWNUM伪列

对于查询返回的每一行,ROWNUM伪列返回一个数字,指示Oracle从表或连接行集中选择行的顺序。所选的第一行具有一个ROWNUM为1,第二为2,等等。

对于ROWNUM伪列分为两个部分
  • 2.9.1 举例

  • 2.9.2 注意事项

2.9.1 举例
--可以使用ROWNUM限制查询返回的行数,如本例所示:
SELECT * FROM hr.employees WHERE rownum < 11;
--如果ORDERBY子句在同一个查询中跟随ROWNUM,那么这些行将被ORDERBY子句重新排序。
--根据访问行的方式,结果可能会有所不同。
--例如,如果ORDER BY子句使Oracle使用索引访问数据,
--然后Oracle可能以与不使用索引的顺序检索行的顺序不同。
--因此,以下语句不一定返回与前面示例相同的行:
SELECT * FROM hr.employees WHERE rownum < 11 ORDER BY last_name;
--如果在子查询中嵌入ORDERBY子句并将ROWNUM条件放置在顶级查询中,
--则可以强制在行排序之后应用ROWNUM条件。
--举个例子,下面的查询将返回员工的10个最小员工号。这有时被称为Top-N报告:
SELECT *
  FROM (SELECT * FROM hr.employees ORDER BY employee_id)
 WHERE rownum < 11;
--在前面的示例中,该行号值的顶层SELECT语句,所以他们行之后,已经下令在子查询产生的employee_id。
--条件测试rownum值大于一个正整数都是假的。例如,该查询不返回任何行
SELECT * FROM hr.employees WHERE rownum > 1;
--获取的第一行被分配为1的ROWNUM,并使条件为false。要获取的第二行现在是第一行,
--并且还分配了一个ROWNUM为1,并使条件为false。所有行随后都不能满足条件,因此不返回任何行。
--还可以使用ROWNUM为表的每一行分配唯一值,如本例所示:
UPDATE my_table SET column1 = rownum;
2.9.2 注意事项

1.ROW_NUMBER内置SQL函数为排序查询结果提供了更好的支持

2.在查询中使用ROWNUM会影响视图优化

3.条件查询ROWNUM不能使用大于一个正整数

2.10 XMLDATA伪列

Oracle根据XMLSchema信息和如何指定存储子句,将XMLType数据存储在LOB或对象关系列中。XMLDATA伪列允许您访问基础LOB或对象关系列,用于指定额外的存储子句参数、约束、索引等。

对于XMLDATA伪列的说明部分提供如下举例
--下面的语句说明了这个伪列的用法。假设您使用一个CLOB列创建了一个XMLType的简单表:
CREATE TABLE xml_lob_tab of XMLTYPE
  XMLTYPE STORE AS CLOB;
--若要更改基础LOB列的存储特性,可以使用以下语句:
  ALTER TABLE xml_lob_tab
  MODIFY LOB (XMLDATA) (STORAGE (MAXSIZE 2G) CACHE);
--如下例子需要查看第十九章的"在SQL语句中使用XML"部分
--现在假设您已经创建了一个基于XMLSchema的表,就像在第十九章上“使用XML在SQL语句中”中创建的
--XMLSchema-based 表一样。然后,可以使用XMLDATA列设置基础列的属性,如下所示:
ALTER TABLE xwarehouses
  ADD (UNIQUE(XMLDATA."WarehouseId"));

本文重点内容




简书网址:https://www.jianshu.com/u/4149ca7cf286



让程序猿能共同成长起来

让程序猿传播和共享技术

让程序猿养成做笔记习惯

让程序猿持续的增长知识

让程序猿写代码更加规范

让程序猿职场上学会低调



以上是关于ORACLE官方SQL语言参考笔记之伪列篇(第二章)的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE官方SQL语言参考笔记之Oracle SQL简介篇(第一章)

Oracle中的伪列

从 Dual 中选择时是不是可以指定 Oracle 8i 伪列的数据类型

Oracle数据库学习

sql server,mysql,oracle有啥相通点和语法区别?

oracle 之 伪列 rownum 和 rowid的用法与区别