PDA

View Full Version : Listagg in ein Feld einlesen



Robi
18-03-26, 10:55
Moin *all

ich brauche für eine Anzeige das Ergebnis einer Listagg Funktion

select substr(listagg(digits(NUMFELD), ', '), 1, 55) from ... funktioniert

Will ich das in eine Datei umleiten (create table x/y as (... ) with data) bekomme ich einen

SQL0802 der Art 12
Fehler bei Datenumsetzung oder beim zuordnen der Daten.
12 = Ergebnis einer Verknüpfungsoperation für ein Feld var.Länge übersteigt die Max. zul. Länge für die Ergebnisart.

Auch mit Char(..., 55) oder varchar(...., 55) habe ich es versucht, selbe Meldung.

Erstelle ich die Datei 'with no data' geht das und ich bekomme:
55 *char wenn ohne cast
55 *char wenn Char und
55 *varchar wenn Varchar.

Ich will das im embeddet sql und wollte eigendlich nur wissen wir ich das Zielfeld zu definieren habe.

Einer ne Idee?
Danke

Fuerchau
18-03-26, 12:10
ListAGG ergibt ein CLOB/DBCLOB, der SUBSTR ergibt denselben Typ.
Wenn das Ergebnis kleiner 32K ist, kannst du das nach dem Substr als
cast(substr(listagg...), 1, n) as varchar(n))
umbauen.

Willst du das ohne Zwischendatei direkt im RPG als Hostfeld, kannst du ein DBCLOB bis 8 MB im Programm anlegen, via SQLTYPE-Funktion.
https://www.ibm.com/docs/en/i/7.6.0?topic=dlhviiratus-lob-host-variables-in-ile-rpg-applications-that-use-sql

Robi
18-03-26, 12:43
Ach du meine Güte ...

ok, danke

ich brauch nun ein Paar Werte die in Summe, incl der ', ' Trennung, in 55 Byte passen.
Kanonen und Spatzen ...
Danke dir

Fuerchau
18-03-26, 16:18
Dann sollte ja der Cast klappen.

B.Hauser
19-03-26, 08:15
Das Problem ist, dass das Ergebnis von LISTAGG länger als 4000 Byte und es dadurch zum Feldüberlauf kommt und nicht erst bei 32K wie Baldur behauptet - Dokumentation lesen! Der Feldüberlauf führt wiederum per Default zum Abbruch.
Man könnte natürlich das Ergebnis aus Digits als CLOB formatieren, dann dürfte das Ergebnis bis zu einem MB groß werden, bevor es zu einem Überlauf und damit per Default zum Abbruch kommt.

Wenn Dich wirklich nur die ersten 55 Byte des Strings interessieren und dir egal ist ob anschließend noch 20 oder 500 oder ... Einträge kommen, kannst Du einfach am Ende der LISTAGG-Funktion ON OVERFLOW TRUNCATE angeben.

Etwa so:



Create Table YourSchema.NewTable
as (Select Substr(ListAgg(Digits(YourColumn), ', ' ON OVERFLOW TRUNCATE), 1, 55) as YourCol
from YourTable)
With data;

Mit CAST, CHAR oder VARCHAR um den SUBSTR herum wird des nicht klappen!
Da ist das Kind bereits in den Brunnen gefallen.