Вызов процедуры из функции и возврат результата - PullRequest
0 голосов
/ 25 октября 2018

возможно ли вызвать процедуру из функции и передать результат этой процедуры как результат функции?

Как:

CREATE FUNCTION test()
return procedure
BEGIN
CALL TEST_PROC();
END@

И затем вызвать функцию как

select * from table(test())@

и посмотреть результаты процедуры?

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

1 Ответ

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

Я бы не рекомендовал такую ​​реализацию, особенно для больших наборов результатов.Но мы можем делать такие странные вещи в DB2 для LUW.

--#SET TERMINATOR @
--
-- "SELECT FROM CALL" example.
-- Stored procedures are often defined as 'MODIFIES SQL DATA'.
-- A 'MODIFIES SQL DATA' table function in DB2 can be inlined only.
-- This means - no ability to process a procedure result set directly.
-- We must wrap the CALL to some intermediate procedure constructing an XML output with data processed.
-- 

CREATE OR REPLACE PROCEDURE DESCRIBE_TABLE_XML(P_FULLTABNAME VARCHAR(256), OUT P_DOC XML)
MODIFIES SQL DATA
BEGIN 
  DECLARE SQLSTATE     CHAR(5);
  DECLARE L_NODE       XML;
  DECLARE L_COLNAME    VARCHAR(128);
  DECLARE L_TYPESCHEMA VARCHAR(128);
  DECLARE L_TYPENAME   VARCHAR(128);
  DECLARE L_LENGTH     INT;
  DECLARE L_SCALE      INT;
  DECLARE L_NULLS      CHAR(1);
  DECLARE V1           RESULT_SET_LOCATOR VARYING;

  CALL ADMIN_CMD('DESCRIBE TABLE '||P_FULLTABNAME);
  ASSOCIATE RESULT SET LOCATOR (V1) WITH PROCEDURE ADMIN_CMD;
  ALLOCATE C1 CURSOR FOR RESULT SET V1;

  SET P_DOC=XMLELEMENT(NAME "DOC");
  L1: LOOP
    FETCH C1 INTO L_COLNAME, L_TYPESCHEMA, L_TYPENAME, L_LENGTH, L_SCALE, L_NULLS;
    IF SQLSTATE<>'00000' THEN LEAVE L1; END IF;
    SET L_NODE=XMLELEMENT(NAME "NODE"
    , XMLELEMENT(NAME "COLNAME", L_COLNAME)
    , XMLELEMENT(NAME "TYPESCHEMA", L_TYPESCHEMA)
    , XMLELEMENT(NAME "TYPENAME", L_TYPENAME)
    , XMLELEMENT(NAME "LENGTH", L_LENGTH)
    , XMLELEMENT(NAME "SCALE", L_SCALE)
    , XMLELEMENT(NAME "NULLS", L_NULLS)
    );
    SET P_DOC=XMLQUERY(
      'transform copy $mydoc := $doc modify do insert $node as last into $mydoc return $mydoc'
      passing P_DOC as "doc", L_NODE as "node"
    );
  END LOOP L1;
  CLOSE c1;
END@

CREATE OR REPLACE FUNCTION DESCRIBE_TABLE_T(P_FULLTABNAME VARCHAR(256))
RETURNS TABLE (
  COLNAME    VARCHAR(128)
, TYPESCHEMA VARCHAR(128)
, TYPENAME   VARCHAR(128)
, LENGTH     INT
, SCALE      INT
, NULLS      CHAR(1)
)
MODIFIES SQL DATA
BEGIN ATOMIC
  DECLARE L_DOC XML;

  CALL DESCRIBE_TABLE_XML(P_FULLTABNAME, L_DOC);
  RETURN
  SELECT *
  FROM XMLTABLE ('$D/NODE' PASSING L_DOC AS "D" COLUMNS 
    COLNAME    VARCHAR(128) PATH 'COLNAME'
  , TYPESCHEMA VARCHAR(128) PATH 'TYPESCHEMA'
  , TYPENAME   VARCHAR(128) PATH 'TYPENAME'
  , LENGTH     INT          PATH 'LENGTH'
  , SCALE      INT          PATH 'SCALE'
  , NULLS      CHAR(1)      PATH 'NULLS'
  );
END@

SELECT * FROM TABLE(DESCRIBE_TABLE_T('SYSIBM.SYSTABLES'))@
SELECT * FROM TABLE(DESCRIBE_TABLE_T('SYSIBM.SYSCOLUMNS'))@
...