【发布时间】:2017-03-01 18:39:44
【问题描述】:
我有一个我似乎无法弄清楚的问题,想知道这是环境的限制,还是我没有想到的简单问题。
我在 AIX 中运行,在程序中使用带有嵌入式 Oracle SQL 的 Microfocus Cobol。
今天,此 SQL 正在针对整个表运行,以按设计进行生产运行。当为生产测试系统运行相同的程序时,我们不需要返回完整的结果集......我们只需要在该生产测试运行中为客户端返回的记录。
所以很容易在 SQL 中添加一条语句来限制它,如下所示:
AND OLM.SYS_TX IN ('8220,8245,8993')
如果我可以将值放入查询中,那就很好了。
问题是我们永远不知道每次运行中这些 4 位数的客户值中有多少。可以是一个,也可以是30个。在我们开始每次生产测试运行之前,我们永远不会知道。
我的解决方案是在 AIX Korn Shell 脚本中创建一个包含这些数字的文件,通过 ENVIRONMENT-NAME 变量接受它们,将它们传递到 COBOL 模块,在程序中对其进行格式化,然后在像这样的 SQL:
AND HIT.SYS_TX IN (:WS-CLIENT-NOS)
但是,我无法让 SQL 将 CLIENT NO 识别到该查询中!
例子:
Korn Shell 脚本准备一个包含以下内容的字段:
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'
位于 WORKING STORAGE 字段 - 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,'0123456789',' ')),
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 (' ') 结构中,那么我会得到 结果,所以我的结构和格式很好。
- 如果我将“”标记硬编码到光标而不是 工作存储字段我没有得到任何结果。
- 如果我将 ( ) 放在工作存储字段中而不是硬编码到 SQL 则无法编译。
- 如果我将关系运算符更改为“=”而不是“IN”并使用 相反,它会拉取结果。
- 如果我对其进行硬编码以连接许多“OR”语句,它将起作用 并拉出结果。但这对 COBOL 来说并不实用。
- 但是,如果我尝试将我正确(据称)格式化的数据行 进入那个“IN”子句是行不通的!
任何帮助或技巧将不胜感激!即使这是做不到的事情!
标记
【问题讨论】:
-
关于 cobol 的知识不多,但是 sql:你的 in 列表可能看起来像(为了表明我的观点,我减少了列表)....... where field in (8220,8396,8529 ) 或 ....... where field in ( '8220', '8396', '8529' ) but never: ....... where field in ( '8220,8396,8529' ) in 子句必须格式正确。而且 afaik in 列表仅限于 1000 个元素。所以要小心,如果你有更多,请使用连接。
-
我认为您需要将其编码为
HIT.SYS_TX IN (:WS-CLIENT-NO1, :WS-CLIENT-NO2, ..... :WS-CLIENT-NO*),目前您正在询问是否为HIT.SYS_TX = :WS-CLIENT-NOS。加载像 Bobc 这样的临时表应该可以工作。无法评论戈登的回答