PDA

View Full Version : Subselect/View



Monika
08-02-05, 12:12
Hallo,
bin angehende Informatikkauffrau und habe kaum Erfahrung mit der AS/400.
Greife aus VBA(EXCEL 2000) auf die DB via ADO zu. Z.Zt. mit folgendem SelectBefehl:

sqlString = "Select AA.aa, BB.bb, BB.gg, CC.cc, DD.dd, (BB.ee + BB.aa - BB.dd) as BAddiert, (BB.ff + BB.gg) as BBAddiert
from {oj Datenbank.Library1.AA AA inner join Library1.BB BB on AA.ww = BB.xx
left outer join Library2.CC CC on BB.xx = CC.yy
left outer join Library2.DD DD on AA.ww = DD.zz}
where ((BB.bb = '320001') and ((BB.gg = 'AD') or (BB.gg= 'EG') or (BB.gg = 'LH') or (BB.gg = 'EB) or (BB.gg = 'KU')))"

Das Ergebnis ist eine Excel-Tabelle, deren relevanter Tabellenbereich ich benenne (Bsp: "Markierung") und als Datenbank in der Systemsteuerung angebe.
Anschließend greife ich mit folgendem Select auf das Ergebnis zu (z.Zt. DAO):

Abfrage.Sql = "Select aa, bb, cc, dd, Count(gg) as Anzahl, SUM(BAddiert) as SumBAddiert, SUM(BBAddiert) as SumBBAddiert from Markierung group by aa,
bb, cc, dd;"

Beides funktioniert; Nun meine Frage: ich möchte gerne beide Abfragen verbinden, entweder als Subselect oder indem ich die 1.Abfrage als View erstelle, auf den ich mit der 2.Abfrage zugreifen kann.

1.Problem: Kenne die Syntax zur View-Erstellung auf der AS/400 nicht (Ist mir schon aufgefallen, daß hier alles etwas anders ist.....)

2.Problem: Der Versuch einer Abfrage auf eine Abfrage funktioniert nicht; auch mit * nicht:

sqlString = "Select * from (Select AA.aa, BB.bb, BB.gg, CC.cc, DD.dd, (BB.ee + BB.aa - BB.dd) as BAddiert, (BB.ff + BB.gg) as BBAddiert from {oj Datenbank.Library1.AA AA inner join Library1.BB BB on AA.ww = BB.xx left outer join Library2.CC CC on BB.xx = CC.yy left outer join Library2.DD DD on AA.ww = DD.zz}
where ((BB.bb = '320001') and ((BB.gg = 'AD') or (BB.gg= 'EG') or (BB.gg = 'LH') or (BB.gg = 'EB) or (BB.gg = 'KU')))"

Könnte mir jemand ein Beispiel geben? Wäre echt froh!!
Danke Moni

Fuerchau
08-02-05, 12:43
Alles eine Frage des Releases:
Select ... from (Select...) gibts erst ab V5 !
Falls du V5 hast:

"{" und "}" ist keine Syntax von SQL, ersetze es durch "(" und ")" !

Eine View wird mittels
create view mylib.myview as
select ...

wobei du die Where-Bedingung weglassen kannst um später per Where auf die View abzufragen (die Felder müssen dann allerdings in der View vorhanden sein).

Auf der AS ist nichts anders, sondern ausschließlich SQL92-Norm.
Zum erstellen der View musst du ggf. in der DSN-Konfig die Journalisierung abschalten (Commit=*NONE).

Monika
08-02-05, 15:48
Hallo,

erstmal vielen, vielen Dank!
Konnte View erstellen, habe die geschweiften Klammen und oj benutzt, da MSQUery diese auch benutzt (wäre selbst nicht darauf gekommen), ging aber vorher nicht mit "normalen" Klammern.

Mein View:
sqlString = "create view Library1.v_BB as select bb as vbb, gg as vgg, (BB.ee + BB.aa - BB.dd) as BAddiert, (BB.ff + BB.gg) as BBAddiert
from {oj Datenbank.Library1.BB} where ((gg = 'AD') or (gg= 'EG') or (gg = 'LH') or (gg = 'EB) or (gg = 'KU'))"

(Habe bereits where in view benutzt, da nur diese Felder der Tabelle benötigt werden)

Nun wollte ich den View in eine Abfrage einbinden, was nur funktioniert, wenn ich NICHT gruppiere!

Folgende Abfrage ohne Aggregatfunktionen/Gruppierung ist ok:
sqlString = "Select AA.aa, v_BB.vbb, BB.vgg, CC.cc, DD.dd, BAddiert, BBAddiert from {oj Datenbank.Library1.AA AA inner join Library1.v_BB v_BB on AA.ww = v_BB.xx left outer join Library2.CC CC on v_BB.xx = CC.yy left outer join Library2.DD DD on AA.ww = DD.zz} "

Abfrage mit Aggregatfunktionen/Gruppierung:
sqlString = "Select AA.aa, v_BB.vbb, Count(vgg) as Anzahl, CC.cc, DD.dd, Sum(BAddiert) as SumBAddiert, Sum(BBAddiert) as SumBBAddiert from {oj Datenbank.Library1.AA AA inner join Library1.v_BB v_BB on AA.ww = v_BB.xx left outer join Library2.CC CC on v_BB.xx = CC.yy left outer join Library2.DD DD on AA.ww = DD.zz} group by AA.aa, v_BB.vbb, CC.cc, DD.dd"

Sobald ich gruppiere bekomme ich eine Fehlermeldung :
"SQL0666 Estimated query processing time 65 exceeds limit 30"

Wobei die processing time je nach Filtersetzung höher sein kann. Was ist das und wo kann ich das limit evtl. erhöhen?

(Und was hat es mit der Journalisierung auf sich? Musste bis jetzt nichts ändern)

BenderD
08-02-05, 16:18
Hallo,

das mit dem Query Time Limit, das ist eine Schätzung des sogenannten Query Optimizers. Ursache ist wohl ein fehlender Index über die Gruppierungs Kriterien, den sollte man mit CREATE INDEX ganz normal anlegen, dann ist das wohl weg. Den Timeout kann man auch einstellen (vermute mal an den DSN Einstellungen, aber da ist Baldur sicher der Experte, so oder so wäre das kurieren an den Symptomen und nicht Beseitigung der Ursache.
Journalisierung, das ist auf der AS400 das, was man woanders zuweilen Database Log nennt und das wird benötigt für Commit Steuerung. Bei den richtigen AS400 Hardlinern ist dieses Feature aber seltsamerweise suspekt, sodass darauf meist verzichtet wird (werden muss). Der einst modernste Datenbankrechner (immer noch aktuell) wird Mehrheitlich von der konservativsten Clientel benutzt.

mfg

Dieter Bender


Hallo,

erstmal vielen, vielen Dank!
Konnte View erstellen, habe die geschweiften Klammen und oj benutzt, da MSQUery diese auch benutzt (wäre selbst nicht darauf gekommen), ging aber vorher nicht mit "normalen" Klammern.

Mein View:
sqlString = "create view Library1.v_BB as select bb as vbb, gg as vgg, (BB.ee + BB.aa - BB.dd) as BAddiert, (BB.ff + BB.gg) as BBAddiert
from {oj Datenbank.Library1.BB} where ((gg = 'AD') or (gg= 'EG') or (gg = 'LH') or (gg = 'EB) or (gg = 'KU'))"

(Habe bereits where in view benutzt, da nur diese Felder der Tabelle benötigt werden)

Nun wollte ich den View in eine Abfrage einbinden, was nur funktioniert, wenn ich NICHT gruppiere!

Folgende Abfrage ohne Aggregatfunktionen/Gruppierung ist ok:
sqlString = "Select AA.aa, v_BB.vbb, BB.vgg, CC.cc, DD.dd, BAddiert, BBAddiert from {oj Datenbank.Library1.AA AA inner join Library1.v_BB v_BB on AA.ww = v_BB.xx left outer join Library2.CC CC on v_BB.xx = CC.yy left outer join Library2.DD DD on AA.ww = DD.zz} "

Abfrage mit Aggregatfunktionen/Gruppierung:
sqlString = "Select AA.aa, v_BB.vbb, Count(vgg) as Anzahl, CC.cc, DD.dd, Sum(BAddiert) as SumBAddiert, Sum(BBAddiert) as SumBBAddiert from {oj Datenbank.Library1.AA AA inner join Library1.v_BB v_BB on AA.ww = v_BB.xx left outer join Library2.CC CC on v_BB.xx = CC.yy left outer join Library2.DD DD on AA.ww = DD.zz} group by AA.aa, v_BB.vbb, CC.cc, DD.dd"

Sobald ich gruppiere bekomme ich eine Fehlermeldung :
"SQL0666 Estimated query processing time 65 exceeds limit 30"

Wobei die processing time je nach Filtersetzung höher sein kann. Was ist das und wo kann ich das limit evtl. erhöhen?

(Und was hat es mit der Journalisierung auf sich? Musste bis jetzt nichts ändern)

Fuerchau
08-02-05, 17:10
Bei MS-Query kann man in den Eigenschaften (irgendwo) die maximale Abfragedauer einstellen. Eine Einstellung bei der DSN gibt es leider nicht.
Beim ADO ist das die Eigenschaft CommandTimeout des Commandobjekts, entsprechend der QueryTimeout beim DAO/RDO-Modell.

Eine Einstellung des QRYTIMLMT auf der AS wird bei ODBC vollständig ignoriert.

Ggf. funktioniert es (ab V5R2) die Abfrageoptionsdatei (in der DSN) anzugeben udn dort den entsprechenden Wert zu setzen (aber zu kompliziert).

Ich muss Dieter insofern recht geben, dass mann auf den Basis-Dateien zusätzliche Indexe benötigt um zu optimieren.
Indexe sollten über die Where-Felder bzw. Group-Felder vorhanden sein. Dann läuft der Query auch schneller.