1

我试图弄清楚如何在 Manage2000 (M2k) MRP 系统中的基于 Unix 的 Unidata 数据库上的文件中查找字段的最大记录长度。我目前有 v7.2 的“使用唯一性”和“Uniquery 命令参考”,我发现最接近的是使用“LIKE”和“UNLIKE”,但它并没有像我希望的那样工作。

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

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

最好的祝福,

——肯

4

2 回答 2

4

首先,我将澄清一些术语,以便我们使用相同的语言。您似乎正在交替使用字段和记录。

一个FILE(又名 TABLE 用于 SQL 民间,在这种情况下为 'QUOTES')包含 0 个或多个RECORDS。每条记录由多个属性(又名字段)组成。您可以使用字典项(也可以创建派生字段)引用这些属性

在这种情况下,您希望找到通过 Part_Nbr 字典访问的最长数据长度,对吗?

假设这是正确的,您可以按以下方式进行

使用字典项

第 1 步:创建一个 I 型字典项(派生字段)。让我们称之为 Part_Nbr_Len。您可以按照下UNIENTRY DICT QUOTES Part_Nbr_Len图在命令行中执行此操作。

在此处输入图像描述

  • 类型 = I(又名派生字段)
  • 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

在此处输入图像描述


临时命令行 hack

或者,如果您不想要永久的东西,您可以在命令行上做一些修改:

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

在此处输入图像描述

好吧,让我们分解一下:

  • list-> 小写字母可能很重要,也可能不重要。这使您可以使用“EVAL”,而不管您的帐户风格如何。

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

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

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


编辑

通过代码解决多值列表

如果您有 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种方法:

  • 直接的
  • 本地 -> 如果您只希望在当前帐户中使用我的建议
  • GLOBAL -> 如果您希望它适用于所有帐户,我的建议

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

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

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

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

这给了你:

在此处输入图像描述

于 2011-09-21T19:50:44.880 回答
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 独特文档

于 2011-10-10T22:58:56.557 回答