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

发布于 2024-12-06 07:20:01 字数 364 浏览 2 评论 0原文

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

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

预先感谢您的帮助和建议。

最好的问候,

--肯

I'm trying to figure out how to find the largest length of records for a field in a file on a Unix-based Unidata database in a Manage2000 (M2k) MRP system. I currently have the "Using Uniquery" and "Uniquery Command Reference" both for v7.2 and the closest that I have found is using "LIKE" and "UNLIKE", but it isn't working exactly like I was hoping.

Basically, we have an QUOTES file with a "Part_Nbr" dictionary and I need to find the length of the largest "Part_Nbr" record in the file. The dictionary field maximum length is 19 characters. In doing a random listing of records, I see some records have data length of 7 characters and some have 13 characters, but I need to find the largest data length.

Thanks in advance for your help and suggestions.

Best Regards,

--Ken

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

慈悲佛祖 2024-12-13 07:20:01

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

一个FILE(又名 SQL 语言中的 TABLE,在本例中为“QUOTES”)包含 0 个或多个 RECORDS。每条记录都由多个属性(又名字段)组成。您可以使用字典项(也可以创建派生字段)引用这些属性。

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

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

使用字典项

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

在此处输入图像描述

  • Type = 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”,无论您的帐户风格如何。

  • 评估 ->动态创建派生字段

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

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


编辑

通过多值列表的代码求解

如果您有多值(和/或子多值)属性,则需要使用子例程来确定最大单个项目的长度。幸运的是,您可以让 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 ->如果您只想在当前帐户中使用我的建议
  • GLOBAL ->如果您希望它适用于所有帐户,我的建议

如果您在“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)

这将为您提供:

在此处输入图像描述

First I will clarify some terms so that we are speaking the same language. You are appear to be using field and record interchangeably.

A FILE (aka TABLE for SQL folk, 'QUOTES' in this case) contains 0 or more RECORDS. Each record is made up of multiple ATTRIBUTES (aka FIELD). You can reference these attributes using dictionary items (which can also create derived fields)

In this case you want to find the longest length of data accessed via the Part_Nbr dictionary, correct?

Assuming this is correct, you can do it as follows

Use a dictionary Item

Step 1: Create a I-type dictionary item (derived field). Let us call it Part_Nbr_Len. You can do this at the command line using UNIENTRY DICT QUOTES Part_Nbr_Len as per the image below.

enter image description here

  • Type = I (aka Derived Field)
  • LOC = LEN(Part_Nbr) (The field is the number of 1 byte characters in the Part_Nbr field)
  • FORMAT = 5R (Right-aligned makes it treat this field as a number for sorting purposes)
  • SM = S (This field is a single value)

Step 2: List the file in descending order by Part_Nbr_Len and optionally as I have done, also list the actual Part_Nbr field. You do this by the following command.

LIST QUOTES BY.DSND Part_Nbr_Len Part_Nbr_Len Part_Nbr

enter image description here


Temporary command-line hack

Alternatively, if you don't want something permanent, you could do a bit of a hack at the command line:

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

enter image description here

Okay, let's break it down:

  • list -> May or may not be important that this is lowercase. This enables you to use 'EVAL' regardless of your account flavor.

  • EVAL -> Make a derived field on the fly

  • 10000+LEN(Part_Nbr) -> Sorting of derived field is done by ASCII order. This means 9 would be listed before 15 when sorting by descending order. The + 10000 is a hack that means ASCII order will be the same as numeric order for numbers between 0 and 9999 which should cover the possible range in your case

  • EVAL "LEN(Part_Nbr)" -> Display the actual field length for you.


EDIT

Solve via code for MultiValued lists

If you have a MultiValued (and/or Sub-MultiValued) attribute, you will be required to use a subroutine to determine the length of the largest individual item. Fortunately, you can have a I-type dictionary item call a subroutine.

The first step will be to write, compile and catalog a simple UniBASIC subroutine to do the processing for you:

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

To compile a program it must be in a DIR type file. As an example, if you have the code in the 'BP' file, you can compile it with this command:

BASIC BP SR.MV.MAXLEN

How you catalog it depends upon your needs. Their are 3 methods:

  • DIRECT
  • LOCAL -> My suggestion if you only want it in the current account
  • GLOBAL -> My suggestion if you want it to work across all accounts

If you have the program compiled in the 'BP' file, the catalog commands for the above would be:

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

After the subroutine has been cataloged, you will need to have the LOC field (attribute 2) of the dictionary item Part_Nbr_Len (as per first part of this answer) updated to call the subroutine and pass it the field to process:

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

Which gives you:

enter image description here

白馒头 2024-12-13 07:20:01

这是一个很棒的答案。不过,随着 Unidata 的最新版本,有一种更简单、更有效的方法来检查最长的 MV 字段。

如果 DICT 项变成:

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

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

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

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

Rocket 软件独特文档

This is a fantastic answer. With more recent versions of Unidata there's a slightly easier, more efficient way to check for the longest MV field though.

If the DICT item becomes:

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

The basic program can become simpler and just find the MAXIMUM value of the multivalued list of lengths:

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

Too bad there's no '-MAXIMUMS' built in function to skip the basic program entirely! It's worth reading section 5.9 of the UniQuery docs at:

Rocket Software Uniquery Docs

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文