Ruzie met PL/pgSQL [solved]
Ik heb de volgende twee tabellen:
tabel 'elements'
- id SERIAL
- element VARCHAR
tabel 'styles'
- id SERIAL
- style TEXT
- element INTEGER (FOREIGN KEY -> elements(id))
Nu komen sommige 'style'-s uit de tabel 'styles' meerdere malen voor, maar met verschillende elementen.
Ik voer deze query uit en zo wil ik het hebben, werkt perfect:
SELECT style FROM styles GROUP BY style ORDER BY style
Maar, nu wil ik ook netjes een met komma gescheiden lijstje van alle 'element'-s die deze 'style' hebben. Voor zover ik weet kun je niet een subquery concatten, dus schrijf ik er even een functie voor. Ik kom in eerste instantie hier op uit:
CREATE FUNCTION get_all(text) RETURNS text '
DECLARE
style_text ALIAS FOR $1;
elements_text TEXT;
row_data record;
BEGIN
FOR row_data IN (SELECT element FROM elements WHERE id IN ( SELECT element FROM styles WHERE style = style_text)) LOOP
elements_text := elements_text || row_data.element || '', '';
END LOOP;
RETURN elements_text;
END;
' LANGUAGE 'plpgsql';
Edit:
De query binnen de functie levert wel het juiste resultaat op als ik 'm los uitvoer:
SELECT element FROM elements WHERE id IN ( SELECT element FROM styles WHERE style = 'color: #FFF;')
Namelijk:
element
---------
a:link
a:hover
body
#main
etc
SELECT element FROM elements WHERE id IN ( SELECT element FROM styles WHERE style = 'color: #FFF;')
Namelijk:
element
---------
a:link
a:hover
body
#main
etc
Als ik nu deze functie uitvoer en er wel resultaten zijn, dan krijg ik:
Quote:
SQL fout:
ERROR: query "SELECT $1 || $2 || '', ''" returned 2 columns
CONTEXT: PL/pgSQL function "get_all" line 7 at assignment
In statement:
SELECT get_all(style) FROM styles
ERROR: query "SELECT $1 || $2 || '', ''" returned 2 columns
CONTEXT: PL/pgSQL function "get_all" line 7 at assignment
In statement:
SELECT get_all(style) FROM styles
Of als ik logischerwijs wat dingen wijzig gaat 'ie klagen over een verkeerde integerwaarde, terwijl het juist met strings werkt. Erg raar.
Nu kan ik 'm ook herschrijven, maar dan krijg ik geen error, maar gewoon over NULL:
DECLARE
style_text ALIAS FOR $1;
elements_text TEXT;
elements_this TEXT;
elements_current RECORD;
BEGIN
FOR elements_current IN SELECT element FROM styles WHERE style = style_text LOOP
SELECT INTO elements_this element FROM elements WHERE id = elements_current.element;
elements_text := elements_text || elements_this;
END LOOP;
RETURN elements_text;
END;
Voor de duidelijkheid, ik gebruik dus:
SELECT style, get_all(style) FROM styles GROUP BY style ORDER BY style
Ik werk eigenlijk nooit met het uitlezen van rows via PL/pgSQL, dus misschien dat ik iets over het hoofd zie dat een ervaren FOR-INner wel ziet.
Alvast bedankt voor jullie tijd,
Erik
Edit:
Script heeft te maken met CSS generator voor een grote website.
Gewijzigd op 01/01/1970 01:00:00 door PHP erik
FROM styles AS s, elements AS e
WHERE s.element_id = e.id
GROUP BY style
ORDER BY style ASC
Edit:
alias toegevoegd
alias toegevoegd
Gewijzigd op 01/01/1970 01:00:00 door Jan Koehoorn
ERROR: function group_concat(character varying) does not exist
HINT: No function matches the given name and argument types. You may need to add explicit type casts.
In statement:
SELECT s.style, GROUP_CONCAT( e.element ) AS element_list
FROM styles AS s, elements AS e
WHERE s.element_id = e.id
GROUP BY style
ORDER BY style ASC
Jammer, ik hoop dat PostGre ook wel een group_concat zou hebben :-(
Hmm, er moet toch echt zoiets bestaan, effe zoeken hoor.
SELECT TRIM(', ' FROM CONCAT((SELECT element FROM elements WHERE id = styles.element)||', ')), style FROM styles GROUP BY style
Gewijzigd op 01/01/1970 01:00:00 door Jan Koehoorn
Thanks Jan voor je nuttige reacties.
DECLARE
style_text ALIAS FOR $1;
elements_text TEXT = ' ';
elements_this TEXT;
elements_current RECORD;
BEGIN
FOR elements_current IN SELECT element FROM styles WHERE style = style_text LOOP
SELECT INTO elements_this element FROM elements WHERE id = elements_current.element;
elements_text := elements_text || ', ' || elements_this;
END LOOP;
RETURN elements_text;
END;