2016-12-16 4 views
1

Nehmen wir an, wir haben diese Anfrage:DB2 Embedded SQL in RPGLE

SELECT T1.*, T2.* INTO :DS1, :DS2 FROM FILE1 AS T1 
LEFT JOIN FILE2 AS T2 ON T1.KEY = T2.KEY 
FETCH FIRST 1 ROW ONLY 

Alles kommt in Ordnung, wenn beide Datensätze gefunden werden. Was passiert jedoch, wenn der Datensatz FILE2 nicht vorhanden ist?

SQLCOD -305 THE NULL VALUE CANNOT BE ASSIGNED TO OUTPUT HOST VARIABLE 

Und selbst wenn der Datensatz von FILE1 gefunden wird, sind beide DS leer! Das ist ein Problem.
Ein Weg, dies zu überwinden, ist COALESCE auf jedem Feld zu verwenden, aber was ist, wenn ich Hunderte von ihnen habe ?!
Eine andere Möglichkeit besteht darin, zwei verschiedene Abfragen zu verwenden. Aber das ist hässlich, wenn ich einen Cursor haben möchte.

Gibt es einen besseren Weg?

+0

Wenn beide vorhanden sein müssen, ändern Sie Ihre LINKE VERBINDUNG mit INNER JOIN –

+0

FILE2 Datensatz ist nicht erforderlich. Aber FILE1-Datensatz wird benötigt. – LppEdd

Antwort

3

Wenn Sie Spalten haben, die NULL sein könnten, müssen Sie eine Integer-Variable übergeben, die als NULL-Indikator verwendet wird. Wenn der Wert für die Ergebnisspalte null ist, setzt SQL in der Indikatorvariablen -1.

Mit einem LINKEN JOIN könnte jede Spalte aus der rechten Tabelle NULL sein.

Die manual hat das folgende Beispiel:

EXEC SQL 
    SELECT COUNT(*), AVG(SALARY) 
    INTO :PLICNT, :PLISAL:INDNULL 
    FROM CORPDATA.EMPLOYEE 
    WHERE EDLEVEL < 18 

Beachten Sie, dass es zwischen der Null-fähiger PLISAL und INDNULL kein Komma ist.

Beim Umgang mit Datenstrukturen können Sie ein Null-Indikator-Array übergeben. So sollten Sie Code so etwas wie sein:

// xx should be the number of columns in T2 
dcl-s indArr int(5) dim(xx); 

exec sql 
    SELECT T1.*, T2.* INTO :DS1, :DS2 :indArr 
    FROM FILE1 AS T1 
    LEFT JOIN FILE2 AS T2 ON T1.KEY = T2.KEY 
    FETCH FIRST 1 ROW ONLY; 

Als FYI: gilt es als eine schlechte Idee SELECT * in Produktionscode zu verwenden. Sie sollten eine explizite Liste von Spalten haben. Auf diese Weise kann jemand später kommen und eine Spalte zu Ihrem Tisch hinzufügen, ohne Ihren Code zu brechen.

+0

Das war es! Super wie immer! Und Sie haben recht, wenn Sie einzelne Spalten verwenden, aber mit 80 Zeichen Beschränkung, Hunderte von Feldern werden ein bisschen langweilig! – LppEdd

+0

@LppEdd, es ist nicht so schwierig, eine durch Kommas getrennte Liste von Spaltennamen zu generieren. Wenn nichts anderes, können Sie eine Liste oder Spalten in einen Texteditor bekommen und die CRLF durch Komma ersetzen. – Charles