OceanBase 偽類

2021-06-18 13:46 更新

偽列(Pseudocolumn)的行為與表中的列相同,但并未存儲(chǔ)具體數(shù)值。因此,偽列只具備讀屬性,您不可以對(duì)偽列進(jìn)行插入、更新、刪除的等行為。

層次查詢偽列

層次查詢偽列僅在層次查詢中有效,要在查詢中定義層次結(jié)構(gòu)關(guān)系,必須使用 CONNECT BY 子句。

CONNECT_BY_ISCYCLE 偽列

?CONNECT_BY_ISCYCLE? 偽列用來協(xié)助標(biāo)記循環(huán)是從哪一行開始的。如當(dāng)前行的子節(jié)點(diǎn)同時(shí)也是其祖先節(jié)點(diǎn)之一,則?CONNECT_BY_ISCYCLE? 返回 1,否則返回 0。

?CONNECT_BY_ISCYCLE? 需要配合 ?CONNECT BY? 子句的 ?NOCYCLE? 使用,否則查詢結(jié)果會(huì)因樹狀結(jié)果存在循環(huán)而報(bào)錯(cuò)。

CONNECT_BY_ISLEAF 偽列

?CONNECT_BY_ISLEAF? 偽列用來協(xié)助標(biāo)記層次結(jié)構(gòu)的葉子節(jié)點(diǎn)。如當(dāng)前行無子節(jié)點(diǎn)即為樹的葉子節(jié)點(diǎn)時(shí),返回 1,否則返回 0。

LEVEL 偽列

?LEVEL? 偽列用來協(xié)助標(biāo)記節(jié)點(diǎn)的層次。層次結(jié)構(gòu)中,根為第 1 層,根的子結(jié)點(diǎn)為第 2 層,之后以此類推。例如,根節(jié)點(diǎn)的 LEVEL 值會(huì)返回 1,根節(jié)點(diǎn)的子節(jié)點(diǎn)的 ?LEVEL? 值會(huì)返回 2,之后以此類推。

序列偽列

序列(Sequence)偽列是數(shù)據(jù)庫按照一定規(guī)則生成的自增數(shù)字序列。因其自增的特性,通常被用作主鍵和唯一鍵。序列偽列有兩種取值方法:

  • ?CURRVAL?:返回序列的當(dāng)前值。
  • ?NEXTVAL?:返回序列的下一個(gè)自增值。

使用序列偽列時(shí),必須在 ?CURRVAL?、?NEXTVAL? 前帶上序列的名稱,并用句點(diǎn)(.)引用。例如,序列的名稱為 SEQ_FOO,則可以通過 ?SEQ_FOO.CURRVAL? 獲取 SEQ_FOO 序列的當(dāng)前值。同樣,可以通過? SEQ_FOO.NEXTVAL ?獲取 SEQ_FOO 序列的下一個(gè)自增值。

序列偽列的應(yīng)用場景

序列偽列 ?CURRVAL? 和 ?NEXTVAL? 的值可以用于以下位置:

  • 非子查詢、物化視圖或者視圖中的 ?SELECT? 語句的選擇列表中。
  • ?INSERT? 語句中子查詢的選擇列表中。
  • ?INSERT? 語句中的 ?VALUE? 子句中。
  • ?UPDATE? 語句中的?SET子句中。

序列偽列 ?CURRVAL? 和 ?NEXTVAL? 的值不能用于以下位置:

  • ?DELETE?、?SELECT? 或者 ?UPDATE? 語句的子查詢中。
  • 視圖或者物化視圖的查詢中。
  • 帶 ?DISTINCT? 運(yùn)算符的 ?SELECT? 語句中。
  • 帶 ?GROUP BY ?子句或者 ?ORDER BY? 子句的 ?SELECT? 語句中。
  • 與另一個(gè) ?SELECT? 語句通過 ?UNION?、?INTERSECT或者 ?MINUS? 集合運(yùn)算符進(jìn)行聯(lián)合的 ?SELECT? 語句中。
  • ?SELECT? 語句的 ?WHERE? 子句中。
  • ?CREATE TABLE ?或者 ?ALTER TABLE? 語句中列的 ?DEFAULT? 值。
  • ?CHECK? 約束的條件中。

如何使用序列偽列

創(chuàng)建序列時(shí),需要明確其初始值和步長。第一次引用 ?NEXTVAL? 將返回序列的初始值,后續(xù)對(duì) ?NEXTVAL? 的引用將按照上一次序列的返回值加上序列定義的步長后返回一個(gè)新值。任何時(shí)候?qū)?nbsp;?CURRVAL? 的引用,都將返回當(dāng)前序列的值,即最后一次對(duì) ?NEXTVAL? 引用時(shí)返回的值。

在會(huì)話中引用序列的 ?CURRVAL? 偽列前,都應(yīng)首先應(yīng)用序列的 ?NEXTVAL? 偽列來初始化本次會(huì)話的序列值。

創(chuàng)建序列時(shí),可以定義其初始值以及其值之間的增量。對(duì) ?NEXTVAL? 的第一次引用將返回序列的初始值。對(duì) ?NEXTVAL? 的后續(xù)引用將會(huì)使序列值按照定義的增量遞增,并返回新值。任何對(duì) ?CURRVAL ?的引用總是返回該序列的當(dāng)前值,即最后一次對(duì) ?NEXTVAL? 引用時(shí)返回的值。對(duì)序列的創(chuàng)建的相關(guān)內(nèi)容,請參考文檔  CREATE SEQUENCE 章節(jié)。

在單條 SQL 語句中引用 ?NEXTVAL? 時(shí),OceanBase 數(shù)據(jù)庫按照以下方式遞增序列:

  • ?SELECT? 語句的外部查詢塊每返回一行遞增一次。這類查詢塊可以出現(xiàn)在以下地方:
    • 頂層 ?SELECT? 語句。
    • ?INSERT... SELECT? 語句。對(duì)于多表插入,?NEXTVAL? 必須位于 ?VALUES? 子句中,子查詢每返回一行序列就遞增一次,即使多個(gè)分支引用了 ?NEXTVAL?。
    • ?CREATE TABLE ... AS SELECT? 語句。
    • ?CREATE MATERIALIZED VIEW ... AS SELECT?語句。
  • ?UPDATE? 語句每更新一行序列就遞增一次。
  • 每有一條包含 ?VALUES? 子句的 INSERT 語句就遞增一次。
  • ?MERGE? 語句每合并一行序列遞增一次。?NEXTVAL? 可以出現(xiàn)在? merge_insert_clause? 或者?merge_update_clause? 子句中,也可兩者同時(shí)出現(xiàn)。?NEXTVAL? 會(huì)隨著每一行的更新和插入而遞增,即使序列數(shù)值沒有用于更新或者插入操作。如果 ?NEXTVAL? 在這些位置中被指定了多次,那么對(duì)應(yīng)每一行都遞增一次序列,而且該行中出現(xiàn)的所有 ?NEXTVAL? 都返回相同的值。

當(dāng)這些位置多次引用一個(gè)序列的 ?NEXTVAL? 偽列時(shí),該序列都只遞增一次,即為所有被引用的 ?NEXTVAL? 偽列返回當(dāng)前序列的下一個(gè)序列值。

當(dāng)這些位置同時(shí)引用一個(gè)序列的 ?CURRVAL?和 ?NEXTVAL? 偽列時(shí),OceanBase 將遞增該序列,即為被引用的 ?CURRVAL? 和 ?NEXTVAL? 偽列都返回當(dāng)前序列的下一個(gè)序列值。

序列可以同時(shí)被許多用戶訪問,不存在等待和鎖定。

ROWSCN 偽列

?ORA_ROWSCN? 偽列將最新更改的系統(tǒng)更改號(hào)(SCN:System Change Number)反映到一行,該更改號(hào)表示這一行數(shù)據(jù)修改所在事務(wù)的提交時(shí)間。

ROWNUM 偽列

?ROWNUM? 偽列會(huì)對(duì)查詢結(jié)果中的每一行進(jìn)行編號(hào),其值為該行在查詢結(jié)果集中的具體位置。第一行返回值 1,第二行返回值 2,之后以此類推。

ROWNUM 的用法說明

?ROWNUM? 可以限制返回的行數(shù),例如以下示例,將返回 employees 表中的 5 條數(shù)據(jù):

SELECT * FROM employees WHERE rownum <=5;

如果在 ?ROWNUM? 后有 ?ORDER BY? 子句,則將對(duì)滿足 ?WHERE? 條件句的結(jié)果進(jìn)行重排序。如果將 ?ORDER BY? 子句嵌入子查詢中,并將 ?ROWNUM? 偽列作為條件放置在頂級(jí)查詢中,則可以強(qiáng)制 ?ROWNUM?條件在行排序之后執(zhí)行。例如,使用以下語句查詢年齡最大的 5 名員工信息是得不到預(yù)期結(jié)果的,該語句只是將查詢結(jié)果中的前 5 條員工信息進(jìn)行年齡排序:

SELECT * FROM employees WHERE rownum <=5 ORDER BY age DESC;

正確的用法應(yīng)該如下:

SELECT * FROM (SELECT * FROM employees ORDER BY age DESC) WHERE rownum <= 5;

在 ?WHERE? 子句中,指定 ?ROWNUM? 大于任何一個(gè)正整數(shù)時(shí)總是返回 FALSE,例如以下 SQL 語句將不返回任何信息:

SELECT * FROM employees WHERE rownum > 1;

因?yàn)樵讷@得表的第一行結(jié)果時(shí),改行的 ?ROWNUM? 偽列值將被賦值為 1,此時(shí)在 ?WHERE? 條件判斷時(shí)結(jié)果為 FALSE,則此行被舍去。在獲得第二行結(jié)果時(shí),該行的 ?ROWNUM? 偽列值任然被賦值為 1,?WHERE? 條件判斷的結(jié)果依舊為 FALSE,此行再次被舍去。以此類推,所以所有行都不滿足條件,因此不返回任何數(shù)據(jù)。

也可以通過 ?UPDATE? 語句將? ROWNUM? 數(shù)值賦值給表中的某一列,例如:

UPDATE employees SET id = rownum;

此語句將對(duì)表 employees 的 id 列進(jìn)行? ROWNUM? 賦值,即依次對(duì) id 列賦值 1、2、... 直至該表總行數(shù)。

注意 
在查詢中使用? ROWNUM ?可能會(huì)影響視圖優(yōu)化。

ROWID 偽列

ROWID 偽列提供了快速定位表中某一行的能力,ROWID 值由主鍵編碼得到,不會(huì)進(jìn)行實(shí)際的存儲(chǔ),類型是 UROWID。使用方法如下:

  1. 從 employees 表中查詢到 ROWID 值

    obclient> SELECT ROWID, last_name FROM employees WHERE department_id = 20;
    +-------------------+-----------+
    | ROWID             | LAST_NAME |
    +-------------------+-----------+
    | *AAIKAQAAAAAAAAA= | xxx       |
    +-------------------+-----------+
    1 row in set (0.01 sec)
  2. 使用 ROWID 值進(jìn)行 update 操作

    obclient> UPDATE employees SET last_name = 'yyy' WHERE ROWID = '*AAIKAQAAAAAAAAA=';
    Query OK, 1 row affected (0.01 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    obclient> select last_name, department_id from employees;
    +-----------+---------------+
    | LAST_NAME | DEPARTMENT_ID |
    +-----------+---------------+
    | yyy       |            20 |
    +-----------+---------------+
    1 row in set (0.01 sec)


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)