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

Sql 从函数调用过程并返回结果,sql,function,db2,return,procedure,Sql,Function,Db2,Return,Procedure,是否可以从函数调用过程并将该过程的结果作为函数的结果传递 比如: 然后调用如下函数 select * from table(test())@ 看到程序的结果了吗 谢谢您的帮助。我不推荐这样的实现,尤其是对于大型结果集。 但是我们可以在DB2forLUW中做这样奇怪的事情 --#SET TERMINATOR @ -- -- "SELECT FROM CALL" example. -- Stored procedures are often defined as 'MODIFIES SQL DAT

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

比如:

然后调用如下函数

select * from table(test())@
看到程序的结果了吗


谢谢您的帮助。

我不推荐这样的实现,尤其是对于大型结果集。 但是我们可以在DB2forLUW中做这样奇怪的事情

--#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'))@

管道SQL函数可以通过pipe语句从SQL过程返回结果集,具体取决于您的Db2服务器平台,这适用于DB2forLinux/Unix/Windows。有记录在案的限制和限制。如果您是初学者,请选择一种更简单的设计,不要过于复杂。您能给我一个例子吗?您的Db2服务器操作平台Z/OS、i-series、LUW和version是什么?Windows版本10.5如前所述,有一些限制和限制,其中之一是需要11.1.3.3或更高版本,以及ORA兼容性。请看我的答案。考虑一个简单的设计。
--#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'))@