将逗号分隔的字符串解析为行

时间:2016-10-12 19:54:36

标签: sql oracle

我有一个用户表,它有一个角色列。每个用户可以有多个角色(或者没有),为了便于使用,我使用逗号分隔列表来存储角色。

USERNAME   ROLE
----------------------
bob        role1,role2
sally      role2

现在,需要检查特定角色,我已经创建了一个视图来获取用户角色映射(类似于基本的XREF表),使用以下子选项:

SELECT DISTINCT username,
  trim(regexp_substr(str, '[^,]+', 1, level)) authority
FROM
  (SELECT username, role str FROM user WHERE role IS NOT NULL
  ) roles_table
CONNECT BY instr(str, ',', 1, level - 1) > 0

获取

USERNAME   AUTHORITY
----------------------
bob        role1
bob        role2
sally      role2

问题是此子查询需要花费大量时间才能运行。 有没有更好的格式化方法来优化流程?

或者我是否需要更新整个结构并恢复使用XREF表? 如果是后者,我可以通过使用索引来创建XREF视图并以某种方式加快速度吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

你可以通过使用instr和substr(而不是regexp版本)来加速它,或者加速它如果输入是CLOB而你使用了instr和substr的dbms_lob版本。

您可以使用on commit refresh fast创建物化视图(代价是在基表上的事务处理速度稍慢)。

最好的选择是将基表替换为第一范式 - 基本上使用当前视图的结果。但也许这不是一种选择。

编辑:我只是再次查看了查询,看看你在做什么......不好!编写分层查询的方式,它会生成过多的行,然后使用DISTINCT减少这些行。先试试这个,也许就是你所需要的:

select username, trim(regexp_substr(str, '[^,]+', 1, level)) authority
from   user
connect by instr(str, ',', 1, level - 1) > 0
       and prior username = username
       and prior sys_guid() is not null;