我已经阅读了其他问题和答案,它们对我的问题没有帮助。我问是否有一种方法可以限制listagg返回的结果数。
我正在使用此查询
HR-HR <80的任何婴儿 AS
[INFO] Analysis Complete (1 seconds)
[WARNING]
One or more dependencies were identified with known vulnerabilities in test:
commons-email-1.1.jar (org.apache.commons:commons-email:1.1, cpe:/a:apache:commons_email:1.1) : CVE-2017-9801, CVE-2018-1294
See the dependency-check report for more details.
,我收到以下错误消息:
ORA-01489:字符串连接的结果太长
我已经在线研究了如何设置大小限制,但似乎无法使其正常工作。有人可以建议如何设置限制,以使其不超过50个字符。
答案 0 :(得分:2)
在Oracle 12.2中,您可以在ON OVERFLOW ERROR
中使用LISTAGG
,例如:
LISTAGG(meas_value, '; ' ON OVERFLOW ERROR) WITHIN GROUP (ORDER BY fm.recorded_time)
然后,您可以用SUBSTR()
括起来以获取前50个字符。
在12.2之前的版本中,您需要重组查询以限制LISTAGG
看到的行数。这是一个使用DBA_OBJECTS
的示例(因此没有您的表的人可以运行它)。对于每种对象类型,它只会显示第三个值。
SELECT object_type,
listagg(object_name, ', ') within group ( order by object_name) first_three
FROM (
SELECT object_type,
object_name,
row_number() over ( partition by object_type order by object_name ) ord
FROM dba_objects
WHERE owner = 'SYS'
)
WHERE ord <= 3
GROUP BY object_type
ORDER BY object_type;
想法是对要聚合的行进行编号,然后仅对其中的第一个X进行聚合,其中“ X”足够小,不会溢出VARCHAR2
上的最大长度。 “ X”取决于您的数据。
或者,如果您不希望中间值出现50个字符的截断和/或不知道可以安全地允许多少个值,则可以将ord
表达式替换为{ {1}}表达式以保持长度的连续计数,并在达到您的限制(50个字符)之前将其限制为上限。该表达式将为running_length
。像这样:
SUM(length()) OVER (...)
对于您的查询,所有内容汇总如下:
SELECT object_type,
listagg(object_name, ', ') within group ( order by object_name) first_50_char,
FROM (
SELECT object_type,
object_name,
sum(length(object_name || ', '))
over ( partition by object_type order by object_name ) running_len
FROM dba_objects
WHERE owner = 'SYS'
)
WHERE running_len <= 50+2 -- +2 because the last one won't have a trailing delimiter
GROUP BY object_type
ORDER BY object_type;