DB2 SQL: функция соединения таблиц с рекурсивным CTE на нескольких строках (разделенные строки)

На IBM DB2 V10 я создал следующую функцию. Эта функция содержит рекурсивное общее табличное выражение. Например, разбивает текстовую строку 'abc,def,ghi'в таблицу с тремя рядами 'abc','def' а также '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;

По сути, эта функция работает, как и ожидалось, для отдельных строк.

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;

Производит следующую таблицу:

SNTNC   | SPLT | WRD
--------|------|----
123,456 |    , | 123
123,456 |    , | 456

Однако, как только появится таблица с более чем одной строкой, DB2 возвращается ERROR [42997] [IBM][DB2] SQL0270N Function not supported (Reason code = ""). Это означает, что если я выполнил следующий запрос с более чем одним оператором выбора без комментариев, эта ошибка возвращается. Хотя каждая отдельная строка не выдает ошибку.

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;

В Центре знаний IBM я не смог найти причину, по которой такую табличную функцию нельзя объединить более чем в одну строку. Ошибка SQL0270N (функция не поддерживается) без кода причины также выглядит не слишком полезной.

Оператор не может быть обработан, поскольку он нарушает ограничение, указанное в следующем коде причины:

Я хотел бы присоединиться к этой функции в подзапросе или таблице с более чем одной строкой. Однако без полезного кода причины я не могу сказать, в чем может быть проблема. У кого-нибудь есть идеи, что может пойти не так, если вы присоединитесь к нескольким рядам?

0 ответов

Другие вопросы по тегам