【问题标题】:Oracle 11.1g - Concatenating column values with large strings using wm_concat()Oracle 11.1g - 使用 wm_concat() 将列值与大字符串连接起来
【发布时间】:2014-10-17 12:59:39
【问题描述】:

尝试在 Oracle 11.1g 中连接列值时出现以下错误:

ORA-06502:PL/SQL:数字或值错误:字符串缓冲区太 小

我首先查看了SQL Query to concatenate column values from multiple rows in Oracle,看看我是否可以使用提供的一些解决方案 - 但没有成功。

我的数据如下所示:

Table A

PID

A
B
C

Table B

PID   SEQ       NOTE_FRAGMENT

A     9999      This is the start of the note
A     9998      and this is a continuation of that note.
A     9997      Finally, this is the last part of the note for PID A.
B     9999      Note data for PID B.
C     9999      Yes
C     9998      we can 
C     9997      do 
C     9996      this work!

我的查询如下:

SELECT 
A.PID,
B.SEQ,
wm_concat(B.NOTE_FRAGMENT)
FROM A 
inner join b on A.PID = B.PID
group by A.PID, B.SEQ
order by B.SEQ

再次,我试图将给定 PID 的所有注释按从最大到最小的顺序组合。我也有一种预感,因为我对我的 SQL 很生疏,所以我的订单已经关闭,但是自从我第一次遇到缓冲区问题以来,我很难找到原因。

【问题讨论】:

  • 连接的字符串会超过 4000 字节吗?您是否有理由使用未记录的 wm_concat 函数?而不是使用您链接到的问题中的listagg 分析函数?还是用户定义的聚合函数?
  • 我使用的是 oracle 11.1,这就是我使用 wm_concat 的原因,我相信使用 listagg 的示例适用于 11.2,因为我无法让它为我工作。我不确定连接的字符串是否可以超过 4000 字节,但我认为这肯定是可能的。
  • 如果结果可以超过 4000 字节,则不能使用 wm_concat(即使您使用的是 11.2,也不能使用 listagg)。你能创建一个自定义聚合函数并使用它吗?
  • @JustinCave 你怎么知道聚合操作的最大允许大小?它是依赖于正在聚合的列类型(在这种情况下,我刚刚意识到它是 varchar2(1500))还是来自 Oracle 文档 docs.oracle.com/cd/B28359_01/server.111/b28320/… 中的最大值,它说 varchar2 是 4000 字节?

标签: sql oracle oracle11g oracle-sqldeveloper


【解决方案1】:

我猜B.SEQ 不在您查询的group by 中(否则,根据您的数据,您将连接一行)。

所以,从测量结果字符串的长度开始:

SELECT A.PID, SUM(LENGTH(B.NOTE_FRAGMENT))
FROM A inner join
     b
     on A.PID = B.PID
group by A.PID
order by 3 DESC;

如果最大值超过4000,则不能将结果放入字符串中。

顺便说一句,在 Oracle 11g 中,我会推荐 listagg() 而不是 wm_concat()

编辑:

实际上,Oracle 非常强大,因此您实际上可以为所欲为:

SELECT A.PID,
       listagg(CASE WHEN CLEN < 3500 THEN B.NOTE_FRAGMENT END), ' ') WITHIN GROUP (ORDER BY B.SEQ)
FROM (SELECT A.PID, B.SEQ,
             SUM(LENGTH(B.NOTE_FRAGMENT) + 1) OVER (PARTITION BY A.PID ORDER BY B.SEQ) as CLEN
      FROM A inner join
           b
           on A.PID = B.PID
     ) AB
GROUP BY A.PID
ORDER BY 3 DESC;

这会测量长度并在连接变得太长之前停止连接。

【讨论】:

  • 尝试此查询后,我收到以下错误: ORA-00923: FROM 关键字未在预期的位置找到 00923. 00000 - “FROM 关键字未在预期的位置找到” 你知道这是否与使用的 Oracle 版本?同样,我使用的是 11.1
  • @sager89 。 . .查询中有几个拼写错误。
  • 即使没有拼写错误,它似乎在 'WITHIN' 子句之后发现了错误。另外,看起来最大音符的长度是 333750...许多其他记录远远超过 4000...看起来我必须编写一个程序在 Oracle 之外将它们串在一起...
  • @sager89 。 . .奇怪的。逻辑应该只记录累积长度远小于 4000 个字符的笔记。
  • 对不起,我说的是刚刚给出长度的 sql 查询。我在尝试运行实际返回连接注释的查询时遇到错误。该错误一直出现在“Within”子句之后,指出“FROM 关键字未在预期的位置找到”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-06
  • 1970-01-01
相关资源
最近更新 更多