从函数调用过程并返回结果

时间:2018-10-25 11:14:01

标签: sql function db2 return procedure

是否可以从函数中调用过程并将该过程的结果作为函数的结果传递?

赞:

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

然后调用

之类的函数
select * from table(test())@

并查看该过程的结果吗?

谢谢您的帮助。

1 个答案:

答案 0 :(得分:2)

我不推荐这样的实现,特别是对于大型结果集。 但是我们可以在DB2 for 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'))@