Wie kann man herausfinden, welches Schema der Datenbankbenutzer hat?

Wie kann man herausfinden, welches Schema der Datenbankbenutzer hat?

User Datenbankbenutzer sollte bei der Datenbank (egal ob MSSQL oder Oracle) nur DBOwner und Public bekommen. Das genügt uns. Sobald mehr Rechte vergeben, wird das Schema automatisch außer Kraft gesetzt. 
Theoretisch kann man das Schema im enaio Enterprisemanager bzw. der Registry hinterlegen. Besser wäre jedoch, das Schema korrekt zu setzen. Mitunter werden aber Änderungen vorgenommen. Das kann das Routing sein oder Netzwerkeinstellungen.

Folgen: 

  • Unser Dienst startet  nicht mehr. 
  • Der Editor meint, dass er keine Tabellen findet. 
  • Das Setup gibt Fehler aus, weil es die Tabellen nicht mehr sieht und beim Anlege-Versuch scheitert weil es die Tabellen schon gibt. 

Das Schema kann auf verschiedene Weisen ermittelt werden. Am sichersten ist es, eine Hilfstabelle anzulegen und dann zu prüfen, welches Schema es bekommen hat. 

Schritt-für-Schritt-Anleitung

  1. Am besten ein ODBC-Tool suchen oder ein MSSQL-Management-Studio oder einen Oracle-Developer. Ist das nicht verfügbar, kann man auch ein Skript verwenden. 
  2. Bei Verwendung MSSQL-Management-Studio oder Oracle-Developer oder ODBC-Tool: 
    Tool starten und mit unserem Datenbankbenutzer eine Verbindung herstellen.
    Test per Abfrage: 
    MSSQL - Schema ermitteln: select schema_name(); 
    Oracle - Schema ermitteln: select * from user_users; (bei default_tablespace ist das Schema zu finden)

    Test per Tabellenanlage: 
    1. Einfach eine Tabelle anlegen. Dazu diesen Befehl ausführen
      MSSQL / Oracle:  CREATE TABLE ALLGTEST (nnr int, nname char(50)); 
    2. Bei Oracle danach noch ausführen: COMMIT; 
    3. Dann die Tabellen aktualisieren. Wie wurde die Tabelle angelegt? Mit Schema+Tabellenname? Wurde die neue Tabelle als DBO.ALLGTEST angelegt, stimmt etwas mit dem Schema nicht oder der Benutzer hat zu viele Rechte!
  3. Verwendet man ein ODBC-Tool, dann kann man u.U. nicht sehen, welches Schema verwendet wurde. Da hilft die Tabellen explizit abzufragen, z. Bsp. so:
    1. SELECT * FROM DBO.ALLGTEST;
      Wenn hier etwas angezeigt wird, dann ist das Schema DBO. Ansonsten gibt einen Fehler, Tabelle unbekannt oder ähnlich.
      Beispiel aus Oracle-Developer:
    2. SELECT * FROM <schema>.ALLGTEST;
      Bsp.: SELECT * FROM SYSADM.ALLGTEST;
      Wenn hier etwas angezeigt wird, dann ist das Schema = Benutzer. Ansonsten gibt einen Fehler, Tabelle unbekannt oder ähnlich.
    3. Beispiel für Fehlerfall: Hier wurde DBO verwendet. Es hätte aber PH sein müssen, analog den anderen Tabellen. 

      Beispiel aus dem MSSQL-Studio:
  4. Nicht empfehlenswert, aber zur Vollständigkeit: Falls man enaio Enterprisemanager verwenden möchte (erfordert einen gestarteten enaio Dienst), dann auf "Verwaltung, Datenbanken" gehen und mit unserem Datenbankbenutzer eine Verbindung herstellen.
    Bei SQL diesen Befehlt eintragen: CREATE TABLE ALLGTEST (nnr int, nname char(50)); 
    Bei Oracle danach noch ausführen: COMMIT; 
    Anzeige aktualisieren. Wenn die Tabelle nicht sichtbar ist und das Admin-Err-Log nichts ausgegeben hat, dann ist das Schema DBO. 
  5. per VBScript: 
    Textdatei erstellen und z. Bsp. test.vbs benennen. ODBC-Verbindung und Pfade anpassen. 
    Danach ausführen mit Doppelklick bei 64bit ODBC ausführen. 
    Bei 32bit ODBC-Quelle: %windir%\syswow64\wscript.exe test.vbs 

    Skript-Inhalt:

    ' Funktion: Verbindung per ODBC aufbauen und Daten auslesen. 
    Dim fso 
    dim fl
    dim log
    dim slogpath
    dim sStatement
    dim dbtyp

    'Protokollpfad (schreibt nur im Fehlerfall)
    slogpath = "C:\_Daten\Schema-Check\"

    'ODBC-Connect eintragen, ermittelt die IDs per Datenbank. 
    dbuser="sysadm"
    Dim connection, connectionString, theCommand, commandString
    ODBCconnectionString = "DSN=enaio;UID=" & dbuser & ";PWD=optimal;"

    ' Datenbanktyp, 1 = MSSQL, alles andere Oracle 
    dbtyp=1

    on error resume next

    '--------------------------------------------------------------------------------
        
    stimeStamp=year(date) & right("0" & month(date),2) & right("0" & day(date),2) & right("0" & hour(time),2) & right("0" & minute(time),2) & right("0" & second(time),2) 
    log= slogpath & "SchemaCheck_" & stimeStamp & ".log"

    Set fso = CreateObject("Scripting.FileSystemObject")
    'msgbox log
    set fl=fso.CreateTextFile(log)
    fl.writeline("Start ODBC-Auslesen " & date & " " & time)

      'Verbindung zur Datenbank herstellen
      Set connection = CreateObject("ADODB.Connection")
      connection.Open ODBCconnectionString
      
      'Recordset-Funktion laden und Statement ausführen
      Set objRecordset = createObject("ADODB.Recordset")

      'fl.writeline(now & "  Statement: " & sStatement)
      fl.writeline(now & " ODBC-Verbindung aufbauen ...")
      
      objRecordset.ActiveConnection=connection
      sStatement = "create table allgmtest (nnr int, nname char(50));"
      objRecordset.source = sStatement
      fl.writeline(sStatement)
      objRecordset.open
      fl.writeline("... Test-Tabelle erstellen ...")

      if dbtyp<>1  then 
        sStatement = "commit;"
        objRecordset.source = sStatement
        objRecordset.open
      end if 

      if err.number<>0 then 
         fl.writeline(now & "  Err-Nr. " & err.number & " - " & err.description)
      else 
         fl.writeline(now & "  Test-Tabelle erstellt.")
      end if

    ' Tests der Tabellen
      fl.writeline("... Abfrage DBO-Tabelle ...")
      sStatement = "select count(*) as anzahlx from dbo.allgmtest;"
      fl.writeline(sStatement)
      objRecordset.source = sStatement
      objRecordset.open

      if err.number<>0 then 
         fl.writeline(now & "  DBO-Tabelle nicht vorhanden. Err-Nr. " & err.number & " - " & err.description)
      else 
         fl.writeline(now & "  DBO-Tabelle vorhanden.")
      end if 
      err.clear

      fl.writeline("... Abfrage Benutzer/Schema-Tabelle ...")  
      sStatement = "select count(*) as anzahlx from " & dbuser & ".allgmtest;"
      fl.writeline(sStatement)
      objRecordset.source = sStatement
      objRecordset.open

      if err.number<>0 then 
         fl.writeline(now & " Benutzer-Tabelle nicht vorhanden. Err-Nr. " & err.number & " - " & err.description)
      else 
         fl.writeline(now & "  Benutzer=Schema - Tabelle vorhanden.")
      end if 

      objRecordset.Close  
      connection.close

    fl.writeline("Ende Auslesen " & now & ".")
    fl.writeline("")
    fl.close




Verwendet man z. Bsp. Winsql.exe, bitte beachten, dass das Tool 32bit ist. Die 64bit-Version ist zwar verfügbar, aber der Kunde müsste sich registrieren. Notlösung: eine temporäre ODBC-Datenquelle 32bit anlegen. Bei Oracle geht das u.U. nicht, da die Treiber nicht verfügbar sind. 

Verwandte Artikel