Leo Elsenberg

Programmierung, Datenbanken, IT-Dienstleistungen, -Schulungen und -Nachhilfe

Tipps und Tricks

Im Laufe der Zeit werden an dieser Stelle Tipps & Tricks, die Datenbanken Microsoft Access (2003/2007/2010) und IBM DB2 (Express-C) betreffend, veröffentlicht.

Verbindung zur IBM DB2 mit DAO herstellen

Schemareferenzierung über Qualifier

Ermitteln, ob BenutzerInnen an einer IBM DB2 Umgebung angemeldet sind


Verbindung zur IBM DB2 mit DAO herstellen

Die Mehrzahl der Access ProgrammiererInnen verwendet nach wie vor das bewährte DAO zur Steuerung der Datenzugriffe. Um bei Verwendung von DAO mit ODBC verknüpften IBM DB2 Tabellen eine Verbindung zur IBM DB2 for LUW (Linux, Unix, Windows) oder IBM DB2 for z/OS herzustellen und den 'Mit Datenbank verbinden' Dialog zu umgehen, kann zu einem Trick gegriffen werden. Hierzu eignet sich die TransferTable Methode des DoCmd Objekts. Das nachfolgende Beispiel veranschaulicht die Vorgehensweise beispielhaft. "SCHEMA" muss durch einen zutreffenden Schemanamen und "UID" und "PWD" müssen durch eine zutreffende Benutzerkennung und ein zutreffendes Passwort ersetzt werden. Des weiteren wird vorausgesetzt, dass die IBM DB2 Beispieldatenbank SAMPLE existiert.

'-------------------------------------------------------------------------------------'
' Prozedur:     ConnectDB2Test
'
' Beschreibung: Ruft die Funktion ConnectDB2viaODBC auf.
'
' Parameter:    Ohne
'-------------------------------------------------------------------------------------'
Private Sub ConnectDB2Test()
    Call ConnectDB2viaODBC("SAMPLE", _
                           "SAMPLE", _
                           "SCHEMA", _
                           "EMPLOYEE", _
                           "UID", _
                           "PWD", _
                           True, _
                           True)
End Sub

'-------------------------------------------------------------------------------------'
' Funktion:     ConnectDB2viaODBC
'
' Beschreibung: Steuert die Herstellung einer Verbindung zur IBM DB2.
'               Vor strTargetFull wird, da bereits eine ODBC Verknüpfung zur Tabelle
'               strTable existieren könnte, die Zeichenkette "ac" gestellt.
'
' Parameter:    strDSN
'               strDBAlias
'               strSchema
'               strTable
'               strUID
'               strPWD
'               boolDeleteTarget
'               boolSavePWD
'
' Rückgabe:     ConnectDB2viaODBC
'-------------------------------------------------------------------------------------'
Public Function ConnectDB2viaODBC(ByVal strDSN As String, _
                                  ByVal strDBAlias As String, _
                                  ByVal strSchema As String, _
                                  ByVal strTable As String, _
                                  ByVal strUID As String, _
                                  ByVal strPWD As String, _
                                  ByVal boolDeleteTarget As Boolean, _
                                  ByVal boolSavePWD As Boolean) As Boolean
    On Error GoTo ConnectDB2viaODBC_Err
    Dim strODBCCnn                  As String
    Dim strSourceFull               As String
    Dim strTargetFull               As String
    Dim strDB2ODBCCnn               As String
    strSourceFull = strSchema & "." & strTable
    strTargetFull = "ac" & strSchema & "_" & strTable
    strODBCCnn = ODBCCnnString(strDSN, _
                               strDBAlias, _
                               strSchema, _
                               strTable, _
                               strUID, _
                               strPWD)
    If strODBCCnn <> vbNullString Then
        ConnectDB2viaODBC = TransferTable(strODBCCnn, _
                                          strSourceFull, _
                                          strTargetFull, _
                                          True, _
                                          boolDeleteTarget, _
                                          boolSavePWD)
    End If
ConnectDB2viaODBC_Exit:
    Exit Function
ConnectDB2viaODBC_Err:
    Call MsgBox("Mögliche Ursachen:" & vbCrLf & vbCrLf & _
                "- IBM DB2 Benutzerkennung und/oder Kennwort abgelaufen " & _
                "oder fehlerhaft" & vbCrLf & _
                "- IBM DB2 wurde nicht gestartet" & vbCrLf & _
                "- Schema- und/oder Tabellenübereinstimmungsfehler" & vbCrLf & _
                "- ODBC Fehler", _
                vbOKOnly + vbExclamation, _
                "Verbindung zur IBM DB2 konnte nicht hergestellt werden!")
    Resume ConnectDB2viaODBC_Exit
End Function
'-------------------------------------------------------------------------------------'
' Funktion:     ODBCCnnString
'
' Beschreibung: Gibt den aufgebauten ODBC Connect String zurück.
'
' Parameter:    strDSN
'               strDBAlias
'               strSchema
'               strTable
'               strUID
'               strPWD
'
' Rückgabe:     ODBCCnnString
'-------------------------------------------------------------------------------------'
Public Function ODBCCnnString(ByVal strDSN As String, _
                              ByVal strDBAlias As String, _
                              ByVal strSchema As String, _
                              ByVal strTable As String, _
                              ByVal strUID As String, _
                              ByVal strPWD As String) As String
    On Error GoTo ODBCCnnString_Err
    ODBCCnnString = "ODBC;DSN=" & strDSN & ";UID=" & strUID & ";PWD=" & strPWD & _
                    ";MODE=SHARE;DBALIAS=" & strDBAlias & _
                    ";;TABLE=" & strSchema & "." & strTable
ODBCCnnString_Exit:
    Exit Function
ODBCCnnString_Err:
    ODBCCnnString = vbNullString
    Resume ODBCCnnString_Err
End Function
'-------------------------------------------------------------------------------------'
' Funktion:     TransferTable
'
' Beschreibung: Überträgt die IBM DB2 Tabelle strSourceTable mit der TransferDatabase
'               Methode des DoCmd Objekts in die Access Tabelle strDestTable.
'               Ist boolStructureOnly = True, wird lediglich die Tabellenstruktur
'               übertragen.
'               Ist boolDeleteTarget = True, wird die Zieltabelle nach dem Übertragen 
'               gelöscht.
'               boolSavePWD steuert die Speicherung des Datenbankkennworts.
'               Anmeldename und Kennwort der ODBC Datenbank werden gespeichert.
'               Hinweis: Zur Übertragung der Tabellenstruktur wird der Parameter
'               	 acImport verwendet, da der Parameter acLink, unabhängig vom Wert
' 		         der booleschen Variablen boolStructureOnly, Struktur und Daten
'                        der Tabelle strSourceTable überträgt!
'
' Parameter:    strODBCConnect
'               strSourceTable
'               strDestTable
'               boolStructureOnly
'               boolDeleteTarget
'               boolSavePWD
'
' Rückgabe:     TransferTable
'-------------------------------------------------------------------------------------'
Public Function TransferTable(ByVal strODBCConnect As String, _
                              ByVal strSourceTable As String, _
                              ByVal strDestTable As String, _
                              ByVal boolStructureOnly As Boolean, _
                              ByVal boolDeleteTarget As Boolean, _
                              ByVal boolSavePWD As Boolean) As Boolean
    On Error GoTo TransferTable_Err
    With DoCmd
        .TransferDatabase acImport, _
                          "ODBC", _
                          strODBCConnect, _
                          acTable, _
                          strSourceTable, _
                          strDestTable, _
                          boolStructureOnly, _
                          boolSavePWD
        If boolDeleteTarget = True Then
            .DeleteObject acTable, strDestTable
        End If
    End With
    TransferTable = True
TransferTable_Exit:
    Exit Function
TransferTable_Err:
    TransferTable = False
    Resume TransferTable_Exit
End Function
Seitenanfang

Schemareferenzierung über Qualifier

Bei Großrechnerbetriebssystemen, wie IBM OS/390 oder IBM z/OS, werden Data Sets in Qualifier zerlegt. Diese Qualifier werden z.B. in JCL Skripten referenziert. Der bis zu 30 Zeichen lange IBM DB2 Schemaname wird in mehrere Teile aufgeteilt und/oder um Qualifier ergänzt und die Daten logisch unter dem zusammengesetzten Qualifier gespeichert. Die Qualifier dienen unter anderem zur Kostenträgerabrechnung der CPU Zeit. So kann z.B. das Schema ARTVERA in die Qualifier VER.ARTA aufgeteilt werden und ARTVERB in VER.ARTB. Auch eine Ergänzung um zusätzliche Qualifier, wie z.B. UF.BA.ART.VERA ist in vielen Fällen üblich. Die maximal zulässige Länge der Qualifier beträgt 44 Zeichen und als Trennzeichen zwischen den einzelnen Qualifiern wird der Punkt verwendet.

Nachfolgend ein in VBA realisiertes Beispiel, welches in einer Anwendung überprüfen könnte, ob der eingegebene Qualifier den IBM Konventionen (1tes Zeichen alphabetisch, keine Umlaute und Sonderzeichen, maximale Länge 8 Zeichen, Trennzeichen Punkt) entspricht:

'-------------------------------------------------------------------------------------' 
' Procedure:    TestQualifier
'
' Beschreibung: Ruft die Prozedur QualTestControl auf.
'
' Parameter:    Ohne 
'-------------------------------------------------------------------------------------'
Sub TestQualifier()
    Call QualTestControl("TSE.A01$0.LBH.1ARTSICH.9ABC.1111.44444.EDCTR")
End Sub
'-------------------------------------------------------------------------------------'
' Procedure:    QualTestControl
'
' Beschreibung: Steuert die Überprüfung der übergebenen Qualifier Zeichenkette.
'
' Parameter:    strQualifier
'-------------------------------------------------------------------------------------'
Sub QualTestControl(ByVal strQualifier As String)
    On Error GoTo QualTestControl_Err
    Dim avntQualifier               As Variant
    Dim avntQualifierNew()          As Variant
    Dim intCnt                      As Integer
    Dim intCntNew                   As Integer
    Dim avntInvalidElements()       As Variant
    Dim intCntInvEl                 As Integer
    Dim boolErr                     As Boolean
    Dim strErr                      As String
    avntQualifier = Split(strQualifier, ".")
    For intCnt = LBound(avntQualifier) To UBound(avntQualifier)
        If Len(avntQualifier(intCnt)) <= 8 _
        And IBMConvTest(CStr(avntQualifier(intCnt))) = True Then
            ReDim Preserve avntQualifierNew(intCntNew)
            avntQualifierNew(intCntNew) = avntQualifier(intCnt)
            intCntNew = intCntNew + 1
        Else
            boolErr = True
            ReDim Preserve avntInvalidElements(intCntInvEl)
            avntInvalidElements(intCntInvEl) = avntQualifier(intCnt)
            intCntInvEl = intCntInvEl + 1
        End If
    Next intCnt
    strQualifier = vbNullString
    If UBound(avntQualifier) - (intCntInvEl - 1) <> 0 Then
        For intCnt = LBound(avntQualifierNew) To UBound(avntQualifierNew)
            strQualifier = strQualifier & avntQualifierNew(intCnt) & _
			   IIf(intCnt < UBound(avntQualifierNew), ".", vbNullString)
        Next intCnt
    End If
    If boolErr = True Then
        strErr = "Folgende Qualifier entsprechen nicht der IBM Konvention:" & _
                 vbCrLf & vbCrLf
        For intCntInvEl = LBound(avntInvalidElements) To UBound(avntInvalidElements)
            strErr = strErr & IIf((intCntInvEl + 1) Mod 5 <> 0, _
                                  avntInvalidElements(intCntInvEl) & vbTab, _
                                  avntInvalidElements(intCntInvEl) & vbCrLf)
        Next intCntInvEl
        If strQualifier <> vbNullString Then
            strErr = strErr & vbCrLf & vbCrLf & _
                     "Die Qualifier wurden wie folgt korrigiert:" & _
                     vbCrLf & vbCrLf & _
                     strQualifier
        Else
            strErr = strErr & vbCrLf & vbCrLf & _
                     "Die Qualifier wurden entfernt!"
        End If
        Call MsgBox(strErr, _
                    vbInformation + vbOKOnly, _
                    "Fehler: IBM z/OS Qualifier")
    End If
QualTestControl_Exit:
    Exit Sub
QualTestControl_Err:
    MsgBox Err.Description
    Resume QualTestControl_Exit
End Sub
'-------------------------------------------------------------------------------------'
' Funktion:     IBMConvTest
'
' Beschreibung: Prüft, ob die eingegebenen Zeichen der IBM Konvention entsprechen.
'               Sollten nationale Sonderzeichen zugelassen sein, muss diese Funktion
'               ergänzt werden.
'
' Parameter:    strQualifier
'
' Rückgabe:     IBMConvTest
'-------------------------------------------------------------------------------------'
Public Function IBMConvTest(ByVal strQualifier As String) As Boolean
    On Error GoTo IBMConvTest_Err
    Dim intCnt                      As Integer
    Dim intLen                      As Integer
    Dim intASC                      As Integer
    intLen = Len(strQualifier)
    For intCnt = 1 To intLen
        intASC = Asc(Mid(strQualifier, intCnt, 1))
        If intCnt = 1 Then  ' A-Z
            If intASC >= 65 And intASC <= 90 Then
                IBMConvTest = True
            Else
                IBMConvTest = False
                Exit For
            End If
        Else                ' A-Z oder 0-9
            If intASC >= 65 And intASC <= 90 _
            Or intASC >= 48 And intASC <= 57 Then
                IBMConvTest = True
            Else
                IBMConvTest = False
                Exit For
            End If
        End If
    Next intCnt
IBMConvTest_Exit:
    Exit Function
IBMConvTest_Err:
    MsgBox Err.Description
    Resume IBMConvTest_Exit
End Function
Seitenanfang

Ermitteln, ob BenutzerInnen an einer IBM DB2 Umgebung angemeldet sind

In vielen Fällen ist es erforderlich festzustellen, ob BenutzerInnen an einer IBM DB2 Umgebung angemeldet sind. So wird z.B. ein LOAD Job scheitern, falls die IBM DB2 Umgebung in welche Daten geladen werden sollen, von anderen BenutzerInnen verwendet wird und Tabellen und/oder Datensätze gesperrt sind.

Die folgende, im IBM DB2 Befehlseditor auszuführende, Abfrage auf die IBM DB2 Sicht SYSIBMADM.SNAPAPPL_INFO, bei welcher 'SAMPLE' durch die zu überprüfende Datenbank zu ersetzen ist, gibt die Namen eine IBM DB2 Umgebung verwendende BenutzerInnen zurück:

SELECT DISTINCT SYSIBMADM.SNAPAPPL_INFO.PRIMARY_AUTH_ID FROM SYSIBMADM.SNAPAPPL_INFO
    WHERE SYSIBMADM.SNAPAPPL_INFO.APPL_STATUS='CONNECTED'
      AND SYSIBMADM.SNAPAPPL_INFO.DB_NAME='SAMPLE'
      AND SYSIBMADM.SNAPAPPL_INFO.PRIMARY_AUTH_ID NOT LIKE CURRENT_USER

Falls diese Abfrage in einer Microsoft Access Anwendung verwendet werden soll, sind die nachfolgenden Modifizierungen zu beachten:

SELECT DISTINCT SYSIBMADM_SNAPAPPL_INFO.PRIMARY_AUTH_ID FROM SYSIBMADM_SNAPAPPL_INFO
    WHERE SYSIBMADM_SNAPAPPL_INFO.STATUS='CONNECTED'
      AND Trim(SYSIBMADM_SNAPAPPL_INFO.DB_NAME) Like 'SAMPLE'
      AND SYSIBMADM_SNAPAPPL_INFO.PRIMARY_AUTH_ID <> 'WHATZITTOOYA'

Hinweis: Microsoft Access stellt kein Äquivalent zum IBM DB2 Spezialregister CURRENT_USER zur Verfügung!

Seitenanfang