db2 - SQLRPGLE 中 OPEN 游标上的 SQL -302

问题

我有一个 SQLRPGLE 程序可以执行如下所示的查询:

SELECT orapdt, oraptm, orodr#, c.ccctls, orbill, b.cuslmn, b.cusvrp, orocty, orost, o.cubzip, o.cucnty, ordcty, ordst, d.cubzip, d.cucnty
FROM order
LEFT JOIN cmtctlf c ON orbill = c.cccode
LEFT JOIN custmast b ON orbill = b.cucode
LEFT JOIN custmast o ON orldat = o.cucode
LEFT JOIN custmast d ON orcons = d.cucode
WHERE
    orstat != 'C' AND
    orbill IN ('ABCDE', 'VWXYZ', 'JKFRTE') AND
    orapdt BETWEEN 2012365 AND 2013362 AND
    o.cucnty = 'USA' AND 
    (o.cubzip LIKE '760%' OR o.cubzip LIKE '761%' OR o.cubzip LIKE '762%') AND
    d.cubzip = '38652' AND
    ordcty = 'NA' AND
    ordst = 'MS' AND 
    d.cucnty = 'USA'
ORDER BY orapdt, oraptm, orodr#

字段定义:

orapdt      7  0
oraptm      4a
orodr#      7a
c.ccctls    6a
orbill      6a
b.cuslmn    2a
b.cusvrp    3a
orocty      4a
orost       2a
o.cubzip    5a
o.cucnty    3a
ordcty      4a
ordst       2a
d.cubzip    5a
d.cucnty    3a
c.cccode    6a
b.cucode    6a
o.cucode    6a
d.cucode    6a

我在作业日志中看到以下错误:

Field HVR0001 and value 1 not compatible. Reason 7.
Conversion error on host variable or parameter *N.

当我提示额外的消息信息时,我被告知:

The attributes of variable field HVR0001 in query record format FORMAT0001 are not compatible with the attributes of value number 1. The value is *N. The reason code is 7.
7 -- Value contains numeric data that is not valid

Host variable or parameter *N or entry 1 in a descriptor area contains a value that cannot be converted to the attributes required by the statement. Error type 6 occurred.
6 -- Numeric data that is not valid.

这些错误是通过打开游标触发的:

...
exec sql PREPARE S1 FROM :sql_stmt;
exec sql DECLARE C1 SCROLL CURSOR FOR S1;
exec sql OPEN C1;
...

我的 outq 中也有 QSQSVCDMP 文件,其中充满了转储信息。我在其中看到的唯一有用的东西是对 CPF4278 和 CPD4374 的引用

CPF4278 表示查询定义模板 &1 无效。

CPD4374 表示 字段 &1 和值 &3 不兼容。原因 &5.

不幸的是,错误消息本身并不存在,只有字符串“CPF4278”和“CPD4374”。

在我监控SQL错误代码的程序中,它们都是一样的:

SQLSTATE:  22023
SQLCODE:  -302
SQLERRMC:  <non-displayable character>*N

错误状态/代码表示"A parameter or variable value is invalid."

我试过的...

经过多次谷歌搜索后,我尝试了:

  1. 删除 ORDER BY 子句(在 OPEN 时,获取数据并 当有 ORDER BY 子句时排序)
  2. 将所有 LEFT JOIN 更改为 INNER JOIN(这样做是为了确保没有 NULL 在右侧的结果记录中)
  3. 在 WHERE 子句中添加“AND orapdt IS NOT NULL”
  4. 还有很多我忘记的事情

我在问什么......

如何找出哪个字段中有错误数据?我知道 HVR0001 无效,但是 HVR0001 代表哪个字段?我尝试以不同的顺序选择字段,但总是 HVR0001 具有无效值。

理想情况下,我希望能够打印出所有 HVR* 字段/值,以便我可以检查它们。

当我查看编译列表时,没有列出任何 HVR* 字段。列出了一些 SQL_* 字段,我可以看到 SQL_00011 用于临时保存放入 orapdt 的数据。 SQL_00011 的定义与 orapdt 完全相同(7,0 压缩)。这是我查询中唯一的数字字段...

我觉得我的问题是由文件的连接方式引起的,我的 orapdt 字段以某种方式被放入了一个无效值(可能是 NULL)。

我还认为我的问题与一个接一个地执行许多这些查询有关(每个查询的某些 WHERE 细节都会发生变化),因为我可以将其中一个失败的查询放入它自己的程序中然后运行它,它工作正常。

这是在 DB2 for i (V6R1) 上,所有涉及的文件都是使用 DDS 创建的

编辑: 这是宿主变量(数据结构)和 LIKE 语句所需的两个外部数据结构:

d eds_custmast  e ds    extname('CUSTMAST') inz
d eds_order     e ds    extname('ORDER') inz

d o               ds
d orapdt                like(ORAPDT)
d oraptm                like(ORAPTM)
d orodr#                like(ORODR#)
d orctls                like(CUCODE)
d orbill                like(ORBILL)
d orslmn                like(CUSLMN)
d orcsr                 like(CUSVRP)
d orocty                like(OROCTY)
d orost                 like(OROST)
d orozip                like(CUBZIP)
d orocntry              like(CUCNTY)
d ordcty                like(ORDCTY)
d ordst                 like(ORDST)
d ordzip                like(CUBZIP)
d ordcntry              like(CUCNTY)

// Define an array to indicate nulls...
d o1nv            s     3i 0 dim(15)

下面是实际获取数据的 fetch 语句:

dow sqlcode = *zeros;
   exec sql FETCH NEXT FROM C1 INTO :o :o1nv;

   if sqlcode = *zeros;
      // process the data.
   endif;
enddo;

exec sql CLOSE C1;

我之前没有包括这个只是因为当我打开游标而不是获取行时发生错误。 OPEN 语句不应该知道有关 o 数据结构的任何信息。

至于 WHERE 子句中的哪些变化 - 所有这些都是动态构建的(因此可以改变),除了:

orstat != 'C' AND orapdt BETWEEN 2012365 AND 2013362

最佳答案

找出真正的错误一点也不容易。我倾向于将这些语句复制到 IBM i Navigator 中,并使用 Visual Explain 来尝试了解优化器做出的决定。另一种方法是执行 STRDBG 并查看作业日志。当 STRDBG 生效时,优化器会将信息性消息放入作业日志中。但即便如此,也很难弄清楚。

在这种情况下,只有一个数字列,orapdt。在没有该列的情况下尝试查询,看看这是否是罪魁祸首。

https://stackoverflow.com/questions/16571234/

相关文章:

google-drive-api - 我如何将文件上传到我拥有具有编辑权限的共享链接的 Google

vba - 如何将 Microsoft Word 中当前选定段落的段落编号获取到 AppleScri

autoconf - Automake 要求 "Autoconf 2.65 or better"但我

chef-infra - 是否有相当于 Berkshelf 的产品,但用于 Puppet 模块?

events - Kendo multiselect,当一个项目被移除时触发一个事件

haskell - Tree(Int,Int) 在 haskell 中是什么意思?

scala - 没有用于 future 的守护线程的执行上下文

itextsharp - 使用 iTextSharp.ShowTextAligned() 添加水印

crystal-reports - 具有内置最终用户报告设计器的报告系统

qt - 平均共享 QML 行中的水平空间