RPGLE 中嵌入了 DB2 SQL

DB2 embedded SQL in RPGLE

假设我们有这个查询:

SELECT T1.*, T2.* INTO :DS1, :DS2 FROM FILE1 AS T1
LEFT JOIN FILE2 AS T2 ON T1.KEY = T2.KEY
FETCH FIRST 1 ROW ONLY

如果找到两条记录,一切都会好起来的。但是如果 FILE2 记录不存在会怎样?

SQLCOD -305 THE NULL VALUE CANNOT BE ASSIGNED TO OUTPUT HOST VARIABLE

而且即使找到FILE1的记录,两个DS都是空的!那是个问题。
克服这个问题的一种方法是在每个字段上使用 COALESCE,但是如果我有数百个怎么办?!
另一种方法是使用两个不同的查询。但如果我想要一个光标,那就太丑了。

有没有更好的方法?

如果您有可能为 NULL 的列,则必须传入一个整数变量以用作 NULL 指示符。然后,如果结果列的值为空,SQL 将 -1 放入指示符变量中。

使用 LEFT JOIN 从右边开始的每一列 table 都可以为 NULL。

manual有如下例子:

EXEC SQL
   SELECT COUNT(*), AVG(SALARY)
   INTO :PLICNT, :PLISAL:INDNULL
   FROM CORPDATA.EMPLOYEE
   WHERE EDLEVEL < 18

请注意,可空的 PLISAL 和 INDNULL 之间没有逗号。

在处理数据结构时,可以传入一个空指针数组。所以你的代码应该是这样的:

// xx should be the number of columns in T2
dcl-s indArr  int(5) dim(xx);

exec sql
  SELECT T1.*, T2.* INTO :DS1, :DS2 :indArr
  FROM FILE1 AS T1
    LEFT JOIN FILE2 AS T2 ON T1.KEY = T2.KEY
   FETCH FIRST 1 ROW ONLY;

仅供参考:在生产代码中使用 SELECT * 被认为是个坏主意。您应该有一个明确的列列表。这样一来,稍后有人就可以在不破坏您的代码的情况下向您的 table 添加一列。