1

Manage2000 (M2k) MRP システムの Unix ベースの Unidata データベースで、ファイル内のフィールドのレコードの最大長を見つける方法を見つけようとしています。私は現在、v7.2 の「Using Uniquery」と「Uniquery Command Reference」の両方を持っており、最も近いものは「LIKE」と「UNLIKE」を使用していますが、期待どおりに機能していません。

基本的に、「Part_Nbr」ディクショナリを含む QUOTES ファイルがあり、ファイル内の最大の「Part_Nbr」レコードの長さを見つける必要があります。ディクショナリ フィールドの最大長は 19 文字です。レコードをランダムにリストすると、データ長が 7 文字のレコードと 13 文字のレコードがあることがわかりますが、最大のデータ長を見つける必要があります。

あなたの助けと提案を前もって感謝します。

よろしくお願いします、

――ケン

4

2 に答える 2

4

最初に、私たちが同じ言語を話しているように、いくつかの用語を明確にします。フィールドとレコードを同じ意味で使用しているようです。

FILE (別名 SQL フォークのTABLE、この場合は 'QUOTES') には 0 個以上のRECORDSが含まれます。各レコードは、複数のATTRIBUTES (別名 FIELD) で構成されています。これらの属性は、ディクショナリ アイテムを使用して参照できます (派生フィールドも作成できます)。

この場合、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

ここに画像の説明を入力


一時的なコマンドライン ハック

別の方法として、永続的なものを望まない場合は、コマンド ラインでちょっとしたハックを行うことができます。

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 はハックであり、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つの方法です:

  • 直接
  • ローカル -> 現在のアカウントでのみ必要な場合の私の提案
  • 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 Uniquery ドキュメント

于 2011-10-10T22:58:56.557 に答える