[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Feb 2001
    Beiträge
    20.241

    Mythos Select * wird nur zur Compilezeit aufgelöst

    Hallo zusammen,
    was hat die IBM da nun wieder geändert?
    Auf einem System mit V7R1 habe ich einen SQL mit "Select * from MyFile" und anschließendem "Fetch ... into : MyDs".
    Soweit so gut.
    In Vorbereitung einer Erweiterung habe ich die Tabelle um 2 Felder erweitert, das Programm aber noch nicht neu erstellt, da es im Batch regelmäßig aufgerufen wird.
    Und was soll ich euch sagen:
    Das Joblog läuft voll mit der Meldung
    "SQL0030 Anzahl der Host-Variablen geringer als die Ergebniswerte."
    und das Programm verarbeitet die Daten nicht mehr.
    Da SQL0030 nicht als Error sondern nur als Warnung ausgegeben wird, erhalte ich einen positioven SQLCODE, der allerdings nicht 100 ist.

    Soviel zum Thema: Ein Select * wird nur zur Compilezeit aufgelöst.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  2. #2
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    ... ich weiß schon, warum ich immer empfehle nur über Views zuzugreifen und eine View niemals zu ändern.
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  3. #3
    Registriert seit
    Aug 2001
    Beiträge
    2.873
    "Select * wird nur zur Compilezeit aufgelöst."
    Kannst Du bitte sagen, wo das steht?
    Soweit ich weiß, wurde der SELECT * schon immer zur Compile-Zeit aufgelöst.
    Das ist nämlich einer der Gründe warum von einem SELECT * immer abgeraten wird.

    Und wenn wir schon bei den Mythen und beim Zusammenreimen sind.
    Die Empfehlung beim Prüfen des SQLCODE lautet entweder auf 100 (nicht gefunden) oder auf < 0 (Fehler abzufragen), jedoch nicht auf SQLCODE = 0. Diese Empfehlung wird spätestens seit Release V5R1 ausgesprochen, als für einige Situationen Warnungen ausgesprochen wurden, die zuvor akzeptiert wurden.

    Hätte man sich an die Empfehlungen gehalten, hätte man jetzt beim Erweitern der Datei keine Probleme bekommen. Nicht immer ist die IBM an allem schuld.

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  4. #4
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    ... erst überlegen, dann schreiben (passiert mir manchmal auch!). Natürlich wird ein SQL Statement zur Compiletime aufgelöst - wenn es denn geht (dynamic SQL lässt grüßen) - die Frage ist doch, ob das auch zur runtime passieren kann. Was schon immer so war, ist: dass zur runtime zuweilen der Access Path neu berechnet wird, was dann alles passiert, ist undokumentiert (:= steht nirgends, was nicht heißt, dass es ein paar Schlauschwätzer geben mag, die behaupten, es besser zu wissen). Was auch unbestreitbar ist, dass IBM an ein paar Stellen mit neueren Releases restriktiver wurde, was manchem auf die Füße fällt. Unbestreitbar ist auch, dass mit den global SQL Variablen einiges an Prüfungen nicht mehr geht.

    Was lernen wir daraus: In erster Linie, wer Views nicht ändert hat wenig Probleme. In zweiter Linie, wer select * vermeidet und fetch in eine externe Datenstruktur macht, gleichzeitig die Änderung von Tabellen und Views für durchführbar hält, hat nix begriffen - denk mal darüber nach!

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  5. #5
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    "Soweit ich weiß, wurde der SELECT * schon immer zur Compile-Zeit aufgelöst.
    Das ist nämlich einer der Gründe warum von einem SELECT * immer abgeraten wird."

    Nun, das kann ich auch nicht so stehen lassen!
    Der "Select *" wird gar nicht (mehr?) zur Compilezeit aufgelöst!!!
    Entscheidend sind nämlich hier 2 ganz andere Dinge:

    1. Select .... Into ....
    2. Fetch ... Into ...

    D.h., der Compiler analysiert die Zielvariablen, generiert daraus seine SQLnnn-Variablen und Aufrufstrukturen, internes SQL-Paket usw.
    Zur Laufzeit erst wird dann der Select von der SQL-Runtime aufgelöst und der Fetch/Select Into prüft dann, ob die Zielvariablen zum Ergebnis passen.

    Beweis:
    Mach mal einen dynamischen SQL mit Statement-Cursor und Prepare und anschließendem statischen Fetch in Variablen. Dies funktioniert obwohl der SQL-Compiler den Select gar nicht kennen kann.
    Bei meinen ArdGate-Programmen passiert nämlich genau dieses. Dynamisches prepare, statisches Fetch, da klappt sogar dann ein "Into : MyDs".

    "Die Empfehlung beim Prüfen des SQLCODE lautet entweder auf 100 (nicht gefunden) oder auf < 0 (Fehler abzufragen), jedoch nicht auf SQLCODE = 0. Diese Empfehlung wird spätestens seit Release V5R1 ausgesprochen, als für einige Situationen Warnungen ausgesprochen wurden, die zuvor akzeptiert wurden."

    Und was die Abfrage des SQL-Codes nach einem Fetch angeht, so habe ich mir angewöhnt, und ich kann es nur jedem empfehlen, grundsätzlich nur Status 0 zu verarbeiten. Dies gilt ebenso bei NULL-Flags.

    Begründung:
    Zwar sind SQLCOD's > 0 und <> 100 nur Warnungen aber wer sagt denn, dass diese Warnungen zu vollständigen und richtigen Daten führen?
    Hier ist es besser, die Daten lieber nicht zu verarbeiten, ggf. Meldungen zu produzieren oder was immer man will.
    Es gibt genug PTF's die mir irgendeine SQL-Modi bringen, die ich nach Birgittas Empfehlung nie gemerkt hätte. So erhielt ich eben die Nachricht, dass eine Verarbeitung nicht läuft, konnte u.U. mit dem Kunden auch schon die eine oder andere Meldung an IBM abgeben die den Fehler dann áuch schnell beheben konnte oder den Fehler durch SQL-Anpassung beheben.
    Z.B. wurde durch den Optimizer mal die Reihenfolge von Ausführungen geändert, so dass eine Datumkonvertierung plötzlich NULL ergab, was vorher nicht passierte. Hätte ich die Daten da weiterverarbeitet wären ganz andere Probleme entstanden.

    Und warum soll für SQL anderes gelten als für native IO?
    Beim Zugriff mittels (E)-Erweiterung frage ich ja auch nur %error() ab und nicht zusätzlich die Details der SDS? Nur bei SQL ist eben die (E)-Erweiterung ständig eingeschaltet.

    Auch ein NULL-Flag -2 sollte die Verarbeitung nicht unbedingt fortsetzen, immerhin sind dann zwar Daten da, aber eben nicht vollständig (meist abgeschnitten, Ziel zu klein).
    Bei native Dezimalarithmetik gibts einen MCH wenn das Ziel zu klein ist. Wer fängt sowas wirklich immer mit Monitor ab?
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  6. #6
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    ... bei DRDA (ArdGate) ist die Sache folgendermaßen:
    Zu unterscheiden ist erst mal static SQL und dynamic SQL:
    - static SQL: beim compile wird das select statement an die Datenbank geschickt und die Datenbank hat die Gelegenheit dieses zu prüfen und (optional) ein Package zu erstellen (bei lokalem RPG ist die Teil des Programms) und eine SQLDA zurückzugeben (die dann gegen den fetch geprüft werden kann). Der Precompiler erstellt sich dann die entsprechenden Variablen zum einlesen und die entsprechenden Zuweisungen an die Hostvariablen, letzteres passiert auch für andere Hostvariablen.
    Beim automatisch erfolgenden prepare kriegt die Datenbank das SQL statement und antwortet mit einer SQLDA. Beim Open wird das Resultset erstellt. Beim fetch werden dann die Felder des Resultsets nach Reihenfolge in die Hostvariablen übertragen.
    Beim dynamischen SQL fällt der Compileschritt für die DB weg (das Statement ist nicht bekannt). Ansonsten geht das wie gehabt.

    Verglichen mit RLA wird bei SQL grundsätzlich Feldweise übertragen und zwar der Reihenfolge der Felder im Resultset nach in die Hostvariablen, wobei bei Datenstrukturen und Indicator Arrays beim Compile in die Einzelfelder aufgelöst wird.

    An diesem Mechanismus hat sich seit ewigen Zeiten (gefühlt 1870) nix geändert, auch nicht bei V7. Das funktioniert auch immer klaglos, solange man die Reihenfolge der Felder nicht verwürfelt und keine unverträglichen Änderungen an Feldtypen vornimmt. Passt irgendwas nur fast in Typ oder Anzahl, dann kommt ein SQLCODE > 100 zurück, falls die Runtime meint, sie hat das hingekriegt, wenn sie meint das kann sie nicht, kommt ein negativer SQLCODE zurück. Auch hier hat sich am Sollzustand nix geändert, ich vermute allerdings, dass es hier mit dem ganzen verwürfeln der Query Engines (welcher Trottel hat da gemeint man braucht mehrere konkurrierend) reichlich Bugs in der Implementierung zu finden sind, die je nach Release mal dies, mal jenes machen. (Das mit den Warnings hat bereits unter älteren Releses die Joblogs vermüllt, wie Mr. google offenbart)

    Nach meiner Erfahrung gibt es zwei stabile Wege damit umzugehen:
    - select Feldliste fetch into (kopierte) Feldliste
    - select * fetch into externe DS
    jeder Mix überkreuz kann zu unerwünschten Nebenwirkungen vor oder nach dem Compile führen.

    Probleme hält man sich ganz einfach vom Hals:
    - nur über Views zugreifen und eine View nie ändern (stattdessen eine zusätzliche und ab und an nicht mehr benötigte wegschmeißen)

    Selbstredend sollte man SQLCode (oder SQLSTATE) fleißig und korrekt abfragen - eine der beliebtesten Fehlerquellen.

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  7. #7
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Nun, seit irgendeinem Release macht der Compiler auch alles richtig, wenn die Tabellen zur Compile-Zeit nicht zur Verfügung standen. Im SQL-Precompiler-Spool gibts nur 00-Meldungen diesbezüglich.

    Und Select * in externe DS kann man z.Zt. auch nur für statische Views gelten lassen.

    Ein CHGPF mit Insert von Spalten statt Append gibt beim anschließenden Fetch nur Warnings wenn Konvertierungen möglich oder nicht nötig sind obwohl man komplett falsche Daten erhält, was ein Ignorieren dieser Warnungen zur Katastrophe werden lässt.
    Der Create or Replace Table macht das ja nun genauso.
    Beim Alter Table Add Field werden Felder nur am Ende hinzugefügt, mitunter also eigentlich kein Grund, beim Select * into externe DS irgendeine Warnung zu geben.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

Similar Threads

  1. SELECT INTO .....
    By alex61 in forum IBM i Hauptforum
    Antworten: 3
    Letzter Beitrag: 12-07-16, 09:23
  2. SQL / Select auf LF / Optimizer
    By harkne in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 23-10-15, 09:36
  3. select into wie fetch next
    By Robi in forum NEWSboard Programmierung
    Antworten: 10
    Letzter Beitrag: 22-05-15, 07:31
  4. DDS Select / Omit
    By KingofKning in forum NEWSboard Programmierung
    Antworten: 16
    Letzter Beitrag: 10-03-15, 16:20
  5. SQL Select
    By TARASIK in forum IBM i Hauptforum
    Antworten: 2
    Letzter Beitrag: 19-09-02, 10:59

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •