oracle CLOB问题-将CLOB列拆分为多行

hxzsmxv2  于 2023-06-05  发布在  Oracle
关注(0)|答案(1)|浏览(381)

我有一张table(描述table):
| 姓名|类型|
| - -----|- -----|
| 关键值|VARCHAR2(100)|
| 正文|CLOB|
示例
| 键值|文本|
| - -----|- -----|
| 一百零一|客户输入05/15/2023 07:20:20 My name is ABX +++ Private Notes What is you name+客户输入04/30/2023 19:40:58 I have issue related to water purifier purchased on Jan 23 +++ Public Notes 04/30/2023 18:19:18 +客户输入04/30/2023请求发送技术人员,由于在工单20092中查看的相同问题,我们无法将其提出。我们不知道这是否与之前的问题相同,但需要知道原因语言偏好:英语|
| 一百零二|客户输入05/15/2023 07:20:20 20424596参考上述票据
+客户输入04/30/2023 19:40:58请更换该项目,因为这是一个有故障的项目
+公众注意04/30/2023 18:19:18 +++客户输入04/30/2023 17:54:54共享了故障机器图片,以便快速采取行动问题背景:第一次发现问题是什么时候?- 4/30,1AM左右最近是否进行了任何更改或维护?- 语言偏好:英语|
我基本上是通过“客户输入”这个词将整个阶段拆分为多行。类似下面的东西:

SELECT distinct keyvalue, level pos, trim(regexp_substr(text, 'Customer Input[^+++]*', 1, level))  x
  FROM 
  (
    SELECT 101 as keyvalue,'Customer Input 05/15/2023 07:20:20 My name is ABX +++ Private Notes What is you name+++Customer Input 04/30/2023 19:40:58 I have issue related to water purifier purchased on Jan 23 
    +++ Public Notes 04/30/2023 18:19:18 +++Customer Input 04/30/2023 Requesting to send a technicial, we could not bring them up due to the same issue that was looked into in ticket 20092. We dont know if this is the same issue as the previous ticket, but need to know the reason Language Preference: English| '
    as text from dual
    union all 
    SELECT 102 as keyvalue,' Customer Input 05/15/2023 07:20:20 20424596 Reference to the above ticket+++Customer Input 04/30/2023 19:40:58 Plesae replace the item as this is a faulty one 
    +++ Public Notes 04/30/2023 18:19:18 +++Customer Input 04/30/2023 17:54:54 Shared the faulty machine pics for quick action Problem Context: When was the issue first observed? - 4/30, 1AM or so Were there any recent changes 
    or maintenance performed? - Language Preference: English| '
    as text from dual  

  ) t
CONNECT BY instr(text, 'Customer Input', 1, level - 1) > 0
order by keyvalue;

| 键值|位置|正文|
| - -----|- -----|- -----|
| 一百零一|1|客户输入05/15/2023 07:20:20 My name is ABX|
| 一百零一|2| Customer Input 04/30/2023 19:40:58我在1月23日购买的净水器有问题|
| 一百零一|3|客户输入04/30/2023请求发送技术信息,由于与20092号工单中调查的相同问题,我们无法将其提出。我们不知道这是否与之前的问题相同,但需要知道原因语言偏好:英语|
| 一百零一|4||
| 一百零二|1|客户输入05/15/2023 07:20:20 20424596参考上述票据|
| 一百零二|2|客户输入04/30/2023 19:40:58请更换该项目,因为这是一个故障|
| 一百零二|3|客户输入04/30/2023 17:54:54共享了故障机器图片,以便快速采取措施问题背景:第一次发现问题是什么时候?- 4/30,1AM左右最近是否进行了任何更改或维护?- 语言偏好:英语|
| 一百零二|4||
由于text列是字符数据类型,因此这可以正常工作。
但是当我运行下面的查询时(在实际的列上,它是clob数据类型)

SELECT distinct keyvalue, level pos, trim(regexp_substr(customer_input_info, 'Customer Input[^+++]*', 1, level)) str
  FROM (select 101 as keyvalue,to_clob('Customer Input 05/15/2023 07:20:20 20424596 Reference to the above ticket+++Customer Input 04/30/2023 19:40:58 Plesae replace the item as this is a faulty one 
    +++ Public Notes 04/30/2023 18:19:18 +++Customer Input 04/30/2023 17:54:54 Shared the faulty machine pics for quick action Problem Context: When was the issue first observed? - 4/30, 1AM or so Were there any recent changes 
    or maintenance performed? - Language Preference: English| ') as customer_input_info from dual) t
CONNECT BY instr(customer_input_info, 'Customer Input', 1, level - 1) > 0
order by 1

我得到下面的错误
ORA-00932:不一致的数据类型:预期-得到CLOB 00932。00000 -“不一致的数据类型:预期的%s得到了%s”* 原因:

  • 操作:行出错:44列:38。
    我不能对内部sql查询进行更改,因为源表是clob数据类型。我应该对外部查询做什么更改。
7nbnzgx9

7nbnzgx91#

如果源文本是一个CLOB,无论长度如何,您发布的代码都会得到该错误。问题不在于长度本身,而是每个拆分行的值也是一个CLOB,并且不能对CLOB使用distinct
使用distinct通常是一个信号,表明有一个更深层次的问题只是被掩盖了。如果没有它,您确实会得到副本,但这是针对多个源行的connect-by查询的一个众所周知的问题,并且随着行的增加会逐渐变得更糟。
您需要将connect-by限制为相同的源行,这很简单,假设keyvalue是唯一的;但是你还需要引入一个非确定性函数调用来防止它使结果膨胀,例如:

CONNECT BY instr(text, 'Customer Input', 1, level - 1) > 0
AND keyvalue = PRIOR keyvalue
AND PRIOR dbms_random.value IS NOT NULL

fiddle
如果切换到使用递归子查询分解而不是分层查询,您可能会发现它更容易理解和维护:

WITH r (keyvalue, text, pos, x) as (
  SELECT keyvalue, text, 1, trim(regexp_substr(text, 'Customer Input[^+++]*', 1, 1))
  FROM t
  UNION ALL
  SELECT keyvalue, text, pos + 1, trim(regexp_substr(text, 'Customer Input[^+++]*', 1, pos + 1))
  FROM r
  WHERE instr(text, 'Customer Input', 1, pos) > 0
)
SELECT keyvalue, pos, x
FROM r
order by keyvalue, pos;

| 关键值|POS| X型|
| - -----|- -----|- -----|
| 一百零一|1|客户输入05/15/2023 07:20:20 My name is ABX|
| 一百零一|2| Customer Input 04/30/2023 19:40:58我在1月23日购买的净水器有问题|
| 一百零一|3|客户输入04/30/2023请求发送技术信息,由于与20092号工单中调查的相同问题,我们无法将其提出。我们不知道这是否与之前的问题相同,但需要知道原因语言偏好:英语||
| 一百零一|4||
| 一百零二|1|客户输入05/15/2023 07:20:20 20424596参考上述票据|
| 一百零二|2|客户输入04/30/2023 19:40:58请更换产品,因为这是一个有故障的产品|
| 一百零二|3|客户输入04/30/2023 17:54:54共享了故障机器图片,以便快速采取措施问题背景:第一次发现问题是什么时候?- 4/30,凌晨1点左右最近有什么变化吗 或进行了维护?- 语言偏好:英语||
| 一百零二|4||
fiddle
我给它留下了相同的停止条件,这将生成一个最终的空条目。对于这两种方法,您可能需要重新考虑这一点。

相关问题