Функция с разными возвратами DB2 - PullRequest
0 голосов
/ 25 октября 2018

Привет, у меня есть эта функция:

 CREATE or replace FUNCTION Tablereturn (SWITCHER INTEGER)
 RETURNS TABLE (Test CHAR(9),
                tester INTEGER
                )
 LANGUAGE SQL
 CONTAINS SQL
 DETERMINISTIC
 NO EXTERNAL ACTION
 BEGIN 

   DECLARE SELECT1, SELECT2 VARCHAR(1024);
   set select1 ='SELECT TEST, TESTER FROM TESTTAB';
   set select2 ='SELECT DUMMY, JAR, BRAND FROM TESTTAB';
 IF (SWITCHER = '1') THEN return select1;
 ELSEIF (SWITCHER = '2') THEN return select2;
  END IF; 
   RETURN TABLE;
   END@

Вызов будет

select TEST from TABLE(Tablereturn(1))@

или

select JAR from TABLE(Tablereturn(2))@

Проблема в том, что она не работает,Компилятор говорит, что после возврата есть неожиданный токен "SELECT1".Я хочу иметь возможность вызывать его в виде таблицы и выбирать значения по мере необходимости в вызове.Я не могу просто вызвать его как процедуру с select как return, так как мне нужно работать с select как таблицей и изменять возвращаемый результат в большем select.Могу ли я иметь EXECUTE IMMEDIATE в функции?

Есть идеи?Другой вопрос, как я могу заставить функцию возвращать разные таблицы?Select2 возвращает 3 значения, а select1 возвращает только 2.

Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Альтернативой использованию PIPE было бы что-то простое, как это

CREATE OR REPLACE FUNCTION TEST_CHOICE(P_CHOICE INT)
RETURNS TABLE (R_COL1 VARCHAR(128), R_COL2 VARCHAR(128))
RETURN
    SELECT COLNAME, TYPENAME FROM SYSCAT.COLUMNS WHERE P_CHOICE = 1
    UNION ALL 
    SELECT TABNAME, OWNER     FROM SYSCAT.TABLES WHERE P_CHOICE = 2
;
0 голосов
/ 25 октября 2018

Оператор RETURN должен быть последним оператором функции.Существует класс функций, называемых «конвейерными», в которых вы можете использовать логику «если тогда еще».Как это:

CREATE OR REPLACE FUNCTION TEST_PIPELINED(P_CHOICE INT)
RETURNS TABLE (R_COL1 VARCHAR(128), R_COL2 VARCHAR(128))
BEGIN 
  DECLARE SQLSTATE CHAR(5);
  DECLARE L_COL1 VARCHAR(128);
  DECLARE L_COL2 VARCHAR(128);
  DECLARE c1 CURSOR FOR S1;

  IF P_CHOICE=1 THEN
    PREPARE S1 FROM 'SELECT COLNAME, COLNO FROM SYSCAT.COLUMNS FETCH FIRST 10 ROWS ONLY';
  ELSE 
    PREPARE S1 FROM 'SELECT TABNAME, OWNER   FROM SYSCAT.TABLES  FETCH FIRST 10 ROWS ONLY';
  END IF;

  OPEN c1;
  L1: LOOP
    FETCH c1 INTO L_COL1, L_COL2;
    IF SQLSTATE<>'00000' THEN LEAVE L1; END IF;
    PIPE(L_COL1, L_COL2);
  END LOOP L1;
  CLOSE c1;
  RETURN;
END@
...