UniQuery - 如何在文件中查找字段的最大长度

时间:2011-09-21 15:43:25

标签: u2 unidata uniquery

我正在试图找出如何在Manage2000(M2k)MRP系统中找到基于Unix的Unidata数据库中文件中字段的最大记录长度。我目前有v7.2的“使用Uniquery”和“Uniquery命令参考”,而我发现的最接近的是使用“LIKE”和“UNLIKE”,但它的工作方式与我希望的完全不同。

基本上,我们有一个带有“Part_Nbr”字典的QUOTES文件,我需要找到文件中最大的“Part_Nbr”记录的长度。字典字段最大长度为19个字符。在做一个随机的记录列表时,我看到一些记录的数据长度为7个字符,有些记录有13个字符,但我需要找到最大的数据长度。

提前感谢您的帮助和建议。

最诚挚的问候,

- 肯

2 个答案:

答案 0 :(得分:4)

首先,我会澄清一些术语,以便我们说同一种语言。您似乎可以互换使用字段和记录。

FILE (对于SQL民谣表,在本例中为“QUOTES”)包含0个或更多 RECORDS 。每条记录由多个 ATTRIBUTES (又名FIELD)组成。您可以使用字典项(也可以创建派生字段)来引用这些属性

在这种情况下,您想要找到通过Part_Nbr字典访问的最长数据,是否正确?

假设这是正确的,您可以按照以下方式执行此操作

使用字典项

步骤1:创建I类字典项(派生字段)。我们称之为Part_Nbr_Len。您可以使用UNIENTRY DICT QUOTES Part_Nbr_Len在命令行执行此操作,如下图所示。

enter image description here

  • 类型= (又名派生字段)
  • LOC = LEN(Part_Nbr)(该字段是Part_Nbr字段中1个字节字符的数量)
  • FORMAT = 5R (右对齐使其将此字段视为用于排序目的的数字)
  • SM = S (此字段为单个值)

步骤2:按Part_Nbr_Len降序列出文件,并且可选地按照我的方式列出,也列出实际的Part_Nbr字段。您可以通过以下命令执行此操作。

LIST QUOTES BY.DSND Part_Nbr_Len Part_Nbr_Len Part_Nbr

enter image description here


临时命令行黑客

或者,如果你不想要永久性的东西,你可以在命令行上做一些黑客攻击:

list QUOTES BY.DSND EVAL "10000+LEN(Part_Nbr)" EVAL "LEN(Part_Nbr)" Part_Nbr

enter image description here

好的,让我们分解一下:

  • list - >这是小写的可能或不重要。这使您可以使用'EVAL',无论您的帐户风格如何。

  • EVAL - >即时创建派生字段

  • 10000+LEN(Part_Nbr) - >派生字段的排序由ASCII顺序完成。这意味着当按降序排序时,将在15之前列出9。 + 10000是一个hack,意味着ASCII顺序与0到9999之间的数字的数字顺序相同,这应该涵盖你案例中可能的范围

  • EVAL "LEN(Part_Nbr)" - >显示实际的字段长度。


修改

通过MultiValued列表的代码解决

如果您具有MultiValued(和/或Sub-MultiValued)属性,则需要使用子例程来确定最大单个项目的长度。幸运的是,您可以让I型字典项调用子例程。

第一步是编写,编译和编目一个简单的UniBASIC子程序,为你做处理:

SUBROUTINE SR.MV.MAXLEN(OUT.MAX.LEN, IN.DATA)

* OUT.MAX.LEN  : Returns the length of the longest MV/SMV value
* IN.ATTRIBUTE : The multivalued list to process

  OUT.MAX.LEN = 0
  IN.DATA = IN.DATA<1> ;* Sanity Check. Ensure only one attribute
  IF NOT(LEN(IN.DATA)) THEN RETURN ;* No Data to check

  LOOP
    REMOVE ELEMENT FROM IN.DATA SETTING DELIM
    IF LEN(ELEMENT) > OUT.MAX.LEN THEN OUT.MAX.LEN = LEN(ELEMENT)
  WHILE DELIM
  REPEAT

RETURN

要编译程序,它必须是DIR类型文件。例如,如果您在“BP”文件中有代码,则可以使用以下命令编译它:

BASIC BP SR.MV.MAXLEN

您如何编目取决于您的需求。他们有3种方法:

  • DIRECT
  • LOCAL - &gt;如果您只想在当前帐户中使用我的建议
  • GLOBAL - &gt;我的建议是否要让它适用于所有帐户

如果您在“BP”文件中编译了程序,则上述目录命令将为:

  • CATALOG BP SR.MV.MAXLEN DIRECT
  • CATALOG BP SR.MV.MAXLEN LOCAL
  • CATALOG BP SR.MV.MAXLEN

在子程序编目后,您需要更新字典项Part_Nbr_Len的LOC字段(属性2)(根据此答案的第一部分)以调用子程序并将其传递给字段处理:

SUBR("SR.MV.MAXLEN", Part_Nbr)

这给了你:

enter image description here

答案 1 :(得分:1)

这是一个很棒的答案。使用更新版本的Unidata,可以更轻松,更有效地检查最长的MV领域。

如果DICT项目变为:

SUBR('-LENS', Part_Nbr);SUBR('SR.MV.MAXLEN',@1)

基本程序可以变得更简单,只需找到多值长度列表的MAXIMUM值:

SUBROUTINE SR.MV.MAXLEN(OUT.MAX.LEN, IN.DATA)
    OUT.MAX.LEN=MAXIMUM(IN.DATA)
RETURN

太糟糕了,内置的'-MAXIMUMS'没有完全跳过基本程序!值得阅读UniQuery文档的第5.9节:

Rocket Software Uniquery Docs