Zuordnungskompatibilität in EGL

Die Regeln für die Zuordnungskompatibilität gelten in allen folgenden Situationen:
In folgenden Fällen gelten unterschiedliche Regeln:

Weitere Informationen über diese Fälle, einschließlich der Zuordnung einer Verweisvariablen zu einer Wertvariablen (und umgekehrt), finden Sie in Referenzkompatibilität in EGL.

In den folgenden Tabellen geben die Typen in der Spalte ganz links die linke Seite (d. h. das Ziel) der Zuordnungsanweisung an und alle anderen Spalten geben die rechte Seite (d. h. die Quelle) an. Der Buchstabe Y gibt kompatible Typen an. Wenn keine Angabe vorhanden ist, bedeutet dies, dass die Typen nicht kompatibel sind. Eine Zahl verweist auf Anmerkungen, die Sie nach der dritten Tabelle finden. Dort wird beschrieben, unter welchen Bedingungen die Typen kompatibel sind.

Die erste Tabelle behandelt Texttypen als Quelle der Zuordnung.

Tabelle 1. Zuordnungskompatibilität: Texttypen
Ziel Quelle
  CHAR MBCHAR STRING, UNICODE DBCHAR
CHAR Y Y Y  
MBCHAR Y Y Y  
STRING, UNICODE Y Y Y Y
DBCHAR     Y Y
BIN 1 1 1  
INT, BIGINT, SMALLINT 1 1 1  
DECIMAL 1 1 1  
NUM 1 1 1  
NUMBER 1 1 1  
FLOAT, SMALLFLOAT 1 1 1  
MONEY 1 1 1  
NUMC 1 1 1  
PACF 1 1 1  
DATE 2 2 2  
INTERVAL (Monate) 2 2 2  
INTERVAL (Sekunden) 2 2 2  
TIME 2 2 2  
TIMESTAMP 2 2 2  
HEX Y   Y  
BOOLEAN        

Die zweite Tabelle behandelt numerische Typen als Quelle der Zuordnung.

Tabelle 2. Zuordnungskompatibilität: numerische Typen
Ziel Quelle
  BIN

INT,
BIGINT, SMALL-
INT

DECI-
MAL

NUM

NUM-
BER

FLOAT,
SMALL-
FLOAT

MONEY NUMC PACF
CHAR Y Y Y Y Y Y 3 Y Y
MBCHAR Y Y Y Y Y Y 3 Y Y
STRING 4 4 4 4 4 4 3, 4 4 4
UNICODE Y Y Y Y Y Y 3 Y Y
DBCHAR Y Y Y Y Y Y Y Y Y
BIN Y Y Y Y Y Y Y Y Y
INT, BIGINT, SMALLINT Y Y Y Y Y Y Y Y Y
DECIMAL Y Y Y Y Y Y Y Y Y
NUM Y Y Y Y Y Y Y Y Y
NUMBER Y Y Y Y Y Y Y Y Y

FLOAT,
SMALL-
FLOAT

Y Y Y Y Y Y Y Y Y
MONEY Y Y Y Y Y Y Y Y Y
NUMC Y Y Y Y Y Y Y Y Y
PACF Y Y Y Y Y Y Y Y Y
DATE 5 5 5 5 5 5 5 5 5
INTERVAL (Monate) 6 6 6 6 6 6 6 6 6
INTERVAL (Sekunden) 6 6 6 6 6 6 6 6 6
TIME                  
TIMESTAMP                  
HEX           7      
BOOLEAN 8 8 8 8 8 8 8 8 8

Die dritte Tabelle behandelt Datums-/Zeittypen, hexadezimale und boolesche Typen als Quelle der Zuordnung.

Tabelle 3. Zuordnungskompatibilität: andere Typen
Ziel Quelle
  DATE INTERVAL (Monate) INTERVAL (Sekunden) TIME

TIME-
STAMP

HEX BOOLEAN
CHAR 9 9 9 9 9 Y  
MBCHAR 9 9 9 9 9    
STRING, UNICODE 9 9 9 9 9 Y  
DBCHAR              
BIN 10 Y Y       11
INT, BIGINT, SMALLINT 10 Y Y       11
DECIMAL 10 12 12       11
NUM 10 12 12       11
NUMBER 10 12 12       11
FLOAT, SMALLFLOAT 10         Y 11
MONEY 10 12 12       11
NUMC 10 12 12       11
PACF 10 12 12       11
DATE Y       Y    
INTERVAL (Monate)   Y          
INTERVAL (Sekunden)     Y        
TIME       Y Y    
TIMESTAMP Y     Y Y    
HEX           Y  
BOOLEAN             Y
Anmerkung:
  1. Der Text muss ein Literal des empfangenden Datentyps beschreiben. Dies kann die Exponentialschreibweise, ein Vorzeichen, ein anderes Dezimalzeichen als den Punkt (abhängig von der Spracheinstellung) und das Währungssymbol (bei Zuordnung zu einem Geldbetrag) beinhalten. Beliebig viele führende und nachfolgende Leerzeichen sind möglich, nur innerhalb der Zeichenfolge sind keine Leerzeichen zulässig.
  2. Siehe Text in Datum/Uhrzeit-Typen konvertieren.
  3. Ein von der Ländereinstellung abhäniges Währungssymbol wird bei der Zuordnung automatisch am Anfang des Ziels hinzugefügt. In einem Vergleich wird das erste Zeichen eines Textwerts ignoriert, wenn es sich um ein Währungssymbol handelt. Die Zeichenfolgen "$10.20" und "10.20" sind beide identisch für eine MONEY-Variable mit dem Wert 10.20.
  4. EGL verwendet strLib.formatNumber() ohne Musterargument, wenn ein numerischer Typ in einen STRING-Wert konvertiert wird. Dies umfasst Zuordnungen und die Verkettung von Zeichenfolgen. Lesen Sie dazu formatNumber().
  5. Wenn der numerische Typ Dezimalstellen enthält, werden diese abgeschnitten. Die Zahl wird als die Anzahl der Tage seit dem 31. Dezember 1899 angenommen. Entsprechend gibt der folgende Code auf der Konsole "03/21/2006" aus:
      Function main()
        testBin BIN(9,3) = 38796.999;
        testDate DATE;
        
        StrLib.defaultDateFormat = "MM/dd/yyyy";
        testDate = testBin;
        writeStdout (testDate);
      end
  6. Dies ist nur gültig, wenn der numerische Wert keine Dezimalstellen hat. Die Zahl wird entsprechend dem Format des Intervalls interpretiert. Ein Beispiel:
    myInterval INTERVAL("yyMM") = 1208;
    Hier interpretiert EGL die Zahl 1208 als zwölf Jahre und acht Monate. Es gelten folgende Regeln:
    • Wenn die Zahl mehr Stellen enthält, als das Intervall aufnehmen kann (führende Nullen nicht gerechnet), werden die weiteren Stellen auf der rechten Seite ignoriert.
    • Wenn die Zahl weniger Stellen enthält, als das Intervall aufnehmen kann, werden führende Nullen hinzugefügt.
    • Das Vorzeichen des Intervalls wird auf das Vorzeichen der Zahl eingestellt.
    • Wenn die Zahl einen Wert angibt, der außerhalb des für ein Intervallfeld gültigen Bereichs liegt, überträgt EGL den Überschreitungsbetrag (Überschuss) auf das nächste Feld. Betrachten Sie dieses Beispiel:
      myInterval INTERVAL("yyMM") = 8216;
      EGL ordnet das Intervall 83 Jahre und 4 Monate zu. Da ein Jahr nur 12 Monate enthält, wird die "16" als vier Monate behandelt und ein weiteres Jahr zu den ursprünglich 82 Jahren addiert.
    • Wenn ein Wert von dem ganz links befindlichen Feld des Intervalls übertragen werden muss, ist dies kein Fehler. Die zusätzlichen Stellen werden einfach gelöscht. Es folgt ein weiteres Beispiel:
      myInterval INTERVAL("yyMM") = 9925;
      EGL ordnet das Intervall 1 Jahr und 1 Monat zu. 25 Monate = 2 Jahre und 1 Monat, folglich Monate = 01. Der Jahreswert ist 99, plus 2 als Übertrag aus den Monaten, ergibt 101, was auf 01 gekürzt wird.
  7. Um einen Wert zuzuordnen, der kein FLOAT-, SMALLFLOAT- oder anderer HEX-Wert ist (einschließlich Literal), setzen Sie den Wert mit dem Operator as um.
  8. Wenn die numerische Variable einen beliebigen Wert ungleich null hat (positiv oder negativ), ordnet EGL der BOOLEAN-Variable den Wert TRUE zu. Nur ein numerischer Wert 0 führt zu einem booleschen Wert FALSE.
  9. Lesen Sie dazu Datum/Zeit-Typen in Text konvertieren.
  10. Wenn Sie einen DATE-Wert einem numerischen Typ zuordnen, ist dieser Wert die Anzahl Tage seit dem 31. Dezember 1899.
  11. Wenn die boolesche Variable TRUE ist, ordnet EGL dem numerischen Typ den Wert 1 zu.
  12. Nur gültig, wenn die Zielvariable keine Dezimalstellen hat.

Runden und Abschneiden zwischen numerischen Typen

Ein Wert eines numerischen Typs (einschließlich NUMC und PACF) kann einer Variable eines beliebigen numerischen Typs und einer beliebigen Größe zugeordnet werden und EGL nimmt die Konvertierungen vor, die erforderlich sind, um den Wert im Zielformat beizubehalten.

Nicht signifikante Nullen werden nach Bedarf hinzugefügt oder abgeschnitten. (Führende Nullen im Integer-Abschnitt eines Werts sind wie die abschließenden Nullen im Bruchzahlenabschnitt eines Werts nicht signifikant.)

Wenn Sie den V6-Ausnahmemodus verwenden und vgVar.handleOverflow entsprechend einstellen, können Sie die Systemvariable sysVar.overflowIndicator verwenden, um zu testen, ob eine Zuordnung oder eine Berechnung zu einem Überlauf geführt hat. Weitere Informationen finden Sie in handleOverflow. Wenn Sie den V6-Ausnahmemodus nicht verwenden oder Überläufe nicht behandeln, bewirkt das Auftreten eines Überlaufs, dass EGL eine Laufzeitausnahmebedingung (RuntimeException) auslöst.

Bei einem Laufzeitwert von 108.314 für die Quelle resultieren die folgenden Aktionen, wenn Sie eine DECIMAL-Variable auf eine andere kopieren:
  • Wenn die Zielvariable sieben Stellen mit einer Dezimalstelle zulässt, nimmt die Zielvariable den Wert 000108.3 auf und es wird kein Überlauf erkannt. (Der Verlust der Genauigkeit eines Bruchzahlenwerts wird nicht als Überlauf angesehen.)
  • Wenn die Zielvariable vier Stellen mit zwei Dezimalstellen zulässt, wird ein Überlauf erkannt.

In einer Zuordnungsanweisung werden zusätzliche Dezimalstellen abgeschnitten, wenn die Builddeskriptoroption truncateExtraDecimals auf YES eingestellt ist (dies ist der Standardwert; weitere Informationen finden Sie im EGL Generation Guide), es sei denn, die Quelle ist ein FLOAT- oder SMALLFLOAT-Wert und das Ziel hat eine feste Anzahl Dezimalstellen. Zusätzliche Dezimalstellen werden gerundet, wenn truncateExtraDecimlas auf NO eingestellt wird oder wenn die Quelle ein FLOAT- oder SMALLFLOAT-Wert ist und das Ziel eine feste Anzahl von Dezimalstellen hat.

In Version 6 und früheren Versionen von EGL gab es die Option truncateExtraDecimals noch nicht. Deswegen wurden zusätzliche Dezimalstellen immer abgeschnitten, es sei denn, die Quelle war ein FLOAT- oder SMALLFLOAT-Wert und das Ziel hatte eine feste Anzahl von Dezimalstellen. Eine zusätzliche Regel verhinderte das Abschneiden, wenn die Quelle der Zuordnung eine der MathLib-Funktionen war. Wenn Sie diese Art des Rundens von V6 beibehalten müssen, verwenden Sie die Funktion MathLib.assign() (siehe assign()).

Auffüllung und Abschneidung nach Zeichentyp

Wenn das Ziel ein Nicht-STRING-Zeichentyp ist (einschließlich DBCHAR und HEX) und über mehr Platz verfügt, als für das Speichern eines Quellenwerts erforderlich ist, füllt EGL wie folgt Daten auf der rechten Seite auf:
  • Einzelbyteleerzeichen füllen ein Ziel des Typs CHAR oder MBCHAR auf.
  • Doppelbyteleerzeichen füllen ein Ziel des Typs DBCHAR auf.
  • Unicode-Doppelbyteleerzeichen füllen ein Ziel des Typs UNICODE auf.
  • Binäre Nullen füllen ein Ziel des Typs HEX auf. Das bedeutet (zum Beispiel), dass ein Quellenwert "0A" in einem Zweibyteziel als "0A00" statt als "000A" gespeichert wird.

EGL schneidet rechts Werte ab, wenn das Ziel eines Zeichentyps nicht genug Platz bietet, um den Quellenwert zu speichern. Es wird kein Fehler gemeldet.

Wenn das Ziel eine Zeichenfolge mit begrenzter Länge ist, gelten die folgenden Regeln:
  • Wenn die Quelle mehr Zeichen enthält, als im Ziel zulässig sind, schneidet die EGL-Laufzeitumgebung den kopierten Inhalt ab, sodass die vorgegebene Länge eingehalten wird.
  • Wenn die Quelle weniger Zeichen enthält, als im Ziel zulässig sind, füllt die EGL-Laufzeitumgebung den kopierten Inhalt bis zur Länge der Zielzeichenfolge mit Leerzeichen auf. Alle abschließenden Leerzeichen in einer Zeichenfolge mit begrenzter Länge werden aber in einem Vergleich ignoriert.
Die folgende Situation stellt einen Sonderfall dar:
  • Die Laufzeitplattform unterstützt den EBCDIC-Zeichensatz.
  • Die Zuordnungsanweisung kopiert ein Literal des Typs MBCHAR oder eine Variable des Typs MBCHAR in eine kürzere Variable des Typs MBCHAR.
  • Eine byteweise Abschneidung würde ein DBCS-Endezeichen entfernen oder ein Doppelbytezeichen teilen.

In dieser Situation schneidet EGL Zeichen nach Bedarf ab, um sicherzustellen, dass die Zielvariable eine gültige Zeichenfolge des Typs MBCHAR enthält. Anschließend werden (falls erforderlich) abschließende Einzelbyteleerzeichen hinzugefügt.

Zuordnung zu bzw. von nullfähigen Typen

Nullfähige Variablen sind zuordnungskompatibel mit Variablen, die nicht nullfähig sind, vorausgesetzt, ihre Basistypen sind zuordnungskompatibel. Wenn eine Variable, die nicht nullfähig ist, einer nullfähigen Variable zugeordnet wird, folgt die Zuordnung den Regeln, die weiter oben in diesem Abschnitt beschrieben wurden. Die Zielvariable wird in diesem Fall nie auf null eingestellt, weil die die Quellenvariable nicht null sein kann. Wenn eine nullfähige Variable einer Variablen zugeordnet wird, die nicht nullfähig ist, hängt das Verhalten von dem Typ der Daten und davon ab, ob die Quelle zu diesem Zeitpunkt null ist. Die folgenden Regeln erläutern das Verhalten:
  • Wenn die Quelle zu diesem Zeitpunkt null ist und das Ziel ist eine Zeichenvariable, wird die Zielvariable auf 'leer' eingestellt.
  • Wenn die Quelle zu diesem Zeitpunkt null ist und die Zeichenvariable ist numerisch, wird die Zielvariable auf 0 eingestellt.
  • Wenn die Quelle nicht null ist, folgt die Zuordnung den normalen Zuordnungsregeln.

Nullfähige Variablen sind nur mit anderen nullfähigen Variablen verweiskompatibel, die genau denselben Basistyp haben. Die Zuordnung folgt den Regeln, die in Referenzkompatibilität in EGL beschrieben sind.

Zuordnung zwischen Zeitmarken

Wenn Sie eine TIMESTAMP-Variable einer anderen TIMESTAMP-Variable zuordnen, gelten die folgenden Regeln:
  • Wenn der Maske der Quellenvariable übergeordnete Einträge fehlen, die von der Zielvariable benötigt werden, werden diese Zieleinträge zum Zeitpunkt der Zuordnung entsprechend der Systemzeit zugeordnet, wie das folgende Beispiel zeigt:
    •   sourceTimeStamp timestamp ("MMdd");
         targetTimeStamp timestamp ("yyyyMMdd");
        
         sourceTimeStamp = "1201";
      
        // Wenn dieser Code in 2004 ausgeführt wird, ordnet die nächste
        // Anweisung dem targetTimeStamp den Wert 20041201 zu.
         targetTimeStamp = sourceTimeStamp; 
    •   sourceTimeStamp02 timestamp ("ssff");
        targetTimeStamp02 timestamp ("mmssff");
        
         sourceTimeStamp02 = "3201";
      
        // Die nächste Zuordnung enthält die aktuelle Minutenangabe
        // zum Zeitpunkt der Ausführung der Zuordnungsanweisung.
        targetTimeStamp02 = sourceTimeStamp02;
    • Wenn der Maske der Quellenvariable untergeordnete Einträge fehlen, die von der Zielvariable benötigt werden, werden diesen Zieleinträgen die niedrigsten gültigen Werte zugeordnet, wie das folgende Beispiel zeigt:
      • sourceTimeStamp timestamp ("yyyyMM");
        targetTimeStamp timestamp ("yyyyMMdd");
        
        sourceTimeStamp = "200412";
        
        // Unabhängig vom Tag ordnet die nächste Anweisung
        // dem targetTimeStamp den Wert 20041201 zu.
        targetTimeStamp = sourceTimeStamp; 
      • sourceTimeStamp02 timestamp ("hh");
        targetTimeStamp02 timestamp ("hhmm");
        
        sourceTimeStamp02 = "11";
        
        // Unabhängig von der Minute ordnet die nächste Anweisung
        // dem targetTimeStamp02 den Wert 1100 zu.
        targetTimeStamp02 = sourceTimeStamp02;

Zuordnung zu bzw. von Feldern in Datensätzen

Sie können ein Unterstrukturfeld einem Nicht-Unterstrukturfeld zuordnen (und umgekehrt) und Sie können Werte zwischen den Unterstrukturfelder zuordnen. Angenommen, die Variablen myNum und myRecord basieren auf den folgenden Abschnitten:

  DataItem Num12
    NUM(12)
  end

  Record ExampleRecord type basicRecord
    10 topMost CHAR(4);
      20 next01 HEX(4);
      20 next02 HEX(4);
  end

Die Zuordnung eines Werts des Typs HEX zu einer Variable des Typs NUM ist nicht außerhalb der mathematischen Systemvariablen gültig; aber eine Zuordnung in dem Format myNum = topMost ist gültig, weil topMost den Typ CHAR hat. Im Allgemeinen übernehmen die Primitive-Typen der Felder in der Zuordnungsanweisung die Steuerung der Zuordnung und die Primitive-Typen untergeordneter Felder werden nicht berücksichtigt.

Der Primitive-Typ eines Unterstrukturfelds ist standardmäßig CHAR. Wenn Sie Daten zu bzw. von einem Unterstrukturfeld zuordnen und wenn Sie keinen anderen Primitive-Typ bei der Deklaration angeben, bleiben die zuvor für Felder des Typs CHAR beschriebenen Regeln während der Zuordnung gültig.

Zuordnung eines strukturierten Datensatzes

Die Zuordnung einer strukturierten Datensatzvariablen zu einer anderen entspricht dem Zuordnen eines Unterstrukturfelds des Typs CHAR zu einem anderen. Bei einer Längendifferenz werden Einzelbyteleerzeichen auf der rechten Seite zum empfangenen Wert hinzugefügt oder es werden Einzelbyteleerzeichen auf der rechten Seite vom empfangenen Wert entfernt. Bei der Zuordnung wird der Primitive-Typ untergeordneter Strukturfelder nicht berücksichtigt.

Folgende Ausnahmen gelten hierfür:
  • Der Inhalt eines Datensatzes kann einer Datensatzvariable oder einer Variable des Typs CHAR, HEX, STRING oder MBCHAR zugeordnet werden, aber nicht einer Variable eines anderen Typs.
  • Ein Datensatz kann Daten aus einer der folgenden Quellen empfangen:
    • Von einem anderen Datensatz
    • Von einem Zeichenfolgeliteral (aber nicht von einem numerischen Literal)
    • Von einer CHAR-, HEX-, STRING- oder MBCHAR-Variable (andere Typen sind nicht zulässig)

Wenn Sie eine strukturierte SQL-Datensatzvariable zu oder von einer strukturierten Datensatzvariable eines anderen Typs zuordnen, müssen Sie sicherstellen, dass der Nicht-SQL-Datensatz genug Platz für den Vier-Byte-Bereich hat, der jedem Strukturfeld vorausgeht (siehe Strukturierte Datensätze).

Zuordnung zwischen Datensätzen

Nicht strukturierte Datensatzvariablen sind nur mit anderen nicht strukturierten Datensatzvariablen mit genau demselben Typ zuordnungskompatibel.

Konsistente Ergebnisse über alle Umgebungen hinweg

Aufgrund der Abschneidung von Zwischenergebnissen können COBOL-Programme für dieselben arithmetischen Anweisungen andere Ergebnisse haben als Java™- oder Rich-UI-Programme. Verwenden Sie nur einen Binäroperator pro Anweisung, um konsistente Ergebnisse über verschiedene Umgebungen sicherzustellen. Mehrere Additions- und Subtraktionsoperatoren können gefahrlos kombiniert werden, wenn die Anzahl der für das Ergebniselement definierten Dezimalstellen größer-gleich der Anzahl der Dezimalstellen in allen Operanden ist.

Der Restwertoperator kann inkonsistente Ergebnisse hervorbringen, wenn das Ergebnis oder einer der Operanden mit Dezimalstellen größer als null definiert ist. Um einen konsistenten Restwert bei den Dezimalstellen zu erhalten, verwenden Sie den folgenden Algorithmus anstelle des Restwertoperators:
quotient = dividend / divisor;
remainder = dividend - (quotient * divisor);

Kompatibilität

Tabelle 4. Überlegungen zur Kompatibilität für Zuordnungen
Plattform Problem
COBOL-Generierung EGL kann Text nicht in SMALLFLOAT oder FLOAT konvertieren, auch wenn dies umgekehrt möglich ist.

Feedback