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 添加一列。
假设我们有这个查询:
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 添加一列。