#伪列

伪列的行为类似于普通列,但其数据并不存储在表中。用户可以SELECT伪列,但不能对伪列进行INSERT、UPDATE、DELETE操作。

YashanDB存在如下五种伪列:

  • ROWSCN
  • ROWID
  • ROWNUM
  • SEQUENCE
  • USER

# ROWSCN伪列

ROWSCN伪列表示行最后一次被修改的SCN。YashanDB的ROWSCN为页面级别,一般情况下返回的ROWSCN是行所在页面最后一次修改并提交的BLOCK SCN,若使用特殊查询条件可能会返回该行最后一次修改并提交的SCN,例如使用ROWID为查询条件时。

若事务修改了表中某行数据并提交了修改,后续查询该行的ROWSCN时,返回值仅会大于或等于修改前的ROWSCN。

该伪列仅适用于HEAP表。

示例(HEAP表)

SELECT ROWSCN FROM area;

# ROWID伪列

ROWID伪列表示行所在的地址。ROWID伪列的类型为ROWID类型,使用限制等更多说明请查阅ROWID UROWID

该伪列仅适用于HEAP表。

示例(HEAP表)

SELECT ROWID FROM area;

# ROWNUM伪列

ROWNUM伪列是系统顺序分配的查询返回的行编号,返回的第一行分配为1,第二行分配为2,依此类推。该伪列可用于限制查询返回的总行数。

分布式部署中不可使用该伪列。

ROWNUM在列存表中的使用限制如下:

  • ROWNUM只能与常量进行比较。
  • 条件语句中不能使用小于、小于等于、大于或大于等于运算符。
  • 使用等值比较时,ROWNUM所比较的对象只能为常量1。
  • 不允许ROWNUM在or的左右条件中使用。
  • ROWNUM在过滤条件中只能使用一次,且只能单独使用,不允许参与运算或作为函数入参。
  • ROWNUM不能出现在非比较谓词和不等于比较中,例如in。
  • 在外连接的连接条件中不可使用ROWNUM。

ROWNUM伪列的常用场景:

WHERE条件中做行数限制

  • WHERE ROWNUM < 常数,返回常数-1行的记录。
  • WHERE ROWNUM = 常数,ROWNUM从1开始累加,因此ROWNUM= 1可以返回1条记录;当ROWNUM = 任何非1值时,条件恒为FALSE,无法返回任何结果。
  • WHERE ROWNUM > 常数,常数小于1,则条件恒为TRUE;常数大于等于1,则条件恒为FALSE(即查询结果恒为空)。

示例(HEAP表)

SELECT area_no,area_name,DHQ FROM area WHERE ROWNUM < 2;

AREA_NO AREA_NAME                                                     DHQ                   
------- ------------------------------------------------------------- --------------------- 
01      华东                                                        Shanghai             

ROWNUM与ORDER BY一起使用

先从表中取出符合ROWNUM条件的行然后再进行排序,其结果取决于执行计划,执行计划不同可能会导致取得的行不同。

示例(单机、共享集群部署)

-- 创建表STUDENTS
CREATE TABLE STUDENTS(num INT,score INT);
INSERT INTO STUDENTS VALUES(1,99);
INSERT INTO STUDENTS VALUES(1,76);
INSERT INTO STUDENTS VALUES(1,84);
INSERT INTO STUDENTS VALUES(1,63);
INSERT INTO STUDENTS VALUES(1,88);
COMMIT;

-- 查询成绩前3的学生成绩,先取出3行再进行排序,结果不一定正确
SELECT score FROM STUDENTS WHERE ROWNUM < 4 ORDER BY score DESC;

-- 查询成绩前3的学生成绩,可以使用order by + limit
SELECT score FROM STUDENTS ORDER BY score DESC LIMIT 3;

-- 查询成绩前3的学生成绩,可以使用子查询 + ROWNUM
SELECT score FROM (SELECT score FROM STUDENTS ORDER BY score DESC) WHERE ROWNUM < 4;

ROWNUM与JOIN一起使用

在JOIN语句中,ROWNUM与在WHERE中使用相同的规则判断。

使用ROWNUM给表中每一行附上唯一的值

示例(单机、共享集群部署)

UPDATE STUDENTS SET num = ROWNUM;

# SEQUENCE伪列

SEQUENCE伪列是创建序列对象时生成的唯一序列号,可分为如下两种类型:

  • CURRVAL:返回当前序列号值,即当前session上一次获取到的NEXTVAL值。
  • NEXTVAL:增加序列号的值并返回序列的NEXTVAL。

分布式部署中不可使用该伪列。

获取序列号:

sequence.CURRVAL
sequence.NEXTVAL

获取指定schema的序列号:

schema.sequence.CURRVAL
schema.sequence.NEXTVAL

dblink获取远端序列号:

[schema.]sequence.CURRVAL@DBLINK_NAME
[schema.]sequence.NEXTVAL@DBLINK_NAME

可以在以下场景使用CURRVAL伪列与NEXTVAL伪列:

  • SELECT语句中被查询的列中不包含子查询的场景
  • INSERT语句中的SELECT从句
  • INSERT语句中的VALUES从句
  • UPDATE语句中的SET从句

禁止使用的场景:

  • DELETE、SELECT、UPDATE语句中的子查询语句
  • 带有DISTINCT算子的SELECT语句
  • 带有GROUP BY或ORDER BY子句的SELECT语句
  • 多个SELECT语句通过UNION集合
  • SELECT语句中的WHERE子句

对于某一个序列号,在使用CURRVAL伪列前,同一会话中必须先通过NEXTVAL伪列完成CURRVAL值的初始化。

示例(单机、共享集群部署)

用以下语法获取序列号:

CREATE SEQUENCE seq_yashan_pseudo;
 
SELECT seq_yashan_pseudo.NEXTVAL FROM dual;
  SEQ_YASHAN1.NEXTVAL
---------------------
                    1

SELECT seq_yashan_pseudo.CURRVAL FROM dual;
  SEQ_YASHAN1.CURRVAL
---------------------
                    1

# USER伪列

USER伪列返回当前登录用户的用户名,返回值类型为VARCHAR(64)。

分布式部署中不可使用该伪列。

示例(单机、共享集群部署)

SELECT USER FROM DUAL;
pdf-btn 下载文档
copy-btn 复制链接