Ich versuche, das Schema einer MDB-Datenbank zu extrahieren, so dass ich die Datenbank an anderer Stelle neu erstellen kann.Wie extrahiert man das Schema einer Access (.mdb) -Datenbank?
Wie kann ich so etwas abziehen?
Ich versuche, das Schema einer MDB-Datenbank zu extrahieren, so dass ich die Datenbank an anderer Stelle neu erstellen kann.Wie extrahiert man das Schema einer Access (.mdb) -Datenbank?
Wie kann ich so etwas abziehen?
Es ist möglich, ein wenig mit VBA zu tun. Zum Beispiel beginnt hier das Erstellen eines Skripts für eine Datenbank mit lokalen Tabellen.
Dim db As Database
Dim tdf As TableDef
Dim fld As DAO.Field
Dim ndx As DAO.Index
Dim strSQL As String
Dim strFlds As String
Dim strCn As String
Dim fs, f
Set db = CurrentDb
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.CreateTextFile("C:\Docs\Schema.txt")
For Each tdf In db.TableDefs
If Left(tdf.Name, 4) <> "Msys" Then
strSQL = "strSQL=""CREATE TABLE [" & tdf.Name & "] ("
strFlds = ""
For Each fld In tdf.Fields
strFlds = strFlds & ",[" & fld.Name & "] "
Select Case fld.Type
Case dbText
'No look-up fields
strFlds = strFlds & "Text (" & fld.Size & ")"
Case dbLong
If (fld.Attributes And dbAutoIncrField) = 0& Then
strFlds = strFlds & "Long"
Else
strFlds = strFlds & "Counter"
End If
Case dbBoolean
strFlds = strFlds & "YesNo"
Case dbByte
strFlds = strFlds & "Byte"
Case dbInteger
strFlds = strFlds & "Integer"
Case dbCurrency
strFlds = strFlds & "Currency"
Case dbSingle
strFlds = strFlds & "Single"
Case dbDouble
strFlds = strFlds & "Double"
Case dbDate
strFlds = strFlds & "DateTime"
Case dbBinary
strFlds = strFlds & "Binary"
Case dbLongBinary
strFlds = strFlds & "OLE Object"
Case dbMemo
If (fld.Attributes And dbHyperlinkField) = 0& Then
strFlds = strFlds & "Memo"
Else
strFlds = strFlds & "Hyperlink"
End If
Case dbGUID
strFlds = strFlds & "GUID"
End Select
Next
strSQL = strSQL & Mid(strFlds, 2) & ")""" & vbCrLf & "Currentdb.Execute strSQL"
f.WriteLine vbCrLf & strSQL
'Indexes
For Each ndx In tdf.Indexes
If ndx.Unique Then
strSQL = "strSQL=""CREATE UNIQUE INDEX "
Else
strSQL = "strSQL=""CREATE INDEX "
End If
strSQL = strSQL & "[" & ndx.Name & "] ON [" & tdf.Name & "] ("
strFlds = ""
For Each fld In tdf.Fields
strFlds = ",[" & fld.Name & "]"
Next
strSQL = strSQL & Mid(strFlds, 2) & ") "
strCn = ""
If ndx.Primary Then
strCn = " PRIMARY"
End If
If ndx.Required Then
strCn = strCn & " DISALLOW NULL"
End If
If ndx.IgnoreNulls Then
strCn = strCn & " IGNORE NULL"
End If
If Trim(strCn) <> vbNullString Then
strSQL = strSQL & " WITH" & strCn & " "
End If
f.WriteLine vbCrLf & strSQL & """" & vbCrLf & "Currentdb.Execute strSQL"
Next
End If
Next
f.Close
Das ist wirklich gut. Wie erhalten Sie die Standardwerte, Fremdschlüssel usw.? – AngryHacker
Es ist notwendig, ADO zu verwenden, um Standardwerte hinzuzufügen. Fremdschlüssel usw. kann mit CONSTRAINT ReferForeignField FOREIGN KEY hinzugefügt werden ( Wenn Sie DAO verwenden, sollten Sie die Beziehungssammlung verwenden, um Fremdschlüsselbeschränkungen anzuwenden, nein? –
Es ist schwer, DDL-Skripte/Abfragen in Access zu tun. Es kann getan werden, aber Sie wären besser dran, nur eine Kopie der Datenbank erstellen - Löschen aller Daten und Verdichten. Verwenden Sie dann eine Kopie davon, um die Datenbank an anderer Stelle neu zu erstellen. Ich befürchtete, dies könnte die Antwort sein. Build-Integration kommt also nicht in Frage. –
AngryHacker
Aber das war nicht deine Frage. Sie haben nicht nach der Build-Integration gefragt, Sie haben nach dem Extrahieren des Schemas gefragt. Sie können den Schema-Build-Prozess natürlich auch schreiben, indem Sie den Code schreiben, genau wie der Rest Ihrer Anwendung. –
dkretz
Schauen Sie sich das Dokument an. TransferDatabase Befehl. Es ist wahrscheinlich die beste Wahl für Build-Integration, die die Datenstruktur replizieren müssen Sie können die ACE/Jet OLE DB-Provider verwenden, und ein ADO-Connection-Objekts der Methode Openschema Schemainformationen als Recordset zu erhalten (die als eine Sammlung arguable besser ist, weil es gefiltert werden kann, sortierte, etc). Die grundlegende Methodik ist adSchemaTables zu verwenden, um die Basistabellen (nicht VIEWs) zu bekommen, dann jede TABLE_NAME verwenden AdSchemaColumns für ORDINAL_POSITION zu holen,! DATA_TYPE,! IS_NULLABLE,! COLUMN_HASDEFAULT,! COLUMN_DEFAULT,! Character_maximum_length,! NUMERIC_PRECISION ,! NUMERIC_SCALE. adSchemaPrimaryKeys ist einfach. In adSchemaIndexes finden Sie UNIQUE-Constraints, die nicht sicher sind, ob diese von eindeutigen Indizes unterschieden werden können, und auch die Namen von FOREIGN KEYs, die in das AdSchemaForeignKeys-Rowset eingefügt werden sollen, z. (Pseudocode): - achten Sie auf die Gotcha, den Jet 3.51 ein FK ermöglicht auf Basis eines namenlos PK (!!) Namen von Validierungsregeln und CHECK-Einschränkungen finden Sie in das adSchemaTableConstraints-Rowset mit dem Tabellennamen im OpenSchema-Aufruf, dann den Namen im Aufruf des adSchemaCheckConstraints-Rowsets, Filter für CONSTRAINT_TYPE = 'CHECK' (ein Gotcha ist ein Constraint namens 'ValidationRule' + Chr $ (0), also Am besten entziehen Sie den Nullzeichen den Namen). Denken Sie daran, dass ACE/Jet-Validierungsregeln entweder auf Zeilen- oder Tabellenebene sein können (CHECK-Einschränkungen sind immer Tabellenebene), daher müssen Sie möglicherweise den Tabellennamen im Filter verwenden: Für adSchemaTableConstraints ist []. []. ValidationRule wird [] .ValidationRule in adSchemaCheckConstraints sein. Ein weiterer Fehler (vermuteter Bug) ist, dass das Feld 255 Zeichen breit ist, so dass jede Validierungsregel/CHECK-Constraint-Definition von mehr als 255 Zeichen einen NULL-Wert haben wird. adSchemaViews für Access Query-Objekte, die auf nicht parameterisierter SELECT SQL-DML basieren, ist einfach; Sie können den VIEW-Namen in adSchemaColumns verwenden, um die Spaltendetails abzurufen. PROCEDURES sind in adSchemaProcedures, wobei alle anderen Varianten von Access Query-Objekten einschließlich parametrisierter SELECT DML sind; für letzteres bevorzuge ich es, die PARAMETERS-Syntax durch CREATE PROCEDURE PROCEDURE_NAME in PROCEDURE_DEFINITION zu ersetzen. Wenn Sie in den adSchemaProcedureParameters nicht nachsehen, werden Sie nichts finden: Die Parameter können mithilfe eines ADOX Catalog-Objekts aufgelistet werden, um einen ADO-Befehl zurückzugeben, z. (Pseudocode): dann aufzählen, die Comm.Parameters Sammlung für den .Name, .Type für DATA_TYPE, (.Attributes Und adParamNullable) für IS_NULLABLE.Wert für COLUMN_HASDEFAULT und COLUMN_DEFAULT, .Size, .Precision, .NumericScale. Für ACE/Jet-spezifische Eigenschaften wie Unicode-Komprimierung müssen Sie eine andere Art von Objekt verwenden. Zum Beispiel kann eine Long-Integer-Autonummer in Zugriffssprache unter Verwendung eines ADO-Katalogobjekts gefunden werden, z. (Pseudocode): Viel Glück :) Wenn Sie glücklich sind etwas anderes als reine Access SQL zu verwenden, können Sie eine Sammlung von ADOX-Objekte bestehen bleiben könnte und nutzen diejenigen, die Tabellenstruktur erstellen . Beispiel (in Python, derzeit nicht neu Beziehungen und Indizes, da sie nicht für das Projekt benötigt wurde ich arbeite): Eine ähnliche Umkehrfunktion rekonstruiert die Datenbank die zweite Verbindung mit Zeichenfolge. So etwas wie "Access SQL" gibt es nicht. Access verwendet Jet SQL standardmäßig, aber das ist völlig unabhängig von Access. –
Wahr, wahr. Ich decke mich einen Pedant Punkt :) –
mavnn
@mavnn: Ja, Schande über dich. Die Tatsache, dass * jeder * genau wusste, was Sie meinten, hat keinerlei Einfluss auf die Sache. –
onedaywhen
Die folgende C# beschreibt, wie Sie das Schema aus einer MDB-Datei erhalten. eine Verbindung zur Datenbank erhalten: die Namen jeder Tabelle holen: Wo tun: die Felder für jede Tabelle holen die Um den Feldnamen für jede Spalte in der Datenbank zu erhalten: OleDbDataReader.GetName (i), wobei i verwendet wird, um durch jede der Feldindexnummern zu iterieren. OleDbDataReader.GetFieldType (i) gibt den Datentyp der Spalte zurück. –
Stewbob
Aha, ich wusste, dass es einen Weg geben muss! Prost. –
dukedave
Ich aktualisierte Ihre Antwort mit den tatsächlichen Zeichenfolgenwerten für die Zeilen, die Sie wollten. Ich werde einen Screenshot aller Optionen in einer Antwort unten hinzufügen. –
ProVega
Vergleichen Sie 'Em http://home.gci.net/~mike-noel/CompareEM-LITE/CompareEM.htm wird glücklich generieren den VBA-Code muss eine MDB neu erstellen. Oder der Code, um die Unterschiede zwischen zwei MDBs zu erstellen, so dass Sie ein Versions-Upgrade der bereits vorhandenen BE-MDB durchführen können. Es ist ein bisschen schrullig, aber funktioniert. Beachten Sie, dass es die neuen ACE-Formate ACE (Access2007) usw. nicht unterstützt. Ich benutze es die ganze Zeit. (OneDayWhen der Bearbeitung war ein Drittel rechts und zwei Drittel falsch.) Es ist eine alte Frage ist jetzt, aber leider ausdauernde :( Ich dachte, dieser Code der Nutzung der Suche nach Lösungen für andere sein kann. es wurde entwickelt von der Kommandozeile über cscript ausgeführt werden, so dass keine Notwendigkeit, Code in Ihre Access-Projekt zu importieren. Ähnlich wie bei (und inspiriert von) der Code von Oliver in How do you use version control with Access development. Wenn Sie l sind Um auch Abfragedefinitionen zu exportieren, sollte this question helfen. Es ist ein wenig anders, weil Sie in der Regel nicht querydefs mit einfachen DDL Aber hier ist ein kleines Stück von einem Skript, das ich für die Sicherung von Abfragen zu trennen geschrieben .SQL-Dateien (die Teil eines größeren Skripts zum Sichern des gesamten Front-End-DB-Codes sind, finden Sie in Oliver's Antwort auf this question). Wie ich oben erwähnt, wäre es toll, wenn dies auch Abfragedefinitionen enthalten würde. –
LondonRob
@LondonRob: hinzugefügt –
Sehr hilfreiche Post! Ich habe das Skript überarbeitet, um die Datendefinitionssprache für SQL Server zu generieren. Ich dachte, es könnte für jemanden nützlich sein, also teile ich es mit. Das einzige Problem, mit dem ich konfrontiert wurde, ist, dass das VBS-Skript alle Felder in der Tabelle für Indizes extrahiert. Ich bin mir nicht sicher, wie ich das noch lösen soll, also extrahiere ich nur das erste Feld. Dies funktioniert für die meisten Primärschlüssel. Schließlich sind nicht alle Datentypen bewiesen, aber ich denke, ich habe die meisten von ihnen. (
rsFK.Filter = "FK_NAME = '" & !INDEX_NAME & "'")
Set Command = Catalog.Procedures(PROCEDURE_NAME).Command
bIsAutoincrement = Catalog.Tables(TABLE_NAME).Columns(COLUMN_NAME).Properties("Autoincrement").Value
import os
import sys
import datetime
import comtypes.client as client
class Db:
def __init__(self, original_con_string = None, file_path = None,
new_con_string = None, localise_links = False):
self.original_con_string = original_con_string
self.file_path = file_path
self.new_con_string = new_con_string
self.localise_links = localise_links
def output_table_structures(self, verbosity = 0):
if os.path.exists(self.file_path):
if not os.path.isdir(self.file_path):
raise Exception("file_path must be a directory!")
else:
os.mkdir(self.file_path)
cat = client.CreateObject("ADOX.Catalog")
cat.ActiveConnection = self.original_con_string
linked_tables =()
for table in cat.Tables:
if table.Type == u"TABLE":
f = open(self.file_path + os.path.sep +
"Tablestruct_" + table.Name + ".txt", "w")
conn = client.CreateObject("ADODB.Connection")
conn.ConnectionString = self.original_con_string
rs = client.CreateObject("ADODB.Recordset")
conn.Open()
rs.Open("SELECT TOP 1 * FROM [%s];" % table.Name, conn)
for field in rs.Fields:
col = table.Columns[field.Name]
col_details = (col.Name, col.Type, col.DefinedSize,
col.Attributes)
property_dict = {}
property_dict["Autoincrement"] = (
col.Properties["Autoincrement"].Value)
col_details += property_dict,
f.write(repr(col_details) + "\n")
rs.Close()
conn.Close()
f.close()
if table.Type == u"LINK":
table_details = table.Name,
table_details += table.Properties(
"Jet OLEDB:Link DataSource").Value,
table_details += table.Properties(
"Jet OLEDB:Link Provider String").Value,
table_details += table.Properties(
"Jet OLEDB:Remote Table Name").Value,
linked_tables += table_details,
if linked_tables !=():
f = open(self.file_path + os.path.sep +
"linked_list.txt", "w")
for t in linked_tables:
f.write(repr(t) + "\n")
cat.ActiveConnection.Close()
String f = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + "database.mdb";
OleDbConnection databaseConnection = new OleDbConnection(f);
databaseConnection.Open();
DataTable schemaTable = databaseConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, tableName, null });
foreach (DataRow row in schemaTable.Rows)
{
String fieldName = row["COLUMN_NAME"].ToString(); //3
String fieldType = row["DATA_TYPE"].ToString(); // 11
String fieldDescription = row["DESCRIPTION"].ToString(); //27
}
}
DataTable dataTable = databaseConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
int numTables = dataTable.Rows.Count;
for (int tableIndex = 0; tableIndex < numTables; ++tableIndex)
{
String tableName = dataTable.Rows[tableIndex]["TABLE_NAME"].ToString();
3
, 11
und 27
kommen aus? Ich habe sie gefunden, indem ich DataRow.ItemArray
mit einem Debugger inspiziert habe, kennt jemand den "korrekten" Weg?' Usage:
' CScript //Nologo ddl.vbs <input mdb file> > <output>
'
' Outputs DDL statements for tables, indexes, and relations from Access file
' (.mdb, .accdb) <input file> to stdout.
' Requires Microsoft Access.
'
' NOTE: Adapted from code from "polite person" + Kevin Chambers - see:
' http://www.mombu.com/microsoft/comp-databases-ms-access/t-exporting-jet-table-metadata-as-text-119667.html
'
Option Explicit
Dim stdout, fso
Dim strFile
Dim appAccess, db, tbl, idx, rel
Set stdout = WScript.StdOut
Set fso = CreateObject("Scripting.FileSystemObject")
' Parse args
If (WScript.Arguments.Count = 0) then
MsgBox "Usage: cscript //Nologo ddl.vbs access-file", vbExclamation, "Error"
Wscript.Quit()
End if
strFile = fso.GetAbsolutePathName(WScript.Arguments(0))
' Open mdb file
Set appAccess = CreateObject("Access.Application")
appAccess.OpenCurrentDatabase strFile
Set db = appAccess.DBEngine(0)(0)
' Iterate over tables
' create table statements
For Each tbl In db.TableDefs
If Not isSystemTable(tbl) And Not isHiddenTable(tbl) Then
stdout.WriteLine getTableDDL(tbl)
stdout.WriteBlankLines(1)
' Iterate over indexes
' create index statements
For Each idx In tbl.Indexes
stdout.WriteLine getIndexDDL(tbl, idx)
Next
stdout.WriteBlankLines(2)
End If
Next
' Iterate over relations
' alter table add constraint statements
For Each rel In db.Relations
Set tbl = db.TableDefs(rel.Table)
If Not isSystemTable(tbl) And Not isHiddenTable(tbl) Then
stdout.WriteLine getRelationDDL(rel)
stdout.WriteBlankLines(1)
End If
Next
Function getTableDDL(tdef)
Const dbBoolean = 1
Const dbByte = 2
Const dbCurrency = 5
Const dbDate = 8
Const dbDouble = 7
Const dbInteger = 3
Const dbLong = 4
Const dbDecimal = 20
Const dbFloat = 17
Const dbMemo = 12
Const dbSingle = 6
Const dbText = 10
Const dbGUID = 15
Const dbAutoIncrField = 16
Dim fld
Dim sql
Dim ln, a
sql = "CREATE TABLE " & QuoteObjectName(tdef.name) & " ("
ln = vbCrLf
For Each fld In tdef.fields
sql = sql & ln & " " & QuoteObjectName(fld.name) & " "
Select Case fld.Type
Case dbBoolean 'Boolean
a = "BIT"
Case dbByte 'Byte
a = "BYTE"
Case dbCurrency 'Currency
a = "MONEY"
Case dbDate 'Date/Time
a = "DATETIME"
Case dbDouble 'Double
a = "DOUBLE"
Case dbInteger 'Integer
a = "INTEGER"
Case dbLong 'Long
'test if counter, doesn't detect random property if set
If (fld.Attributes And dbAutoIncrField) Then
a = "COUNTER"
Else
a = "LONG"
End If
Case dbDecimal 'Decimal
a = "DECIMAL"
Case dbFloat 'Float
a = "FLOAT"
Case dbMemo 'Memo
a = "MEMO"
Case dbSingle 'Single
a = "SINGLE"
Case dbText 'Text
a = "VARCHAR(" & fld.Size & ")"
Case dbGUID 'Text
a = "GUID"
Case Else
'>>> raise error
MsgBox "Field " & tdef.name & "." & fld.name & _
" of type " & fld.Type & " has been ignored!!!"
End Select
sql = sql & a
If fld.Required Then _
sql = sql & " NOT NULL "
If Len(fld.DefaultValue) > 0 Then _
sql = sql & " DEFAULT " & fld.DefaultValue
ln = ", " & vbCrLf
Next
sql = sql & vbCrLf & ");"
getTableDDL = sql
End Function
Function getIndexDDL(tdef, idx)
Dim sql, ln, myfld
If Left(idx.name, 1) = "{" Then
'ignore, GUID-type indexes - bugger them
ElseIf idx.Foreign Then
'this index was created by a relation. recreating the
'relation will create this for us, so no need to do it here
Else
ln = ""
sql = "CREATE "
If idx.Unique Then
sql = sql & "UNIQUE "
End If
sql = sql & "INDEX " & QuoteObjectName(idx.name) & " ON " & _
QuoteObjectName(tdef.name) & "("
For Each myfld In idx.fields
sql = sql & ln & QuoteObjectName(myfld.name)
ln = ", "
Next
sql = sql & ")"
If idx.Primary Then
sql = sql & " WITH PRIMARY"
ElseIf idx.IgnoreNulls Then
sql = sql & " WITH IGNORE NULL"
ElseIf idx.Required Then
sql = sql & " WITH DISALLOW NULL"
End If
sql = sql & ";"
End If
getIndexDDL = sql
End Function
' Returns the SQL DDL to add a relation between two tables.
' Oddly, DAO will not accept the ON DELETE or ON UPDATE
' clauses, so the resulting sql must be executed through ADO
Function getRelationDDL(myrel)
Const dbRelationUpdateCascade = 256
Const dbRelationDeleteCascade = 4096
Dim mytdef
Dim myfld
Dim sql, ln
With myrel
sql = "ALTER TABLE " & QuoteObjectName(.ForeignTable) & _
" ADD CONSTRAINT " & QuoteObjectName(.name) & " FOREIGN KEY ("
ln = ""
For Each myfld In .fields 'ie fields of the relation
sql = sql & ln & QuoteObjectName(myfld.ForeignName)
ln = ","
Next
sql = sql & ") " & "REFERENCES " & _
QuoteObjectName(.table) & "("
ln = ""
For Each myfld In .fields
sql = sql & ln & QuoteObjectName(myfld.name)
ln = ","
Next
sql = sql & ")"
If (myrel.Attributes And dbRelationUpdateCascade) Then _
sql = sql & " ON UPDATE CASCADE"
If (myrel.Attributes And dbRelationDeleteCascade) Then _
sql = sql & " ON DELETE CASCADE"
sql = sql & ";"
End With
getRelationDDL = sql
End Function
Function isSystemTable(tbl)
Dim nAttrib
Const dbSystemObject = -2147483646
isSystemTable = False
nAttrib = tbl.Attributes
isSystemTable = (nAttrib <> 0 And ((nAttrib And dbSystemObject) <> 0))
End Function
Function isHiddenTable(tbl)
Dim nAttrib
Const dbHiddenObject = 1
isHiddenTable = False
nAttrib = tbl.Attributes
isHiddenTable = (nAttrib <> 0 And ((nAttrib And dbHiddenObject) <> 0))
End Function
Function QuoteObjectName(str)
QuoteObjectName = "[" & str & "]"
End Function
CREATE VIEW foo AS ...
Syntax erstellen, in der Tat bin ich mir nicht sicher, können Sie (?)Dim oApplication
Set oApplication = CreateObject("Access.Application")
oApplication.OpenCurrentDatabase sMyAccessFilePath
oApplication.Visible = False
For Each myObj In oApplication.DBEngine(0)(0).QueryDefs
writeToFile sExportpath & "\queries\" & myObj.Name & ".sql", myObj.SQL
Next
Function writeToFile(path, text)
Dim fso, st
Set fso = CreateObject("Scripting.FileSystemObject")
Set st = fso.CreateTextFile(path, True)
st.Write text
st.Close
End Function
Option Compare Database
Function exportTableDefs()
Dim db As Database
Dim tdf As TableDef
Dim fld As DAO.Field
Dim ndx As DAO.Index
Dim strSQL As String
Dim strFlds As String
Dim fs, f
Set db = CurrentDb
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.CreateTextFile("C:\temp\Schema.txt")
For Each tdf In db.TableDefs
If Left(tdf.Name, 4) <> "Msys" And Left(tdf.Name, 1) <> "~" Then
strSQL = "CREATE TABLE [" & tdf.Name & "] (" & vbCrLf
strFlds = ""
For Each fld In tdf.Fields
strFlds = strFlds & ",[" & fld.Name & "] "
Select Case fld.Type
Case dbText
'No look-up fields
strFlds = strFlds & "varchar (" & fld.SIZE & ")"
Case dbLong
If (fld.Attributes And dbAutoIncrField) = 0& Then
strFlds = strFlds & "bigint"
Else
strFlds = strFlds & "int IDENTITY(1,1)"
End If
Case dbBoolean
strFlds = strFlds & "bit"
Case dbByte
strFlds = strFlds & "tinyint"
Case dbInteger
strFlds = strFlds & "int"
Case dbCurrency
strFlds = strFlds & "decimal(10,2)"
Case dbSingle
strFlds = strFlds & "decimal(10,2)"
Case dbDouble
strFlds = strFlds & "Float"
Case dbDate
strFlds = strFlds & "DateTime"
Case dbBinary
strFlds = strFlds & "binary"
Case dbLongBinary
strFlds = strFlds & "varbinary(max)"
Case dbMemo
If (fld.Attributes And dbHyperlinkField) = 0& Then
strFlds = strFlds & "varbinary(max)"
Else
strFlds = strFlds & "?"
End If
Case dbGUID
strFlds = strFlds & "?"
Case Else
strFlds = strFlds & "?"
End Select
strFlds = strFlds & vbCrLf
Next
'' get rid of the first comma
strSQL = strSQL & Mid(strFlds, 2) & ")" & vbCrLf
f.WriteLine strSQL
strSQL = ""
'Indexes
For Each ndx In tdf.Indexes
If Left(ndx.Name, 1) <> "~" Then
If ndx.Primary Then
strSQL = "ALTER TABLE " & tdf.Name & " ADD CONSTRAINT " & tdf.Name & "_primary" & " PRIMARY KEY CLUSTERED (" & vbCrLf
Else
If ndx.Unique Then
strSQL = "CREATE UNIQUE NONCLUSTERED INDEX "
Else
strSQL = "CREATE NONCLUSTERED INDEX "
End If
strSQL = strSQL & "[" & tdf.Name & "_" & ndx.Name & "] ON [" & tdf.Name & "] ("
End If
strFlds = ""
''' Assume that the index is only for the first field. This will work for most primary keys
''' Not sure how to get just the fields in the index
For Each fld In tdf.Fields
strFlds = strFlds & ",[" & fld.Name & "] ASC "
Exit For
Next
strSQL = strSQL & Mid(strFlds, 2) & ") "
End If
Next
f.WriteLine strSQL & vbCrLf
End If
Next
f.Close
End Function
Welche Sprache? Ist es wichtig? –
Ich verstehe die Frage nicht wirklich. Der extrahierte Text sollte sich in Access SQL befinden, damit ich die Datenbank bei Bedarf neu erstellen kann. – AngryHacker
Die Sprache kann relevant sein, wenn Sie _not_ für die Verwendung von Access SQL auswählen, z. B. meine Antwort unten, die ADOX von Python verwendet. DDL aus einer Access-Datenbank zu konstruieren ist eine PITA (wie die Ausführlichkeit von Remous Antwort unten zeigt) ... – mavnn