Oracle:按级别和regexp_substr

时间:2018-12-21 16:18:33

标签: oracle connect-by regexp-substr

您好,我有一个我没有编写的Oracle查询,并且我也没有访问权限以在Oracle环境中运行。

请问有人可以解释这个查询在做什么吗?

WITH tableName AS 
( SELECT regexp_substr(fieldName,'[^,]+',1,level) as tableName 
  FROM   (SELECT :tableName as fieldName From DUAL) 
  CONNECT BY LEVEL <= REGEXP_COUNT(fieldName ,'[,]')+1 )

我了解它正在创建一个名为tableName的CTE,并且Oracle允许在不需要任何表中数据的查询中将DUAL指定为表。这样,上面的查询就不会从任何特定的表中提取。

但是我不了解查询的其余部分,因为我刚接触Oracle。

我尝试使用Google谷歌搜索,但发现空白后,将不胜感激。

2 个答案:

答案 0 :(得分:1)

它将逗号分隔的值字符串分成几行。例如(稍作修改,使其可以在SQL * Plus中使用):

SQL> with tableName AS
  2   ( SELECT regexp_substr(fieldName,'[^,]+',1,level) as tableName
  3     FROM (SELECT '&tableName' as fieldName From DUAL)
  4     CONNECT BY LEVEL <= REGEXP_COUNT(fieldName ,'[,]')+1 )
  5  select * From tablename;
Enter value for tablename: little,foot,overflow

TABLENAME
----------------------------------------------------------------------
little
foot
overflow

SQL>

一个简单/简短的版本:

SQL> select level, regexp_substr('&&fieldName','[^,]+',1,level) as tableName
  2  from dual
  3  connect by LEVEL <= REGEXP_COUNT('&&fieldName' ,'[,]') + 1;
Enter value for fieldname: emp,dept,bonus,salgrade

     LEVEL TABLENAME
---------- --------------------
         1 emp
         2 dept
         3 bonus
         4 salgrade

SQL>

那么,它有什么作用? REGEXP_COUNT计算分隔符的数量(在这种情况下为逗号),并在CONNECT BY中使用,它与其LEVEL伪列的分层查询有关(我将其包含在第二个示例的输出中)在REGEXP_SUBSTR中用作第四个参数 occurrence

答案 1 :(得分:1)

警告:如果列表中有NULL元素,则使用通用正则表达式'[^,]+'进行的字符串解析不会返回预期值。元素将在NULL元素之后放置在错误的位置。请注意,第二个元素为NULL,但是在结果集中,这些元素返回的位置错误:

SQL> select level, regexp_substr('emp,,bonus,salgrade','[^,]+',1,level) as tableName
       from dual
       connect by LEVEL <= REGEXP_COUNT('emp,,bonus,salgrade' ,',') + 1;

     LEVEL TABLENAME
---------- -------------------
         1 emp
         2 bonus
         3 salgrade
         4

使用这种形式的REGXP_SUBSTR()处理NULL:

SQL> select level, regexp_substr('emp,,bonus,salgrade','(.*?)(,|$)',1,level, NULL, 1) as tableName
       from dual
       connect by LEVEL <= REGEXP_COUNT('emp,,bonus,salgrade' ,',') + 1;

     LEVEL TABLENAME
---------- -------------------
         1 emp
         2
         3 bonus
         4 salgrade

See this post for more info