游标执行没有结果(db2)

时间:2014-05-27 15:23:04

标签: stored-procedures db2 database-cursor

我无法从光标中检索正确的结果。我没有经常使用游标,并且会欣赏正确方向上的一点。我需要这个游标来返回产生多行的select语句的结果。我的db2存储过程的调用语句是

CALL schema.stored_procedure ('in_category', 'in_BUSINESS_NAME', 'ALL');

in_Business_name之后的最后一个参数是项目名称。当声明'ALL'时,它应该产生包含多行的所有项目。当声明特定项目名称时,该过程将生成一行作为示例:

CALL schema.stored_procedure ('CATEGORY_1', 'BUSINESS_1', 'PROJECT_1');

我已经放入支票,它看起来是接收'in_category'和'in_BUSINESS_name'的值,但不是项目名称。这是我的光标:

DECLARE CURS1 CURSOR FOR
SELECT DP.dim_project_id
   ,DP.PROJECT_NAME
   ,DP.TITLE
   ,DP.LONG_TITLE
   ,DP.POINT
   ,DP.FIELD_SHORT
   ,DP.FIELD
   ,DM.BUSINESS_id
   ,DM.BUSINESS_NAME 
   ,'CATEGORY_1' 
   ,0.0 AS CAPABILITY
   ,SCHEMA.BUCKET_A(in_BUSINESS_NAME,a.project_name, 19990101, 20040522) AS BUCKET_A
   ,SCHEMA.BUCKET_B(in_BUSINESS_NAME,a.project_name, 19990101, 20040522) AS BUCKET_B
   ,SCHEMA.BUCKET_C(in_BUSINESS_NAME,a.project_name, 19990101, 20040522) AS BUCKET_C
   ,0.0 AS PERCENT
   ,0.0 AS PERCENT_A
   ,0.0 AS PERCENT_B   
from (SELECT distinct DP.PROJECT_NAME   
 FROM warehouse.fact AS FAT
 INNER JOIN WAREHOUSE.DIM_JOB AS DJ on FAT.DIM_JOB_ID = DJ.DIM_JOB_ID
 INNER JOIN WAREHOUSE.DIM_PROJECT AS DP on FAT.DIM_PROJECT_ID = DP.DIM_PROJECT_ID
 INNER JOIN WAREHOUSE.DIM_A AS DA on FAT.DIM_A_ID = DA.DIM_A_ID
 WHERE FAT.ADJUSTED_DATE_END_ID >= 19990101 AND FAT.ADJUSTED_DATE_END_ID < 20040522
 AND DA.category = in_CATEGORY_NAME
 AND DJ.BUSINESS_name=  in_BUSINESS_NAME) a
 left outer join warehouse.dim_project dp on dp.PROJECT_NAME = a.PROJECT_NAME
 left outer join warehouse.dim_BUSINESS dm on dm.BUSINESS_name = in_BUSINESS_NAME
 order by dp.project_name;

OPEN CURS1; 
IF (in_PROJECT_NAME = 'ALL' AND in_CATEGORY_NAME = 'CATEGORY_1') THEN
BEGIN 
  FETCH FROM CURS1 INTO 
 v_DIM_PROJECT_ID 
 ,v_PROJECT_NAME
 ,v_SHORT_TITLE
 ,v_LONG_TITLE 
 ,v_POINT
 ,v_FIELD_SHORT 
 ,v_FIELD 
 ,v_BUSINESS_ID
 ,v_BUSINESS_NAME
 ,v_CATEGORY_NAME
 ,v_CAPABILITY_HOURS
 ,v_BUCKET_A
 ,v_BUCKET_B
 ,v_BUCKET_C
 ,v_PERC_TOTAL
 ,v_PERCENT_BUCKET_A
 ,v_PERCENT_BUCKET_B;

  END;

 CLOSE CURS1;

1 个答案:

答案 0 :(得分:0)

可以将打开的游标视为具有通过执行提取扫描的多个记录的结果集。通常,您会在一段时间内扫描结果集,并为每一行执行操作。

如果要根据给定的参数检索不同的值,则需要一个动态语句。您准备带有列的“选择”并预测您想要的内容,然后用它打开一个光标。

这是基于给定参数

的动态查询示例
ALTER MODULE LOGADMIN ADD
  PROCEDURE LOGS (
  IN LENGTH SMALLINT DEFAULT 72,
  IN QTY INT DEFAULT 100,
  IN MIN_LEVEL ANCHOR LOGDATA.LEVELS.LEVEL_ID DEFAULT NULL
  )
  LANGUAGE SQL
  SPECIFIC P_LOGS
  DYNAMIC RESULT SETS 1
  MODIFIES SQL DATA
  NOT DETERMINISTIC
  NO EXTERNAL ACTION
  PARAMETER CCSID UNICODE
 P_LOGS: BEGIN
  DECLARE STMT ANCHOR LOGGER.MESSAGE;
  DECLARE C CURSOR
    WITH RETURN TO CALLER
    FOR RS;

  SET STMT = 'SELECT TIME, MESSAGE FROM ('
    || 'SELECT SUBSTR(TIMESTAMP(L.DATE), 12, 15) AS TIME, '
    || 'SUBSTR(L.MESSAGE, 1, ' || LENGTH || ') AS MESSAGE '
    || 'FROM LOGDATA.LOGS AS L ';
  IF (MIN_LEVEL = -1) THEN
   SET STMT = STMT
     || 'WHERE L.LEVEL_ID = -1 OR L.LEVEL_ID IS NULL ';
  ELSEIF (MIN_LEVEL IS NOT NULL) THEN
   SET STMT = STMT
     || 'WHERE L.LEVEL_ID <= ' || MIN_LEVEL || ' '
     || 'AND L.LEVEL_ID >= 0 ';
  END IF;
  SET STMT = STMT
    || 'ORDER BY L.DATE DESC '
    || 'FETCH FIRST ' || QTY || ' ROWS ONLY '
    || 'WITH UR '
    || ') ORDER BY TIME'
    ;
  IF (LOGGER.GET_VALUE(LOGGER.LOG_INTERNALS) = LOGGER.VAL_TRUE) THEN
   INSERT INTO LOGDATA.LOGS (LEVEL_ID, LOGGER_ID, MESSAGE) VALUES
     (4, -1, 'Statement: ' || COALESCE(STMT,'NULL'));
   COMMIT;
  END IF;
  PREPARE RS FROM STMT;
  OPEN C;
 END P_LOGS @

此脚本取自log4db2:https://github.com/angoca/log4db2/blob/master/src/main/sql-pl/AdminBody.sql