On IBM DB2 V10 I have created following function. This function contains a recursive common table expression. It splits a text string, for example 'abc,def,ghi'
, into a table with three rows 'abc'
,'def'
and 'ghi'
.
CREATE FUNCTION TOOLS.SPLIT (
TEXT VARCHAR(32704),
SPLIT VARCHAR(16) )
RETURNS TABLE (WRD VARCHAR(128))
LANGUAGE SQL
CALLED ON NULL INPUT
READS SQL DATA
DETERMINISTIC
NO EXTERNAL ACTION
RETURN
WITH SPLIT_TBL(WORD, SENTENCE, CNT) AS (
SELECT CAST(NULL AS VARCHAR(128)) WORD
,TEXT SENTENCE
,0 CNT
FROM SYSIBM.SYSDUMMY1
UNION ALL
SELECT CASE WHEN INSTR(S1.SENTENCE, SPLIT) > 0
THEN LEFT( S1.SENTENCE,
INSTR(S1.SENTENCE, SPLIT) - MIN(1, LENGTH(SPLIT)) )
ELSE S1.SENTENCE
END AS WORD
,CASE WHEN INSTR(S1.SENTENCE, SPLIT) > 0
AND LENGTH(S1.SENTENCE) > 1
THEN SUBSTR( S1.SENTENCE,
INSTR(S1.SENTENCE, SPLIT) + MAX(LENGTH(SPLIT), 1) )
ELSE CAST(NULL AS CHAR(128))
END AS SENTENCE
,CNT + 1 CNT
FROM SPLIT_TBL S1
WHERE S1.SENTENCE IS NOT NULL
AND S1.CNT < 32704 )
SELECT WORD
FROM SPLIT_TBL
WHERE WORD IS NOT NULL;
Basically, this function works as expected on single strings.
SELECT s.*, val.*
FROM TABLE (
SELECT '123,456' sntnc, ',' splt FROM SYSIBM.SYSDUMMY1
) s
LEFT JOIN TABLE (
TOOLS.SPLIT(s.sntnc, s.splt)
) val ON 1=1;
Produces following table:
SNTNC | SPLT | WRD
--------|------|----
123,456 | , | 123
123,456 | , | 456
However, as soon as there is a table with more than one row to be joined, DB2 returns ERROR [42997] [IBM][DB2] SQL0270N Function not supported (Reason code = "").
This means, if I executed following query with more than one select statement not commented out, this error is returned. Though, each single row by itself does not produce an error.
SELECT s.*, val.*
FROM TABLE (
-- SELECT CAST(NULL AS CHAR) sntnc, ',' splt FROM SYSIBM.SYSDUMMY1
-- UNION ALL
-- SELECT '' sntnc, ',' splt FROM SYSIBM.SYSDUMMY1
-- UNION ALL
-- SELECT 'AB' sntnc, CAST(NULL AS CHAR) splt FROM SYSIBM.SYSDUMMY1
-- UNION ALL
SELECT ',' sntnc, ',' splt FROM SYSIBM.SYSDUMMY1
UNION ALL
SELECT ',ABC,DEF,/' sntnc, '' splt FROM SYSIBM.SYSDUMMY1
-- UNION ALL
-- SELECT ',ABC,ADEF,/' sntnc, ',A' splt FROM SYSIBM.SYSDUMMY1
-- UNION ALL
-- SELECT '123,456,, ' sntnc, ',' splt FROM SYSIBM.SYSDUMMY1
-- UNION ALL
-- SELECT ',,,' sntnc, ',' splt FROM SYSIBM.SYSDUMMY1
) s
LEFT JOIN TABLE (
TOOLS.SPLIT(s.sntnc, s.splt)
) val ON 1=1;
On IBM Knowledge Center, I could not find a reason, why such a table function cannot be joined on more than one row. Error SQL0270N (Function not supported), without a reason code, appears not too helpful either.
The statement cannot be processed because it violates a restriction as indicated by the following reason code:
I would like to join this function on a subquery or table with more than one row. However, without a useful reason code, I cannot tell what the problem might be. Has anyone an idea what might go wrong when joining more than one row?