[NEWSboard IBMi Forum]
Seite 1 von 2 1 2 Letzte
  1. #1
    Registriert seit
    Dec 2013
    Beiträge
    17

    Bibliotheksliste aus .Net-Anwendung (OleDbConnection) ermitteln

    Hallo,

    ich habe folgendes Problem und hoffe, dass mir hier geholfen werden kann:

    Mittels einer C#-Anwendung verbinde ich mich mittels OleDb auf unsere AS400.
    Beim Verbindungsaufbau bestehen folgende "Standardbiblotheken"
    Bibliothek Art
    QSYS SYS
    QSYS2 SYS
    QHLPSYS SYS
    QUSRSYS SYS
    AGPL SYS
    ...

    Über ein "Start-CL" werden u.a. folgende Biblotheken zur Biblotheksliste hinzugefügt:

    Bibliothek Art = ProdUmgebungAGPL
    ...
    INTOBJ
    INTDTA
    EXTOBJ
    EXTDTA
    EXTSYS
    Über ein anderes "Start-CL" können folgende Biblotheken hinzugefügt werden:

    Biblothek Art = DevUmgebung
    AGPL
    ...
    TESTOBJ
    TESTDTA

    Welches Start-CL ausgeführt wird, lässt sich zu Beginn des Programms dynamisch über eine ComboBox auswählen. (es gibt aktuell vier unterschiedliche)
    In den Biblotheken INTDTA und TESTDTA liegen jeweils die gleichen Datenbanken, können aber aufgrund des Programmstands unter Umständen unterschiedliche Spalten beinhalten.

    Nun versuche ich herauszufinden, welche Spalten mir in meiner ausgewählten Arbeitsumgebung zur Verfügung stehen.



    • Ein "DSPLIBL" lässt sich meines Wissens nach nicht in eine Datei ausgeben
    • mit "GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new Object... " erhalte ich alle Spalten, die aus der Prod- sowie Dev-Umgebung, und nicht die aus *LIBL.
    • Dito "select * from qsys2.columns"

  2. #2
    Registriert seit
    Aug 2001
    Beiträge
    2.869
    Die Bibliotheksliste kann über den CL-Befehl RTVJOBA ermittelt werden (und zwar die SYSLIBL, CURLIB, sowie die USRLIBL.

    Wenn Du allerdings wissen möchtest in welcher Bibliothek eine bestimmte Datei, die Du gerade bearbeiten willst steht, kannst Du dies über das API QDBRTVSN (Retrieve Short Name) ermitteln. Dieses API bringt den qualifizierten System-Namen (damit also auch die Bibliothek) zurück. Mit diesen Informationen kannst Du dann auf die Catalog View SYSCOLUMNS zugreifen, um Dir die Spalten-Informationen zu holen:

    QDBRTVSN - Retrieve Short Name

    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

  3. #3
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Mit den Schemaabfragen liegst du dich gar nicht falsch.
    Mittels SchemaTables bekomst du die verfügbaren Tabellen und Schemata, über SchemaColumns zu jeder Tabelle die entsprechenden Spalten.
    Wo ist also dein Problem?

    Direktzugriffe auf die SYSColumns u.ä. solltest du gar nicht machen, zumal du dann ja die Schemata kennen musst.
    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

  4. #4
    Registriert seit
    Dec 2013
    Beiträge
    17
    Das Problem beschreibt sich wie folgt:
    Es gibt eine Datei "TABLE" diese liegt in "INTDTA" und "TESTDTA" ggfs. noch in "OLDDTA"
    Aufgrund des Entwicklungsstandes hat die Datei TESTDTA.TABLE mehr Spalten als die Datei INTDTA.TABLE. z.B.:

    INTDTA besteht aus den Spalten COL1, COL2 und COL3.
    TESTDTA besteht aus den Spalten COL1, COL2, COL3, COL4 und COL5.

    Die OleDbAbfrage "GetOleDbSchama(Columns..., new object{null, null, null, "TABLE"});
    bringt mir das Ergebnis:
    INTDTA.COL1
    INTDTA.COL2
    INTDTA.COL3
    TESTDTA.COL1
    TESTDTA.COL2
    TESTDTA.COL3
    TESTDTA.COL4
    TESTDTA.COL5

    Nun müsste ich in Erfahrung bringen, ob ich nun die Biblothek INTDTA oder TESTDTA "im Zugriff" habe.
    Meine Datei "TABLE" kann je nachdem drei oder aber auch fünf Spalten haben, je nachdem wo ich mich befinde.

    Ergebnis soll sein, dass ich innerhalb meiner Anwendung die Spalten in ein DateGridView einlese und anschließend die DataGridViewHeader gegen die dazugehörigen Beschreibungen tausche.

  5. #5
    Registriert seit
    Aug 2001
    Beiträge
    2.869
    Zitat Zitat von Ranger Beitrag anzeigen
    Nun müsste ich in Erfahrung bringen, ob ich nun die Biblothek INTDTA oder TESTDTA "im Zugriff" habe.
    Dann ruf' das API QDBRTVSN (s.o.) auf. Dieses API ermittelt den qualifizierten System-Namen, also Bibliothek + DateiName. Beim Aufruf des APIs kann sowohl der lange SQL als auch der System-Name der Datei übergeben werden und *LIBL ist für die Bibliothek zulässig.
    Wird *LIBL übergeben wird die Bibliotheksliste nach dem Objekt gescannt und die Bibliothek mit dem ersten Vorkommen im qualifizierten Namen ausgegeben.

    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

  6. #6
    Registriert seit
    Dec 2013
    Beiträge
    17
    Vielen Dank für eure Tipps.
    An dieser Stelle muss ich noch sagen, dass ich bisher ohne APIs zurecht gekommen bin, deswegen bin ich mit der API "QDBRTVSN" vorerst nicht klar gekommen.
    Nach weiterem Suchen im Internet habe ich gesehen, dass APIs mittels cwbx.dll aufgerufen werden und bin dann auch auf die API "QUSRJOBI" gestoßen -> ein Aufruf hat mir die Bibliotheksliste 1:1 zurückgegeben.
    Der erste Versuch die vorgeschlagene API "QDBRTVSN" zu verwenden hat nicht funktioniert (weil ich die Parameter wahrscheinlich falsch übergeben habe)

    Aber: kann ich die APIs auch ohne cwbx.dll dafür via OleDbConnection verwenden?

  7. #7
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Wenn du die .NET-Funktion SchemaColumns für eine Tabelle aufrufst, erhälst du automatisch neben den Spaltennamen auch den Tabellen- und Schema-Namen.
    Ebenso liefert dir ja ein simpler "Select * from " genauso die Spaltennamen im Reader- oder TableObjekt.
    Bindest du ein Grid an eine DBTable werden die Spalten automatisch ermittelt.
    Wo ist also dein Problem?
    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

  8. #8
    Registriert seit
    Dec 2013
    Beiträge
    17
    Vielleicht verwende ich die falsche Funktion:

    Code:
    this.as400Connection.IDB2Connection.Open();
    DataTable dt = this.as400Connection.IDB2Connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, "TABLE", null });
    dataGridView1.DataSource = dt;
    this.as400Connection.IDB2Connection.Close();
    Bringt mir in einer Tabelle zurück:
    Schema
    Column
    INTDTA COL1
    INTDTA COL2
    INTDTA COL3
    TESTDTA COL1
    TESTDTA COL2
    TESTDTA COL3
    TESTDTA COL4
    TESTDTA COL5
    OLDDTA COL1
    OLDDTA COL2
    OLDDTA COL3

    um nur die Spaltenbezeichnungen aus der ProdUmgebung zu ermitteln müsste ich folgenden Aufruf tätigen:
    Code:
    this.as400Connection.IDB2Connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, "INTDTA", "TABLE", null });
    um nur die Spaltenbezeichnungen aus der DevUmgebung zu ermitteln müsste ich folgenden Aufruf tätigen:
    Code:
    this.as400Connection.IDB2Connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, "TESTDTA", "TABLE", null });
    da ich aber die aktuelle Bibliothek nicht weiß, habe ich auch ein Aufruf mit
    Code:
    this.as400Connection.IDB2Connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, "*LIBL", "TABLE", null });
    oder
    Code:
    this.as400Connection.IDB2Connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, "*CURLIB", "TABLE", null });
    versucht, dies bringt mir jedoch gar kein Ergebnis.

    Aktuell sehe ich für mich vier Varianten:
    1. die API-Funktionen QUSRJOBI oder QDBRTVSN in eine OleDbFunktion einbauen.
      => dies wäre mein Favorit
    2. in meiner bestehende Klasse die cwbx.dll einbinden und die APIs verwenden.
      => wobei sich hier für die Schwierigkeit ergibt, dass ich trotzdem meine Connection via OleDb aufbauen möchte und nun über eine zusätzliche cwbx-Verbindung die Informationen aus der OleDbConnection abrufen muss.
    3. in meiner bestehenden Klasse die Funktionen aus dem Start-CL nachbauen.
    4. Oder jemand von euch kennt noch einen vierten Weg.

  9. #9
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Leider ist der NetProvider von CA sehr schlecht und unvollständig implementiert, da er nicht von den IDB-Schnittstellen erbt.
    Viele automatische .NET-Funktionen können daher nicht verwendet werden.
    Besser ist es, den allgemeinen OleDB-Provider von .NET zu verwenden und von CA den IBMDASQL-Provider einzusetzen.
    Erst dann hast du die volle Unterstützung von .NET incl. des DataAdapters u.v.m.

    Wenn du dann eine Verbindung aufmachst und per Auswahl ja die LIBL setzt, liefert SchemaTables und SchemaColumns ausschließlich die Objekte, die per USRLIBL erreichbar sind.
    Alle anderen Tabellen werden automatisch ausgeschlossen.

    An Stelle deines StartCL's solltest du in der Verbindung die LIBL selber setzen.
    In der Verbindungsfolge gibst du "Data Source=System;Default Collection=Hauptlib;Library List=Lib1, Lib2, ...;" an und öffnest dann die Verbindung.

    Um alle Eigenschaften und Einstellungen einzusehen kannst du auch folgendes machen:
    Erstelle eine leere "MyConn.udl"-Datei.
    Per Doppelclick kannst du dann den Provider auswählen und im Register "Alle" die Eigenschaften pflegen.
    Die Verbindung kann auch getestet werden.

    Nach dem Speichern der Verbindung kann man diese UDL-Datei in der Verbindungsfolge des Connection-Objekts angeben "File Name=Pfad und Name der UDL".
    Wenn Kennwort und User in der UDL gespeichert sind, brauchst du nichts weiter.

    Da die OLEDB-Objekte alle von den Standard-Objekten DataTable, DataReader usw. erben, kannst du in der Anwendung ausschließlich auf diese Objekte referenzieren.
    Einzig die Verbindung muss einmalig mittels OleDbConnection aufgebaut werden und kann dann per DBConnection verwendet werden.

    API's und sonstige Geschichten sind vollkommen unnötig.

    Die UDL hat den Vorteil, dass du ja beliebige UDL's zur Auswahl anbieten kannst und ggf. über die Properties-Auflistung des Connection-Objekts die "Library List" direkt abfragen kannst.

    Durch die Namenskonvention SQL musst du ja sowieso alle SQL's qualifiziert verwenden.
    Viele Frameworks helfen da aber beim automatischen und dynamischen generieren von SQL's auch zur Laufzeit.
    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

  10. #10
    Registriert seit
    Dec 2013
    Beiträge
    17
    Durch die Namenskonvention SQL musst du ja sowieso alle SQL's qualifiziert verwenden.
    Dies wollte ich ja explizit durch die vorangestellten Biblotheken umgehen!
    Wenn ich jedes SQL qualifizieren muss, brauch ich keine modifizierte Bibliotheksliste.

    Aber so wie es mir im Augenblick scheint, bin ich der einzige mit dieser Aufgabenstellung und dann ist mein Ansatz u.U. falsch.

  11. #11
    Registriert seit
    Mar 2002
    Beiträge
    5.286
    ...zum LIBL gehört der Datenschrank und keine Datenbank!!! Da hat man eine Datenbank, die sogar referentielle Integrität sicherstellen kann und dann kommt so ein Programm daher, das dann der Datenbank erzählt: "Schau mal in der LIBL wo Du einen Kundensatz für meinen Auftrag findest".
    Qualifizieren braucht man da garnichts, wenn man pro Datenbank (AS/400 = LIB) eine eigene Connection verwendet und für diese das Default Schema adäquat setzt! Alles andere ist Huddel ala RPG.

    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/

  12. #12
    Joe is offline [professional_User]
    Registriert seit
    Mar 2001
    Beiträge
    365
    Zitat Zitat von BenderD Beitrag anzeigen
    ...zum LIBL gehört der Datenschrank und keine Datenbank!!! Da hat man eine Datenbank, die sogar referentielle Integrität sicherstellen kann und dann kommt so ein Programm daher, das dann der Datenbank erzählt: "Schau mal in der LIBL wo Du einen Kundensatz für meinen Auftrag findest".
    Qualifizieren braucht man da garnichts, wenn man pro Datenbank (AS/400 = LIB) eine eigene Connection verwendet und für diese das Default Schema adäquat setzt! Alles andere ist Huddel ala RPG.

    D*B
    Wobei RPG auch ohne "Huddel" geht...

    Gruß Joe

Similar Threads

  1. Zeitdauer ermitteln in RPG
    By sepp in forum IBM i Hauptforum
    Antworten: 2
    Letzter Beitrag: 09-07-02, 17:09
  2. STRPCCMD blockiert Anwendung
    By peter-venkman in forum IBM i Hauptforum
    Antworten: 2
    Letzter Beitrag: 09-07-02, 09:55
  3. XML-Anwendung
    By Case Consult in forum Archiv NEWSboard Events
    Antworten: 0
    Letzter Beitrag: 18-03-02, 12:41
  4. Web-Anwendung - Zugriff auf AS400-Daten?
    By mott in forum IBM i Hauptforum
    Antworten: 2
    Letzter Beitrag: 27-02-02, 16:13
  5. Ankündigung eBusiness-Anwendung skyva 3.0
    By W.Steiner in forum Archiv NEWSblibs
    Antworten: 0
    Letzter Beitrag: 31-05-01, 12:18

Berechtigungen

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