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

本文简述

此书下载方法:加入群技术交流群(免费)699712384,文件夹为ORACLE官方文档中 
CSDN技术网址 
简书技术网址 
ORACLE官网教程地址 
书名:

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

英文名:《SQL Language Reference》

作者:二次猿

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

准备工作:详情见:具体可以参考简书和二次猿公众号常用表

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

分层查询 Pseudocolumns

分层查询 pseudocolumns 仅在分层查询中有效。分层查询 pseudocolumns 是:

  • CONNECT_BY_ISCYCLE Pseudocolumn

  • CONNECT_BY_ISLEAF Pseudocolumn

  • 级别 Pseudocolumn

    扫描二维码关注公众号,回复: 868110 查看本文章

若要在查询中定义层次结构关系, 必须使用CONNECT BY子句。

CONNECT_BY_ISCYCLE Pseudocolumn

如果当前行的子级也是其祖先, 则CONNECT_BY_ISCYCLE pseudocolumn 返回1。否则它返回0。

只有指定CONNECTby 子句的NOCYCLE参数时, 才能指定CONNECT_BY_ISCYCLE . BYNOCYCLE使 Oracle 能够返回由于数据中循环CONNECTBY导致的查询结果。

CONNECT_BY_ISLEAF Pseudocolumn

如果当前行是由CONNECTBY条件定义的树的叶, 则CONNECT_BY_ISLEAF pseudocolumn 返回1。否则它返回0。此信息指示是否可以进一步扩展给定行以显示更多层次结构。

CONNECT_BY_ISLEAF 示例下面的示例显示hr.employees表的前三个级别, 指示每行是否为叶行 (在IsLeaf列中指示为 1), 或是否具有子行 ( IsLeaf列中指示 0):

SELECT 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 = 100
  CONNECT BY PRIOR employee_id = manager_id AND LEVEL <= 4
  ORDER BY "Employee", "IsLeaf";

Employee                      IsLeaf      LEVEL Path
------------------------- ---------- ---------- -------------------------
Abel                               1          3 /King/Zlotkey/Abel
Ande                               1          3 /King/Errazuriz/Ande
Banda                              1          3 /King/Errazuriz/Banda
Bates                              1          3 /King/Cambrault/Bates
Bernstein                          1          3 /King/Russell/Bernstein
Bloom                              1          3 /King/Cambrault/Bloom
Cambrault                          0          2 /King/Cambrault
Cambrault                          1          3 /King/Russell/Cambrault
Doran                              1          3 /King/Partners/Doran
Errazuriz                          0          2 /King/Errazuriz
Fox                                1          3 /King/Cambrault/Fox
. . . 

级别 Pseudocolumn

对于由分层查询返回的每一行, 级别 pseudocolumn 返回 1, 用于根行、2对于根的子LEVEL等。根行是倒树中的最高行。子行是任何非根行。父行是任何具有子级的行。叶行是没有子级的任何行。图 2-1显示了具有LEVEL值的倒树节点。

图2-1 分层树

Description of Figure 2-1 follows
"图2-1 分层树" 的描述

序列 Pseudocolumns

序列是一个可以生成唯一顺序值的架构对象。这些值通常用于主要和唯一键。可以使用以下 pseudocolumns 引用 SQL 语句中的序列值:

  • CURRVAL: 返回序列的当前值

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

必须使用序列的名称限定CURRVALNEXTVAL :

sequence.CURRVAL
sequence.NEXTVAL

若要引用另一个用户架构中序列的当前或下一个值, 则必须已授予序列上的SELECT对象特权或SELECTANYSEQUENCE系统特权, 并且必须限定包含它的架构的序列:

schema.sequence.CURRVAL
schema.sequence.NEXTVAL

若要引用远程数据库上序列的值, 必须使用数据库链接的完整或部分名称限定序列:

schema.sequence.CURRVAL@dblink
schema.sequence.NEXTVAL@dblink

许多用户可以同时访问序列, 无需等待或锁定。

在何处使用序列值

可以在以下位置使用CURRVALNEXTVAL :

  • 未包含在子查询、实例化视图或视图中的SELECT语句的选择列表

  • INSERT语句中子查询的选择列表

  • INSERT语句的VALUES子句

  • UPDATE语句的SET子句

序列值的限制在以下构造中不能使用CURRVALNEXTVAL :

  • DELETESELECTUPDATE语句中的子查询

  • 视图或实例化视图的查询

  • 具有DISTINCT运算符的SELECT语句

  • SELECT BY BY语句, 其GROUPby 子句或ORDERby 子句

  • 一个SELECT语句, 它与UNIONINTERSECTMINUSset 运算符的另一个SELECT语句组合在一起

  • SELECT语句的WHERE子句

  • CREATETABLEALTERTABLE语句中的列的DEFAULT

  • CHECK约束的条件

在使用CURRVALNEXTVAL的单个 SQL 语句中, 所有引用的LONG列、更新的表和锁定表都必须位于同一数据库中。

如何使用序列值

创建序列时, 可以定义其初始值及其值之间的增量。NEXTVAL的第一个引用返回序列的初始值。后续对NEXTVAL的引用将按定义的增量递增序列值并返回新值。CURRVAL的任何引用都始终返回序列的当前值, 它是上次引用NEXTVAL时返回的值。.

在会话中对序列使用CURRVAL之前, 必须首先使用NEXTVAL初始化序列。有关序列的信息, 请参阅创建序列

在包含对NEXTVAL的引用的单个 SQL 语句中, Oracle 递增序列一次:

  • 对于由SELECT语句的外部查询块返回的每一行。这样的查询块可以出现在以下位置:

    • 顶层SELECT语句

    • INSERT..。SELECT语句 (单表或多表)。对于多表插入, 对 NEXTVAL 的引用必须出现在值子句中, 并且对子查询返回的每一行都更新序列, 即使 NEXTVAL 可能在NEXTVAL VALUES NEXTVAL多表插入。

    • CREATETABLE..。ASSELECT语句

    • CREATEMATERIALIZEDVIEW..。ASSELECT语句

  • 对于在UPDATE语句中更新的每一行

  • 对于包含VALUES子句的每个INSERT语句

  • 对于每个INSERT ..。[ALL|FIRST]语句 (多表插入)。多表插入被视为单个 SQL 语句。因此, 对序列的NEXTVAL的引用只会为来自语句的SELECT部分的每个输入记录增加一次序列。如果在INSERT的任何部分中多次指定NEXTVAL .。[ALL|FIRST]语句, 则无论给定记录的插入频率如何, 所有插入分支的值都是相同的。

  • 对于由MERGE语句合并的每一行。NEXTVAL的引用可以出现在merge_insert_clausemerge_update_clause或两者中。即使在更新或插入操作中实际不使用序列号, NEXTVALUE值对于每个已更新的行和插入的每一行递增。如果在上述任一位置中多次指定NEXTVAL , 则每行的序列递增一次, 并为该行的所有NEXTVAL匹配项返回相同的值。

  • 对于多表 INSERT 全部语句中的每个输入行. INSERT ALL对于子查询返回的每一行, NEXTVAL递增一次, 而不管insert_into_clause映射到每一行的次数是多少。

如果这些位置中的任何一个包含多个对NEXTVAL的引用, 则 Oracle 将递增序列一次, 并为NEXTVAL的所有匹配项返回相同的值。.

如果这些位置中的任何一个都包含对CURRVALNEXTVAL的引用, 则 Oracle 将递增序列, 并为CURRVALNEXTVAL返回相同的值。.

查找序列的下一个值: 示例本示例选择示例架构hr中雇员序列的下一个值。:

SELECT employees_seq.nextval 
  FROM DUAL;

将序列值插入表中: 示例本示例递增雇员序列, 并将其值用于插入到示例表中的新雇员hr.employees:

INSERT INTO employees
  VALUES (employees_seq.nextval, 'John', 'Doe', 'jdoe', '555-1212',
          TO_DATE(SYSDATE), 'PU_CLERK', 2500, null, null, 30);

重用序列的当前值: 示例本示例将一个新订单添加到主订单表中的下一个订单编号。然后将 suborders 添加到明细订单表中:

INSERT INTO orders (order_id, order_date, customer_id)
  VALUES (orders_seq.nextval, TO_DATE(SYSDATE), 106);

INSERT INTO order_items (order_id, line_item_id, product_id)
  VALUES (orders_seq.currval, 1, 2359);

INSERT INTO order_items (order_id, line_item_id, product_id)
  VALUES (orders_seq.currval, 2, 3290);

INSERT INTO order_items (order_id, line_item_id, product_id)
  VALUES (orders_seq.currval, 3, 2381);

版本查询 Pseudocolumns

版本查询 pseudocolumns 仅在 oracle 闪回版本查询中有效, 这是 oracle 闪回查询的一种形式。版本查询 pseudocolumns 是:

  • VERSIONS_STARTSCNVERSIONS_STARTTIME: 在创建行版本时启动系统更改号 (SCN) 或TIMESTAMP此 pseudocolumn 标识数据第一次具有行版本中反映的值的时间。使用此 pseudocolumn 标识 oracle 闪回表或 oracle 闪回查询的过去目标时间。如果此 pseudocolumn 为NULL, 则在开始之前创建行版本。

  • VERSIONS_ENDSCNVERSIONS_ENDTIME: 在行版本过期时, SCN 或TIMESTAMP如果 pseudocolumn 为NULL, 则在查询时行版本是当前的, 或者该行对应于DELETE操作。

  • VERSIONS_XID: 创建行版本的事务的标识符 (RAW编号)。

  • VERSIONS_OPERATION: 事务执行的操作: I用于插入、 D删除或U进行更新。该版本是插入、删除或更新的行的。即, 在INSERT操作之后的行、 DELETE操作之前的行或由UPDATE操作影响的行。

    对于索引键的用户更新, Oracle 闪回版本查询可能将UPDATE操作视为两个操作, DELETEINSERT, 表示为两个版本行, D后面跟着IVERSIONS_OPERATION.

COLUMN_VALUE Pseudocolumn

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

XMLTable的上下文中, 返回的值是数据类型XMLType例如, 以下两个语句是等效的, 并且两者的输出都显示COLUMN_VALUE作为要返回的列的名称:

SELECT *
  FROM XMLTABLE('<a>123</a>');

COLUMN_VALUE
---------------------------------------
<a>123</a>

SELECT COLUMN_VALUE
  FROM (XMLTable('<a>123</a>'));

COLUMN_VALUE
----------------------------------------
<a>123</a>

TABLE集合表达式的上下文中, 返回的值是集合元素的数据类型。下面的语句创建了"创建表: 多级集合示例"中所示的两个嵌套表级别, 以显示在此上下文中COLUMN_VALUE的用法:

CREATE TYPE phone AS TABLE OF NUMBER;   
/
CREATE TYPE phone_list AS TABLE OF phone;
/

下一条语句使用COLUMN_VALUEphone类型中进行选择:

SELECT t.COLUMN_VALUE
  FROM TABLE(phone(1,2,3)) t;

COLUMN_VALUE
------------
           1
           2
           3

在嵌套类型中, 可以在选择列表和TABLE集合表达式中使用COLUMN_VALUE pseudocolumn:

SELECT t.COLUMN_VALUE
  FROM TABLE(phone_list(phone(1,2,3))) p, TABLE(p.COLUMN_VALUE) t;

COLUMN_VALUE
------------
           1
           2
           3

关键字COLUMN_VALUE也是 Oracle 数据库为内部嵌套表的标量值生成的名称, 没有列或属性名, 如下面的示例所示。在此上下文中, COLUMN_VALUE不是 pseudocolumn, 而是实际的列名。

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

OBJECT_ID Pseudocolumn

OBJECT_ID pseudocolumn 返回对象表或视图的列的对象标识符。Oracle 使用此 pseudocolumn 作为对象表的主键。OBJECT_ID在视图触发器INSTEAD OF中很有用, 用于标识对象表中可替换行的 ID。

注意:

在早期版本中, 此 pseudocolumn 称为SYS_NC_OID$ 该名称仍然支持向后兼容性。 但是, Oracle 建议您使用更直观的名称OBJECT_ID.

OBJECT_VALUE Pseudocolumn

OBJECT_VALUE pseudocolumn 返回对象表、 XMLType表、对象视图或XMLType视图的列的系统生成的名称。此 pseudocolumn 用于标识对象表中可替换行的值, 以及使用WITH OBJECT IDENTIFIER子句创建对象视图。

注意:

在早期版本中, 此 pseudocolumn 称为SYS_NC_ROWINFO$ 该名称仍然支持向后兼容性。 但是, Oracle 建议您使用更直观的名称OBJECT_VALUE.

ORA_ROWSCN Pseudocolumn

ORA_ROWSCN反映了对行最近更改的系统更改号 (SCN)。此更改可以位于块 (粗) 或行级别 (细粒度) 的级别。后者由行级依赖项跟踪提供。请参阅CREATETABLE.。NOROWDEPENDENCIES |ROWDEPENDENCIES有关行级依赖项跟踪的更多信息。在没有行级别依赖项的情况下, ORA_ROWSCN反映块级别的依赖项。

无论是在块级别还是在行级别, ORA_ROWSCN都不应视为精确的 SCN。例如, 如果事务更改了块中的行 R 并在 SCN 10 中提交, 则该行的ORA_ROWSCN返回10并不总是正确的。如果值小于10将永远不会返回, 则任何大于或等于10的值都可以返回。即, 行的ORA_ROWSCN并不总是保证是上次修改该行的事务的确切提交 SCN。但是, 使用细粒度的ORA_ROWSCN, 如果两个事务 T1 和 T2 修改了同一行 r, 一个接一个又一次提交, 则在 T1 提交后, 行 r 的ORA_ROWSCN上的查询将返回一个值低于T2 的承诺。如果对块进行两次查询, 则ORA_ROWSCN的值可能在查询之间进行更改, 即使在查询之间的时间内没有更新行。唯一的保证是, 两个查询中的ORA_ROWSCN的值大于上次修改该行的事务的提交 SCN。

不能将查询中的ORA_ROWSCN pseudocolumn 用于视图。但是, 您可以使用它在创建视图时引用基础表。也可以在UPDATEDELETE语句的WHERE子句中使用此 pseudocolumn。

对于闪回查询, 不支持ORA_ROWSCN 。相反, 使用版本查询 pseudocolumns, 这是显式提供的闪回查询。请参阅SELECT..。 flashback_query_clause有关闪回查询和"版本查询 Pseudocolumns"的信息, 以了解有关这些 Pseudocolumns 的其他信息。

对 ORA_ROWSCN 的限制:外部表不支持此 pseudocolumn。

例子下面的第一个语句使用ORA_ROWSCN pseudocolumn 获取employees表上最后一个操作的系统更改号。第二个语句使用带有SCN_TO_TIMESTAMP函数的 pseudocolumn 来确定操作的时间戳:

SELECT ORA_ROWSCN, last_name
  FROM employees
  WHERE employee_id = 188;

SELECT SCN_TO_TIMESTAMP(ORA_ROWSCN), last_name
  FROM employees
  WHERE employee_id = 188;

ROWID Pseudocolumn

对于数据库中的每一行, ROWID pseudocolumn 返回行的地址。Oracle 数据库 rowid 值包含查找行所需的信息:

  • 对象的数据对象编号

  • 数据文件中该行驻留的数据块

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

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

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

ROWID pseudocolumn 的值具有数据类型ROWIDUROWID有关详细信息, 请参阅"Rowid 数据类型""UROWID 数据类型" 。

Rowid 值有几个重要用途:

  • 它们是访问单行的最快方法。

  • 它们可以显示如何存储表中的行。

  • 它们是表中行的唯一标识符。

不应将ROWID用作表的主键。例如, 如果删除并重新插入与导入和导出实用程序的行, 则其 rowid 可能会更改。如果删除一行, 则 Oracle 可能会将其 rowid 重新分配给以后插入的新行。

尽管可以在查询的SELECTWHERE子句中使用ROWID pseudocolumn, 但这些 pseudocolumn 值实际上并不存储在数据库中。不能插入、更新或删除ROWID pseudocolumn 的值。

例子此语句选择包含部门20中员工数据的所有行的地址:

SELECT ROWID, last_name
  FROM employees
  WHERE department_id = 20;

ROWNUM Pseudocolumn

注意:

ROW_NUMBER内置 SQL 函数为排序查询结果提供了高级支持。 有关详细信息, 请参阅ROW_NUMBER 。

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

可以使用ROWNUM来限制查询返回的行数, 如下例所示:

SELECT *
  FROM employees
  WHERE ROWNUM < 11;

如果ORDER BY子句在同一个查询中跟随ROWNUM , 则这些行将由ORDERby 子句重新排序. BY根据访问行的方式, 结果可能会有所不同。例如, 如果ORDERBY子句导致 oracle 使用索引来访问数据, 则 oracle 可能会以不同的顺序检索行, 而不是索引。因此, 下面的语句不一定返回与前面的示例相同的行:

SELECT *
  FROM employees
  WHERE ROWNUM < 11
  ORDER BY last_name;

如果在子查询中嵌入ORDER BY子句, 并将ROWNUM条件置于顶级查询中, 则可以强制在行排序后应用ROWNUM条件。例如, 下面的查询返回具有10个最小雇员编号的员工。这有时称为上 N 报告:

SELECT *
  FROM (SELECT * FROM employees ORDER BY employee_id)
  WHERE ROWNUM < 11;

在前面的示例中, ROWNUM值是顶层SELECT语句的, 因此它们是在子查询中的employee_id已排序之后生成的。

大于正整数的ROWNUM值的条件测试始终为 false。例如, 此查询不返回行:

SELECT *
  FROM employees
  WHERE ROWNUM > 1;

获取的第一行被分配为1的ROWNUM , 并使条件为 false。要提取的第二行现在是第一行, 并且还分配了ROWNUM 1 并使条件为 false。随后, 所有行都无法满足条件, 因此不返回行。

也可以使用ROWNUM为表的每一行分配唯一值, 如本示例所示:

UPDATE my_table
  SET column1 = ROWNUM;

有关为行分配唯一编号的替代方法, 请参阅函数ROW_NUMBER 。

注意:

在查询中使用ROWNUM可能会影响视图优化。

XMLDATA Pseudocolumn

Oracle 根据 XMLSchema 信息以及如何指定存储子句, 在 LOB 或对象关系列中存储XMLType数据。XMLDATA pseudocolumn 允许您访问基础 LOB 或对象关系列, 以指定附加的存储子句参数、约束、索引等。

例子以下语句说明了此 pseudocolumn 的用法。假设您使用一个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);

现在假设您已经创建了一个基于 XMLSchema 的表, 如"在 SQL 语句中使用 XML" 中创建的xwarehouses表。然后, 可以使用XMLDATA列设置基础列的属性, 如下面的语句所示:

ALTER TABLE xwarehouses
  ADD (UNIQUE(XMLDATA."WarehouseId"));

猜你喜欢

转载自blog.csdn.net/huyingzuo/article/details/80299790