PDA

View Full Version : DB2_NUMBER_ROWS Falsche Anzahl von Sätzen



GUK
14-10-21, 13:57
Hallo,

ich habe folgenden Code:



exec sql prepare dynSqlStmt1 from :wkSqlStmt;
exec sql open sqlCsrRead1;
exec sql
get diagnostics :wkCount = DB2_NUMBER_ROWS;
exec sql declare sqlCsrRead1 cursor for dynSqlStmt1;


Obwohl es nur ein Satz vorhanden ist, bekomme ich immer Werte zurück die ich mir nicht erklären kann (997, 1247, ..)

Da ich den SFL-Dynamisch aufbaue und mit Pagedown die nächsten lese, weiß ich beim drucken nicht wie viele Sätze vorhanden sind.

Laut Handbuch sollte das so funktionieren.

Was ist an der Methode falsch?

Dank im Voraus

Liebe Grüße

PS: habe auch versucht den Cursor vorher zu schließen

Fuerchau
14-10-21, 14:18
Die Info ist vom Grundsatz her ein Schätzwert, da je nach Komplexität des Selects die genaue Anzahl erst beim vollständigen Lesen verfügbar ist.

Du kannst allerdings beim Select einen zusätzlichen "count(*) over() as total" hinzufügen.
Somit wird nun tatsächlich erst mal alles gelesen und du hast vom 1. bis letzten Satz die Gesamtzahl zur Verfügung.
Dies ist allerdings mit einer kleinen Perfomranceeinbuße hinzunehmen.

GUK
14-10-21, 14:24
Danke für die Info, werde ich gleich ausprobieren.

Das Statement ist gar nicht so komplex.
Das es Probleme mit Joins geben würde, war mir bewusst aber dachte wenn ich nur eine Tabelle abfrage...



SELECT ARLAG, ARTNR, ARTBZ, ARTBZ2, AREXTNR, ARDPR, ARLBS FROM
MATARTP WHERE Length(rtrim(ARTNR)) >= 8 AND ARTNR NOT IN(
'FREMD-REP ') AND ARTNR NOT LIKE ('K-%') AND UPPER(ARLAG) =
UPPER('0 ') AND ARLBS = 0 ORDER BY ARTNR

Fuerchau
14-10-21, 16:37
Da können fast keine Indizes verwendet werden, kein Wunder dass es eine Schätzung gibt.

prsbrc
15-10-21, 07:24
Ich hatte das Selbe Problem. Nach einer Suche im Internet wurde mir vorgeschlagen den Cursor als INTENSITIVE zu deklarieren, es klappt nun mit den "DB2_NUMBER_ROWS" ... inwiefern sich diese Änderung jedoch positiv oder negativ auf dein Programm auswirken könnte müsstest probieren.

GUK
15-10-21, 07:56
Danke man lernt nie aus INTENSITIVE habe ich bis dato noch nie verwendet.

B.Hauser
15-10-21, 08:04
Sollte wohl INSENSITIVE heißen?!

Hier aus der Reference was INSENSITIVE bedeutet ...
INSENSITIVE
Specifies that once the cursor is opened, it does not have sensitivity to inserts, updates, or
deletes performed by this or any other activation group. If INSENSITIVE is specified, the cursor is
read-only and a temporary result is created when the cursor is opened. In addition, the SELECT
statement cannot contain a UPDATE clause and the application must allow a copy of the data
(ALWCPYDTA(*OPTIMIZE) or ALWCPYDTA(*YES)).

Fuerchau
15-10-21, 08:25
ALWCPYDTA ist eine Compiler-Anweisung des CRTSQL.... und steht per Default auf *Optimize.
Da finde ich persönlich inzwischen "Count(*) Over()" schöner und fast ohne Performancenachteile.

prsbrc
15-10-21, 10:27
Sollte wohl INSENSITIVE heißen?!

Hier aus der Reference was INSENSITIVE bedeutet ...
INSENSITIVE
Specifies that once the cursor is opened, it does not have sensitivity to inserts, updates, or
deletes performed by this or any other activation group. If INSENSITIVE is specified, the cursor is
read-only and a temporary result is created when the cursor is opened. In addition, the SELECT
statement cannot contain a UPDATE clause and the application must allow a copy of the data
(ALWCPYDTA(*OPTIMIZE) or ALWCPYDTA(*YES)).

:-) Natürlich. Muss mir wohl einen Korrekturleser besorgen. Danke für die Richtigstellung.

Fuerchau
15-10-21, 16:33
Da brauchst du nichts bestellen, die sind doch schon da;-), und das ganz freiwillig.