如何动态更改每个循环的 where 条件?
How can I dynamically change the where conditions of a for each loop?
我有一个 table 的记录有两个逻辑标志,holdn 和 holdl。我想用 3 个不同的标准遍历这个 table。
任一标志为 TRUE - 我们希望看到暂停的所有内容
Flag holdl 为 TRUE - 我们只想查看出于这个原因而被搁置的项目
Flag holdn 为 TRUE - 我们只想查看由于其他原因而被搁置的项目。
我不知道如何基于此动态更改 for each 循环。到目前为止,我尝试的是根据这些条件设置变量的值,然后使用变量的内容作为 where 参数之一。这不起作用,因为 Progress 抱怨数据不匹配。变量是一个字符串,标志是合乎逻辑的,所以这确实有意义。请参阅下面的示例代码。这是更改了 table 名称的实际代码片段。 which-hold、order-from 等变量在调用此模块的不同模块中定义和设置。
DEFINE VARIABLE which-hold# AS CHARACTER FORMAT "x(30)" NO-UNDO.
CASE which-hold:
WHEN "B" THEN which-hold# = "(widget.holdn or widget.holdl)".
WHEN "L" THEN which-hold# = "widget.holdl".
WHEN "N" THEN which-hold# = "widget.holdn".
END CASE.
for each widget where which-hold# and
widget.order-no >= order-from and widget.order-no <= order-thru and
widget.line-no >= line-from and widget.line-no <= line-thru and
widget.joint-no >= joint-from and widget.joint-no <= joint-thru
no-lock:
A bunch of code to make a nice report with the retrieved records...
end.
在这里自学 Progress 程序员,他继承了一个巨大的、文档不完整的应用程序。请温柔点
你要的其实是动态查询。我会在最后讲到它,但首先我想解释一下为什么您不能尝试替换 which-hold# 变量中的字段名称:因为查询是在编译时求值的。这就是它读取的内容(假设 which-hold# 的值为 widget.holdn
FOR EACH widget where "widget-holdn" (...)
这不会评估为 TRUE 或 FALSE。那又怎样,你问?好吧,这就是这里的关键。每个条件都需要评估为真或假,所以如果你尝试
,你会更幸运
for each widget where (if widget-hold# = 'widget.holdn' then widget.holdn = true else TRUE) (...)
再次注意,如果 widget-hold# 具有我想要的值,条件将存在,否则它根本不会对此进行过滤。
所以你可以按照我展示的方式(针对你所拥有的每个条件)进行编码,它应该可以正常工作。
但是让我建议一个动态查询。
您需要:
DEFINE VARIABLE hQuery AS HANDLE NO-UNDO.
CREATE QUERY hQuery.
hQuery:SET-BUFFERS(BUFFER widget:HANDLE).
hQuery:QUERY-PREPARE('<THIS IS THE CORE>').
hQuery:QUERY-OPEN().
DO WHILE hQuery:GET-NEXT():
A bunch of code to make a nice report with the retrieved records...
END.
所以在核心中,您有一个字符串对应于您希望它看起来的每一种方式。所以它应该是例如(将它存储在一个变量中,或者 assemble 它在查询准备中,没关系):
'FOR EACH widget NO-LOCK WHERE ' +
(if which-hold = 'B' then 'widget.holdn = true and widget.holdl = true'
else if which-hold = 'L' then 'widget-holdl = true'
else /* N */ 'widget-holdn = true').
记得我说过您的查询是在编译时评估的吗?好吧,正如你所知,另一端的动态查询是在 运行 时评估的,因此请准备好仅在 运行 时才会弹出错误。我应该提到的另一件事是动态查询比静态查询慢,所以请评估并选择你的毒药:)
这应该是您所需要的。如果有帮助或有任何问题,请告诉我。
如果您不想处理句柄,也可以使用半动态方法:
define variable i as integer no-undo.
define query q for customer.
do while true:
update i.
case i:
when 0 then quit.
when 1 then open query q for each customer no-lock where custNum >= 1000.
when 2 then open query q for each customer no-lock where state = "nh".
otherwise open query q for each customer no-lock where name begins "u".
end.
do while true with frame a:
get next q.
if not available customer then leave.
display custNum name state with frame a 10 down.
down with frame a.
end.
close query q.
end.
我有一个 table 的记录有两个逻辑标志,holdn 和 holdl。我想用 3 个不同的标准遍历这个 table。
任一标志为 TRUE - 我们希望看到暂停的所有内容
Flag holdl 为 TRUE - 我们只想查看出于这个原因而被搁置的项目
Flag holdn 为 TRUE - 我们只想查看由于其他原因而被搁置的项目。
我不知道如何基于此动态更改 for each 循环。到目前为止,我尝试的是根据这些条件设置变量的值,然后使用变量的内容作为 where 参数之一。这不起作用,因为 Progress 抱怨数据不匹配。变量是一个字符串,标志是合乎逻辑的,所以这确实有意义。请参阅下面的示例代码。这是更改了 table 名称的实际代码片段。 which-hold、order-from 等变量在调用此模块的不同模块中定义和设置。
DEFINE VARIABLE which-hold# AS CHARACTER FORMAT "x(30)" NO-UNDO.
CASE which-hold:
WHEN "B" THEN which-hold# = "(widget.holdn or widget.holdl)".
WHEN "L" THEN which-hold# = "widget.holdl".
WHEN "N" THEN which-hold# = "widget.holdn".
END CASE.
for each widget where which-hold# and
widget.order-no >= order-from and widget.order-no <= order-thru and
widget.line-no >= line-from and widget.line-no <= line-thru and
widget.joint-no >= joint-from and widget.joint-no <= joint-thru
no-lock:
A bunch of code to make a nice report with the retrieved records...
end.
在这里自学 Progress 程序员,他继承了一个巨大的、文档不完整的应用程序。请温柔点
你要的其实是动态查询。我会在最后讲到它,但首先我想解释一下为什么您不能尝试替换 which-hold# 变量中的字段名称:因为查询是在编译时求值的。这就是它读取的内容(假设 which-hold# 的值为 widget.holdn FOR EACH widget where "widget-holdn" (...) 这不会评估为 TRUE 或 FALSE。那又怎样,你问?好吧,这就是这里的关键。每个条件都需要评估为真或假,所以如果你尝试
,你会更幸运for each widget where (if widget-hold# = 'widget.holdn' then widget.holdn = true else TRUE) (...)
再次注意,如果 widget-hold# 具有我想要的值,条件将存在,否则它根本不会对此进行过滤。 所以你可以按照我展示的方式(针对你所拥有的每个条件)进行编码,它应该可以正常工作。 但是让我建议一个动态查询。 您需要:
DEFINE VARIABLE hQuery AS HANDLE NO-UNDO.
CREATE QUERY hQuery.
hQuery:SET-BUFFERS(BUFFER widget:HANDLE).
hQuery:QUERY-PREPARE('<THIS IS THE CORE>').
hQuery:QUERY-OPEN().
DO WHILE hQuery:GET-NEXT():
A bunch of code to make a nice report with the retrieved records...
END.
所以在核心中,您有一个字符串对应于您希望它看起来的每一种方式。所以它应该是例如(将它存储在一个变量中,或者 assemble 它在查询准备中,没关系):
'FOR EACH widget NO-LOCK WHERE ' +
(if which-hold = 'B' then 'widget.holdn = true and widget.holdl = true'
else if which-hold = 'L' then 'widget-holdl = true'
else /* N */ 'widget-holdn = true').
记得我说过您的查询是在编译时评估的吗?好吧,正如你所知,另一端的动态查询是在 运行 时评估的,因此请准备好仅在 运行 时才会弹出错误。我应该提到的另一件事是动态查询比静态查询慢,所以请评估并选择你的毒药:)
这应该是您所需要的。如果有帮助或有任何问题,请告诉我。
如果您不想处理句柄,也可以使用半动态方法:
define variable i as integer no-undo.
define query q for customer.
do while true:
update i.
case i:
when 0 then quit.
when 1 then open query q for each customer no-lock where custNum >= 1000.
when 2 then open query q for each customer no-lock where state = "nh".
otherwise open query q for each customer no-lock where name begins "u".
end.
do while true with frame a:
get next q.
if not available customer then leave.
display custNum name state with frame a 10 down.
down with frame a.
end.
close query q.
end.