DB2 / 400替代打开游标

时间:2016-01-07 17:50:18

标签: db2 ibm-midrange db2-400

我正在运行DB2 for i,V7R2 TR3。

我被告知打开游标会提供很多开销,应该尽可能避免。根据我的阅读,使用EXECUTE INTO var1 USING var2是一种替代方案,但我无法使其正常运行。我得到SQL0104 error

这是我的存储过程:

BEGIN 
DECLARE STMT1 VARCHAR ( 500 ) ;     

SET STMT1 =     'SELECT SUBSTR (''' || TRIM(ITEM) || ''' , ( LENGTH ( TRIM ( PREFIX ) ) + 1 ) , ( 20 - LENGTH ( TRIM ( PREFIX ) ) ) ) ' ||
                'FROM   MYLIB.MYTABLE ' ||
                'WHERE  PREFIX = SUBSTR(''' || TRIM(ITEM) || ''', 0,LENGTH ( TRIM ( PREFIX ) ) + 1 ) ' ||
                'AND    SEQ1 = ' || TYPE || ' ' ||
                'ORDER BY   LENGTH ( TRIM ( PREFIX) ) DESC , TRIM (PREFIX) DESC ' ||
                'FETCH FIRST 1 ROWS ONLY ';

PREPARE S1 FROM STMT1; 
EXECUTE S1 INTO BASEITEM;

--OPEN C1 ; 
--  FETCH C1 INTO BASEITEM ; 
--CLOSE C1 ; 

IF(TRIM(BASEITEM) = '') THEN
    SET BASEITEM = ITEM;
END IF;
END  ; 

它有三个变量定义如下:

IN ITEM CHAR(20) CCSID 37 DEFAULT  ''  , 
IN TYPE INT DEFAULT  1  , 
INOUT BASEITEM CHAR(20) DEFAULT  '' 

当我EXECUTE INTO...这将无法编译时,如果我使用EXECUTE USING...它将编译,但BASEITEM最终为空,IF语句解析为真。< / p>

我已尝试按照EXECUTE文档操作,显然INTO只能用于CALLVALUES INTO语句。然后,我尝试按照VALUES INTO文档进行操作,但无法弄清楚如何使用它。

注意*:我希望最终更改连接变量以使用参数标记,但接下来我会担心这一点。

我想我应该发布正在使用的表格: 的 MYLIB.MYTABLE

Column |Prefix|SEQ1|SEQ2|
Row 1  |aaa   |   1|   3|
Row 2  |aab   |   1|   3|
Row 3  |aabd  |   2|   4|

我基本上传入一个字符串,然后从字符串中删除最长的前缀。然后我返回了新的字符串。 SEQ1只是前缀的类型(1或2),SEQ2是前缀的长度。

2 个答案:

答案 0 :(得分:5)

您收到错误,因为EXECUTE stmt INTO无法按照您的想法运作。

真正的问题是,当您不需要时,您正尝试使用动态SQL。请改用静电。

BEGIN 

  SELECT SUBSTR (TRIM(ITEM), ( LENGTH ( TRIM ( PREFIX ) ) + 1 ) , ( 20 - LENGTH ( TRIM ( PREFIX ) ) ) )
    INTO BASEITEM
    FROM   MYLIB.MYTABLE 
   WHERE  PREFIX = SUBSTR(TRIM(ITEM), 0,LENGTH ( TRIM ( PREFIX ) ) + 1 )
          AND    SEQ1 = TYPE
   ORDER BY   LENGTH ( TRIM ( PREFIX) ) DESC , TRIM (PREFIX) DESC
   FETCH FIRST 1 ROWS ONLY;

IF(TRIM(BASEITEM) = '') THEN
    SET BASEITEM = ITEM;
END IF;
END  ;

答案 1 :(得分:2)

EXECUTE只能用于DML语句,而不能用于查询,所以除了声明动态游标之外别无选择。话虽如此,没有“打开游标的开销”,只不过是以任何其他方式执行查询,因为对于任何查询,如果没有显式,仍然会隐式创建和打开游标。

游标的效率低于基于集合的操作,例如:何时,而不是像INSERT INTO table1 SELECT something FROM table2 WHERE...这样的东西,你在table2上打开一个光标,然后在一个循环中逐一将行插入table1。这种情况的低效率来自于执行单行插入(或更新)与多行更新,而不是来自光标本身,这与声明“打开游标提供了大量开销”完全不同。

因为在你的情况下你只能获取一条记录,所以这个循环与set参数不适用。