Sql 基于IN子句查询Oracle CLOB列

Sql 基于IN子句查询Oracle CLOB列,sql,oracle11g,clob,Sql,Oracle11g,Clob,我有一个具有以下定义的表: Table name: MY_TAB ID NUMBER, ACCESS_LVL CLOB 此表中可能存在的一些示例数据如下: ID: 1 ACCESS_LVL: RoleName-A,RoleName-B,RoleName-C,RoleName-D,RoleName-E ID: 2 ACCESS_LVL: RoleName-D,RoleName-E ID: 3 ACCESS_LVL: RoleName-A,RoleName-B,RoleN

我有一个具有以下定义的表:

Table name: MY_TAB

ID          NUMBER,
ACCESS_LVL  CLOB
此表中可能存在的一些示例数据如下:

ID: 1
ACCESS_LVL: RoleName-A,RoleName-B,RoleName-C,RoleName-D,RoleName-E

ID: 2
ACCESS_LVL: RoleName-D,RoleName-E

ID: 3
ACCESS_LVL: RoleName-A,RoleName-B,RoleName-C,RoleName-D,RoleName-E,RoleName-F,RoleName-G,RoleName-H

ID: 4
ACCESS_LVL: RoleName-E
我不确定如何做的查询是,我需要返回所有可能具有以下访问级别值(其中访问级别是clob)的
id
,即

基本上是这样的:

select id
from my_tab
where ('RoleName-B','RoleName-C','RoleName-D') in (ACCESS_LVL)
所以这个例子的结果是:

ID
1
2
3

在单个列中存储逗号分隔的值违反了所有规范化规则。这将使您的查询更难编写,运行也更慢。您确实应该有一个存储角色的1对多子表。如果这样做,您的查询将更加高效

你可以这样做

select id
  from my_tab
 where ',' || access_lvl || ',' like '%,RoleName-B,%'
    or ',' || access_lvl || ',' like '%,RoleName-C,%'
    or ',' || access_lvl || ',' like '%,RoleName-D,%'

这将非常缓慢,但它会起作用。

在一列中存储逗号分隔的值违反了所有规范化规则。这将使您的查询更难编写,运行也更慢。您确实应该有一个存储角色的1对多子表。如果这样做,您的查询将更加高效

你可以这样做

select id
  from my_tab
 where ',' || access_lvl || ',' like '%,RoleName-B,%'
    or ',' || access_lvl || ',' like '%,RoleName-C,%'
    or ',' || access_lvl || ',' like '%,RoleName-D,%'

这将非常缓慢,但会起作用。

这有帮助吗?@Peter认为这不是我想要的,因为我需要为一组特定的数据执行IN子句。要作为一个查询执行此操作。不,不需要执行IN子句。业务问题中没有此类要求;在你认为问题应该得到解决的狭隘范围内,只有这样一个要求。你需要学会在头脑中清楚地区分这一点。谷歌“XY问题”,看看这意味着什么——它将在未来帮助你。这有用吗?@Peter不认为这是我想要的,因为我需要为一组特定的数据执行in子句。要作为一个查询执行此操作。不,不需要执行IN子句。业务问题中没有此类要求;在你认为问题应该得到解决的狭隘范围内,只有这样一个要求。你需要学会在头脑中清楚地区分这一点。谷歌“XY问题”,看看这意味着什么-它将在未来帮助你。了解你在说什么,贾斯汀,但这是我的数据表定义。没有办法将ACCESS\u LVL clob转换为列表中的变量,这样我就可以将其作为普通IN子句的一部分使用?@tonyf-可以,但这将要复杂得多。您可以使用
access\u lvl
值,从
dual
执行
connect by level
以获取元素数,然后执行一些
substr
instr
调用,将每一个值的单行解析为一行,然后将其用作数据源。这比这段代码要复杂得多,我预计不会更快。而且由于它是CLOB,它(其中“it”=将每个CLOB分离为其组件标记)可能需要很多时间。实际上,任何解决方案都可能需要很多时间,这可能是违反第一个标准形式所付出的代价。我想我还将研究dbms_lob.instr解决方案,看看这是否会有帮助。@tonyf-dbms_lob.instr可能确实工作得更快。另外,如果您被迫处理这种类型的数据,但允许您创建一个物化视图,那么您可以从将字符串分解为MV中的标记中获益。。。特别是如果数据变化(非常)缓慢,请理解你的意思,Justin,但这是我所拥有的数据表定义。没有办法将ACCESS\u LVL clob转换为列表中的变量,这样我就可以将其作为普通IN子句的一部分使用?@tonyf-可以,但这将要复杂得多。您可以使用
access\u lvl
值,从
dual
执行
connect by level
以获取元素数,然后执行一些
substr
instr
调用,将每一个值的单行解析为一行,然后将其用作数据源。这比这段代码要复杂得多,我预计不会更快。而且由于它是CLOB,它(其中“it”=将每个CLOB分离为其组件标记)可能需要很多时间。实际上,任何解决方案都可能需要很多时间,这可能是违反第一个标准形式所付出的代价。我想我还将研究dbms_lob.instr解决方案,看看这是否会有帮助。@tonyf-dbms_lob.instr可能确实工作得更快。另外,如果您被迫处理这种类型的数据,但允许您创建一个物化视图,那么您可以从将字符串分解为MV中的标记中获益。。。尤其是当数据变化(非常)缓慢时。