Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs
ASP German Homepage Homepage
 

Liste

.NET 2.0 (1)
.NET Allgemein (16)
.NET Fu (5)
ADO.NET (11)
Aprilscherz (3)
ASP Grundlagen (44)
ASP Tricks (83)
ASP.NET (44)
ASPIntranet.de (5)
C# (28)
Datenbank (44)
Dokumentation (4)
IIS 6.0 (1)
Komponenten (29)
Optimierung (10)
Server (21)
Sicherheit (34)
Tee Off (6)
VB.NET (6)
WAP (8)
Web Services (11)
XML (9)

RSS 2.0 - Die neuesten fünf Artikel auf AspHeute.com


 

Suchen





 

English Articles
Chinese Articles
Unsere Autoren
 
Link zu AspHeute
Impressum
Werben
Anfragen

Tabellenexistenz in Datenbanken überprüfen

Geschrieben von: Christoph Wille
Kategorie: Datenbank

Im Normalfall weiß man, wenn man mit einer Datenbank arbeitet, welche Tabellen in ihr enthalten sind. Andererseits gibt es aber Anwendungsfälle, wo man erst zur Laufzeit auf eine Datenbank connected, und dann dynamisch herausfinden muß, welche Tabellen es gibt, oder überprüfen muß, ob eine spezielle Tabelle existiert.

Heute stelle ich diverse Varianten vor, wie man feststellen kann, ob eine Tabelle in einer Datenbank enthalten ist. Das Auflisten aller Tabellen ist, wie sich zeigt, immer nur der Spezialfall der Suche nach einer Tabelle (oder anders herum, je nach dem, wie man das Problem betrachtet). Sei es wie es sei, ich demonstriere die verschiedenen Wege für SQL Server und Access, beginnend mit SQL Server.

In SQL Server

In SQL Server ist die Sache sehr einfach, wenn man weiß, wo man nachsehen muß. Die berühmte "allwissende Müllhalde" ist in SQL Server die Tabelle namens sysobjects - in dieser sind alle Objekte einer Datenbank vermerkt. Jedes dieser Objekte hat einen Typ, und der Typ der Tabellen zugeordnet ist, ist U.

Das nun folgende Beispiel alltables_sql.asp zeigt, wie man sich alle Tabellen in einer SQL Server Datenbank auflisten lassen kann:

<%
strConnStr = "Provider=SQLOLEDB;Data Source=strangelove;Initial Catalog=Northwind;..."
strTableStmt = "select * from sysobjects where type='U'"

Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open strTableStmt, strConnStr
While Not rs.EOF
  Response.Write rs.Fields("name").Value & "<br>" & vbCrlf
  rs.MoveNext
Wend

rs.Close
Set rs = Nothing
%>

Damit hätten wir alle Tabellen aufgelistet, die es gibt. Nun müssen wir diesen Code nur noch modifizieren - und etwas leichter wiederverwendbar machen - damit wir die Existenz oder Nichtexistenz einer einzelnen Tabelle nachweisen. Dies erledigt das nun folgende Script tableexists_sql.asp.

<% Option Explicit%>
<script language="vbscript" runat="server">
Function TableExistsSql(ByVal strConnStr, ByVal strTable)
 Dim strSQL, rs, nCount
 strSQL = "select count(*) from sysobjects where type='U' AND name='" & _
    strTable & "'"

 Set rs = Server.CreateObject("ADODB.Recordset")
 rs.Open strSQL, strConnStr
 nCount = rs.Fields(0).Value
 rs.Close
 Set rs = Nothing

 TableExistsSql = False
 If (1 = nCount) Then TableExistsSql = True
End Function

</script>

<%
Dim strConnStr
strConnStr = "Provider=SQLOLEDB;Data Source=strangelove;Initial Catalog=Northwind;..."

Response.Write TableExistsSql(strConnStr, "Customers")
%>

Die Funktion TableExistsSql kann man in ein zentrales Include geben, um eine leichte Wiederverwendbarkeit zu erzielen.

In Access - mit Bordmitteln

SQL Server war quasi "aufgelegt". In Access wird's unter Umständen schon etwas verzwickter, außer man kennt zufälligerweise die "Untiefen" des Systems.

Die angesprochene Untiefe ist das Faktum, daß Access seine Objekte ebenfalls in Tabellen verwaltet, diese allerdings versteckt sind. Man muß diese erst in Tools / Options zu Tage fördern:

Und dann hat man plötzlich etliche zusätzliche Tabellen im Datenbankfenster (simple.mdb ist im heutigen Download enthalten):

Der Name MSysObjects sieht doch bereits verdächtig nach dem aus, was wir suchen. Und tatsächlich - diese Tabelle enthält alle Objekte inklusive Tabellen, und Tabellen haben hier den Typ 1. Also müssen wir unseren Code nur geringfügig modifizieren - zuerst alltables_access.asp:

<%
strConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
      "Data Source=" & Server.MapPath("simple.mdb")

strTableStmt = "select * from MSysObjects where type=1"

Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open strTableStmt, strConnStr
While Not rs.EOF
  Response.Write rs.Fields("name").Value & "<br>" & vbCrlf
  rs.MoveNext
Wend

rs.Close
Set rs = Nothing
%>

Die Sache hat nur einen Schönheitsfehler, der uns bei der Ausführung des Scripts schnell aufgezeigt wird:

Microsoft JET Database Engine error '80040e09' 
Record(s) cannot be read; no read permission on 'MSysObjects'. 
/aspheute/findtable/alltables_access.asp, line 8 

Im Vergleich zu SQL Server ist die Tabelle sogar gegen Zugriff durch den Admin (sa-Äquivalent in Access) gesperrt. Eine kurze Visite in Tools / Security / User and Group Permissions ist notwendig - wir müssen uns (dem Admin) die Read Data Rechte erlauben:

Und jetzt funktioniert unser Script klaglos. Somit können wir auch unser Script zum Auffinden einer einzelnen Tabelle anpassen (tableexists_access.asp):

<% Option Explicit%>
<script language="vbscript" runat="server">
Function TableExistsAccess(ByVal strConnStr, ByVal strTable)
 Dim strSQL, rs, nCount
 strSQL = "select count(*) from MSysObjects where Type=1 AND Name='" & _
    strTable & "'"

 Set rs = Server.CreateObject("ADODB.Recordset")
 rs.Open strSQL, strConnStr
 nCount = rs.Fields(0).Value
 rs.Close
 Set rs = Nothing

 TableExistsAccess = False
 If (1 = nCount) Then TableExistsAccess = True
End Function

</script>

<%
Dim strConnStr
strConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
      "Data Source=" & Server.MapPath("simple.mdb")

Response.Write TableExistsAccess(strConnStr, "TestTable")
%>

Einzig der SQL String wurde geändert, sonst funktioniert alles gleich wie für SQL Server. Praktisch.

In Access mit ADOX

Es heißt, es führen mehrere Wege nach Rom. Für das Überprüfen der Tabellenexistenz stimmt das - man kann dies auch mit ADOX (ADO Extensions for Data Definition Language and Security) bewerkstelligen.

Dieses Mal erspare ich uns den Umweg über das Auflisten aller Tabellen (das kann jeder selbst über die Tables Collection nachholen), und starte sogleich mit tableexists_adox.asp:

<% Option Explicit%>
<script language="vbscript" runat="server">
Function TableExistsADOX(ByVal strConnStr, ByVal strTable)
 Dim cat, tbl
 Set cat = Server.CreateObject("ADOX.Catalog")
 cat.ActiveConnection = strConnStr

 On Error Resume Next
 Set tbl = cat.Tables.Item(strTable)

 TableExistsADOX = True
 If Err.Number <> 0 Then
   TableExistsADOX = False
 End If
 Set cat = Nothing
End Function

</script>

<%
Dim strConnStr
strConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
      "Data Source=" & Server.MapPath("simple.mdb")

Response.Write TableExistsADOX(strConnStr, "TestTable")
%>

Ich greife mit cat.Tables.Item(strTable) direkt in die Tables Collection hinein, um mir eine Referenz auf die gewünschte Tabelle zu holen. Die Frage ist, was passiert, wenn diese nicht existiert - es wird ein Fehler ausgelöst:

ADOX.Tables error '800a0cc1' 
Item cannot be found in the collection corresponding to the requested name or ordinal. 
/aspheute/findtable/tableexists_adox.asp, line 9 

Genau deshalb verwende ich das On Error Resume Next Statement - wird kein Fehler ausgelöst, existiert die Tabelle - kommt ein Fehler, war keine Tabelle dieses Namens in der Datenbank auffindbar. Diese Information verwende ich, um den Rückgabewert der Funktion zu belegen.

Schlußbemerkung

Was ist jetzt der bessere Weg um die Tabellenexistenz abzufragen? Nun, in SQL Server stellt sich die Frage nicht, und in Access ist der Weg über ADOX sicherlich der des geringsten Widerstands, da man die Originaldatenbank nicht modifizieren muß.

Download des Codes

Klicken Sie hier, um den Download zu starten.

Verwandte Artikel

ADO Component Checker Tool
Installation der neuesten ADO Version (ADO 2.5)
Tabellenerstellung mit ADOX
Yet Another Access Database Administration Tool

Wenn Sie jetzt Fragen haben...

Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten.

Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.

 

Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.

Bewerten Sie diesen Artikel
 Sehr gut   Nicht genügend  
   1  2  3  4  5  
 

  
   Für Ausdruck optimierte Seite

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.