我有一个问题,我似乎无法弄清楚并怀疑它是环境中的限制,还是我没有想到的简单的东西。COBOL游标在WHERE子句中使用IN运算符
我在AIX中运行,在程序中使用Microfocus Cobol和嵌入式Oracle SQL。
今天,这个SQL针对整个生产运行表运行,这是按照设计的。当为生产测试系统运行同一个程序时,我们不需要返回一整套结果......我们只需要在生产测试运行中为客户返回的记录。
所以这是很容易的添加语句转换成SQL来限制它像如下:
AND OLM.SYS_TX IN ('8220,8245,8993')
这工作就好了,如果我能得到的值(一个或多个)进入查询。
问题是我们永远不知道这些4位数的客户端值将在每次运行中有多少。可能是一个,可能是其中的一个。直到我们开始每个生产测试运行,我们才会知道。
我的解决方案是在这些数字的AIX Korn Shell脚本中创建一个文件,将它们传递到COBOL模块中,方法是通过一个ENVIRONMENT-NAME变量接受它们,在程序中格式化它们,然后使用格式化的字段在SQL中是这样的:
AND HIT.SYS_TX IN (:WS-CLIENT-NOS)
但是,我无法让SQL将SQLENT识别到该查询中!
实施例:
Korn外壳脚本准备了场与它下面的:
8220,8396,8529,8685,8499,8218,8383,8150,8778,8255,8773,8993,8299
COBOL程序接受此订单,并格式化一个新的在SQL使用。
我已经通过上面的数字圈出了我有多少非空格字符,然后我使用STRING命令来格式化在SQL中使用的新行。因此,格式化后,我有这样的:
'8220,8396,8529,8685,8499,8218,8383,8150,8778,8255,8773,8993,8299'
驻留在工作存储领域 - WS-CLIENT-NOS
而那场在以下CURSOR使用:
EXEC SQL DECLARE PRETEST_EXT_HIT_LIST_CSR CURSOR FOR
SELECT HIT.ACCOUNT_NUMBER,
HIT.SYS_TX,
HIT.PRIN_TX,
LPAD(NVL(RANK, 99999),5, 0),
NON_OPTIONAL,
LPAD(LOC.LOCATION_ID, 10, 0),
LPAD (TRIM (ITEM_ID), 10, '0'),
TO_CHAR (HIT.START_DT, 'YYYYMMDD'),
EXT_CLIENT_HIT_LIST_PK
FROM OLM_MSG_MASTER OMM,
EXT_CLIENT_HIT_LIST HIT,
OLM_LOCATIONS LOC
WHERE DECODE(TRIM(TRANSLATE(item_id,'',' ')),
NULL, 'number','contains char') = 'number'
AND LOC.OLM_LOCATIONS_PK = OMM.OLM_LOCATIONS_FK
AND OLM_MSG_MASTER_PK = ITEM_ID
AND APPLICATION_ID = 'MMSG'
AND HIT.START_DT <=
TO_DATE (:HV-PROCESS-DATE, 'MMDDYYYY')
AND (HIT.END_DT IS NULL
OR HIT.END_DT >=
TO_DATE (:HV-PROCESS-DATE, 'MMDDYYYY'))
AND HIT.SYS_TX IN (:WS-CLIENT-NOS) <============================
ORDER BY HIT.SYS_TX, HIT.PRIN_TX, HIT.ACCOUNT_NUMBER,
ITEM_ID
END-EXEC.
但查询不会返回任何结果。
- 如果我将相同的数据硬编码为IN('')结构,那么我得到 结果,所以我的结构和格式都很好。
- 如果我将''标记硬编码到光标而不是在 工作存储字段中,我不会得到任何结果。
- 如果我将()放在Working-Storage字段中,而不是硬编码到SQL中,那么它将不会编译。
- 如果我将关系运算符更改为'='而不是“IN”,并使用单个值而不是它将取得结果。
- 如果我对它进行硬编码以连接大量的“或”语句,它将工作 并拉取结果。但对于COBOL来说这是不实际的。
- 但是,如果我尝试将我的正确(据称)格式的数据行 纳入该“IN”条款,它不起作用!
任何帮助或窍门将不胜感激!即使这是无法完成的事情!
马克
没有那么多关于cobol的知识,但sql:你在列表中可能看起来像(显示我的观点,我减少了列表).......其中字段在(8220,8396,8529)或。 ......('8220','8396','8529')中的字段,但从未:.......其中('8220,8396,8529')字段必须格式化正确。并且afaik列表中的限制为1000个元素。所以要小心,如果你有更多,请使用连接。 – nabuchodonossor
我想你会需要像'HIT.SYS_TX IN(:WS-CLIENT-NO1,:WS-CLIENT-NO2,.....:WS-CLIENT-NO *)'编写代码,现在你是询问“HIT.SYS_TX =:WS-CLIENT-NOS”。加载像Bobc这样的临时表应该可行。无法对Gordons发表评论 –