实现"IN";SQL功能正在进行中?这是我的代码块,我想将此查询限制为5个不同的引脚号,以便进行测试。我宁愿不使用字符串";OR";如果我能避免的话。
//using the "IN" way with specific pin numbers
FOR EACH names NO-LOCK WHERE names.m-date GE 1/1/1900: //AND names.pin IN (179,198,200,201,210)
FOR EACH nacminfo NO-LOCK WHERE nacminfo.pin = names.pin:
FIND FIRST nacmtype WHERE nacmtype.contact_type_num EQ nacminfo.contact_type_num
AND nacmtype.descr MATCHES ("~*" + "email") NO-LOCK NO-ERROR.
IF AVAILABLE nacmtype THEN DO:
DISPLAY
nacmtype.type_val
nacmtype.descr.
END.
END.
END.
正如Stefan所说,您可以使用LOOKUP,但性能可能会受到影响,因为您需要将每个记录与列表进行比较。
使用一系列OR比较可以非常有效,如果列表很短并且是静态的(就像你的例子一样(,那么一点也不难做到
如果列表较长或频繁更改,或者它保存在变量中,则可以考虑在FOR EACH之外对列表进行迭代。
类似这样的东西:
define variable i as integer no-undo.
define variable j as integer no-undo.
define variable n as integer no-undo.
define variable myList as character no-undo.
myList = "179,198,200,201,210".
n = num-entries( myList ).
do j = 1 to n:
FOR EACH names NO-LOCK WHERE names.m-date GE 1/1/1900 AND names.pin = entry( j, myList ):
FOR EACH nacminfo NO-LOCK WHERE nacminfo.pin = names.pin:
FIND FIRST nacmtype NO-LOCK
WHERE nacmtype.contact_type_num EQ nacminfo.contact_type_num
AND nacmtype.descr MATCHES ("~*" + "email") NO-ERROR.
IF AVAILABLE nacmtype THEN DO:
DISPLAY
nacmtype.type_val
nacmtype.descr.
END.
END.
END.
end.
或者,最后,将列表转换为临时表。类似这样的东西:
define temp-table tt_myList no-undo
field namePIN as character
index namePIN-idx is unique primary namePIN.
.
define variable i as integer no-undo.
define variable n as integer no-undo.
define variable myList as character no-undo.
myList = "179,198,200,201,210".
/* build a TT */
n = num-entries( myList ).
do i = 1 to n:
create tt_myList.
tt_myList.namePIN = entry( i, myList ).
end.
for each tt_myList:
FOR EACH names NO-LOCK WHERE names.m-date GE 1/1/1900 AND names.pin = tt_myList.repName:
FOR EACH nacminfo NO-LOCK WHERE nacminfo.pin = names.pin:
FIND FIRST nacmtype NO-LOCK
WHERE nacmtype.contact_type_num EQ nacminfo.contact_type_num
AND nacmtype.descr MATCHES ("~*" + "email") NO-ERROR.
IF AVAILABLE nacmtype THEN DO:
DISPLAY
nacmtype.type_val
nacmtype.descr.
END.
END.
END.
end.
你可以在FOR EACH中加入TT,但这并没有什么区别,而且就我个人而言,我发现嵌套的FOR EACH语法更自然。
你真的需要第一个吗?FIND的结果中会有不止一条记录吗?
最后,MATCHES对你的表现没有任何帮助。希望WHERE子句的其他部分能够缩小结果集的范围,使其影响最小化。
注意性能,因为左侧的函数通常不能使用索引,但可以使用查找函数:
for each names
where names.m-date ge 1/1/1990
and lookup( string( names.pin ), '179,198,200,201,210' ) ) > 0
no-lock:
// do something
end.
我宁愿不使用字符串"OR";如果我能避免的话。
Stefan指出,在WHERE子句中使用函数意味着不使用任何索引。这将影响性能,可能非常严重。
研究使用动态查询来构建一个包含一堆OR names.pin = 179
短语的WHERE子句。
您需要调整where字符串的构建,以确保它使用了可用的最佳索引(这本身就是一个巨大的主题(。您可以通过LOG-MANAGER
查看使用了哪些索引-请参阅https://docs.progress.com/bundle/openedge-abl-troubleshoot-applications-122/page/Query-information-logged.html了解更多信息。
define variable pins as integet extent 5 initial [179,198,200,201,210] no-undo.
define variable loop as integer no-undo.
define variable cnt as integer no-undo.
define variable whereString as character no-undo.
define query q1 for names.
whereString = ' for each names no-lock where names.m-date GE 1/1/1900'.
cnt = extent(pins).
do loop = 1 to cnt:
whereSTring = whereSTring + substitute(' OR names.pin = &1', pins[loop]).
end.
query q1:query-prepare(whereString).
query q1:query-open().
query q1:get-first().
do while available names:
// do something with the names
query q1:get-next().
end.
finally:
query q1:query-close().
end finally.