Table structures in Access can be migrated to SQL Server using the Import feature in SQL Server Management Studio.
However, there are difficulties with this for a number of reasons, probably the most significant being that SSMS Import will not create identity fields corresponding to Access autonumbers.
The code below will create a script which, when executed in SQL Server, creates all your tables in a SQL database and handles the creation of identities and common types of constraints.
Please note that some assumptions are made about how some data types are translated, and not all situations are handled. Check the output script carefully before you execute it, both for incompatibilities with your intended translation and also for inline error messages.
Function goScriptCreate() As Boolean
Dim fso As Object, oFile As Object, dbs As DAO.Database, tdf As TableDef, fld As DAO.Field, idx As Index, strOutput As String
Dim strPrimaryKey As String, strTypeName As String, strConstraints As String, parTablename As String, boolFldRequired As Boolean
Const cDatabase = "ACF_OurSpace"
Const cDropTables As Boolean = True
Set fso = CreateObject("Scripting.FileSystemObject")
strOutput = Mid(CurrentDb().Name, 1, InStrRev(CurrentDb().Name, "\")) & "TableScripts.txt"
Set oFile = fso.CreateTextFile(strOutput)
oFile.writeline "USE [" & cDatabase & "]"
oFile.writeline "GO"
Set dbs = CurrentDb()
For Each tdf In dbs.TableDefs
parTablename = tdf.Name
strConstraints = ""
If Left(tdf.Name, 1) <> "~" And Left(tdf.Name, 4) <> "MSys" And tdf.Connect = "" Then
strPrimaryKey = getPrimaryKey(tdf.Name)
oFile.writeline " "
oFile.writeline " "
oFile.writeline "/********************************************"
oFile.writeline " " & IIf(cDropTables, "Drop and Create table", "Create new table") & " '" & parTablename & "'"
oFile.writeline " Autoscripted at " & Now()
oFile.writeline "********************************************/"
oFile.writeline " "
oFile.writeline "SET ANSI_NULLS ON"
oFile.writeline "GO"
oFile.writeline "SET QUOTED_IDENTIFIER ON"
oFile.writeline "GO"
If cDropTables Then
oFile.writeline " "
oFile.writeline " "
oFile.writeline "DROP TABLE IF EXISTS [dbo].[" & parTablename & "]"
oFile.writeline "GO"
oFile.writeline " "
oFile.writeline " "
End If
oFile.writeline "CREATE TABLE [dbo].[" & parTablename & "]( "
For Each fld In tdf.Fields
boolFldRequired = (fld.Required) Or (InStr(strPrimaryKey, "[" & fld.Name & "]") > 0)
If fld.Attributes And dbAutoIncrField Then
oFile.writeline " [" & fld.Name & "] [int] IDENTITY(1,1) NOT NULL,"
Else
Select Case fld.Type
Case 1, 2 ' 1=Yes/No, On/Off, True/False, 2=Number (byte)
strTypeName = "Byte"
oFile.writeline " [" & fld.Name & "] [int] " & IIf(boolFldRequired, "NOT ", "") & "NULL,"
Case 3, 4 'Integer
oFile.writeline " [" & fld.Name & "] [int] " & IIf(boolFldRequired, "NOT ", "") & "NULL,"
Select Case fld.Properties("DefaultValue")
Case "Date()"
strConstraints = strConstraints & vbCrLf & "ALTER TABLE [dbo].[" & parTablename & "] ADD CONSTRAINT [DF_" & parTablename & "_" & fld.Name & "] DEFAULT (getdate()) FOR [" & fld.Name & "]"
strConstraints = strConstraints & vbCrLf & "GO"
Case "0"
strConstraints = strConstraints & vbCrLf & "ALTER TABLE [dbo].[" & parTablename & "] ADD CONSTRAINT [DF_" & parTablename & "_" & fld.Name & "] DEFAULT ((0)) FOR [" & fld.Name & "]"
strConstraints = strConstraints & vbCrLf & "GO"
Case vbNullString
Case Else
Debug.Print "Table " & parTablename & "." & fld.Name & "." & fld.Properties("DefaultValue"); ": Unknown constraint"
strConstraints = strConstraints & vbCrLf & "--*********************"
strConstraints = strConstraints & vbCrLf & "-- UNKNOWN CONSTRAINT *"
strConstraints = strConstraints & vbCrLf & "--*********************"
End Select
Case 5
oFile.writeline " [" & fld.Name & "] [money] " & IIf(boolFldRequired, "NOT ", "") & "NULL,"
Case 6, 7, 20 ' 6=Single, 7=double, 20=decimal
oFile.writeline " [" & fld.Name & "] [numeric] (18,4) " & IIf(boolFldRequired, "NOT ", "") & "NULL,"
Case 8 'Date
oFile.writeline " [" & fld.Name & "] [datetime] " & IIf(boolFldRequired, "NOT ", "") & "NULL,"
Case 10
oFile.writeline " [" & fld.Name & "] [nvarchar](" & fld.Size & ") " & IIf(boolFldRequired, "NOT ", "") & "NULL,"
Case 12
oFile.writeline " [" & fld.Name & "] [nvarchar](max) NULL,"
Case 104
If fld.Properties("DisplayControl") <> 109 Then
oFile.writeline "--***********************"
oFile.writeline "-- Field " & fld.Name & Space(15 - Len(fld.Name)) & "*"
oFile.writeline "-- Lookup Data Type " & fld.Type & " *"
oFile.writeline "-- Display Control " & fld.Properties("DisplayControl") & " *"
oFile.writeline "--***********************"
Else
oFile.writeline "--***********************"
oFile.writeline "-- Field " & fld.Name & Space(15 - Len(fld.Name)) & "*"
oFile.writeline "-- Unknown Data Type " & fld.Type & " *"
oFile.writeline "-- Display Control " & fld.Properties("DisplayControl") & " *"
oFile.writeline "--***********************"
End If
Case Else 'not catered for
strTypeName = "N/A"
oFile.writeline "--***********************"
oFile.writeline "-- Field " & fld.Name & Space(15 - Len(fld.Name)) & "*"
oFile.writeline "-- UNKNOWN Data Type " & fld.Type & " *"
oFile.writeline "--***********************"
End Select
End If
Next
oFile.writeline " CONSTRAINT [PK_" & parTablename & "] PRIMARY KEY CLUSTERED"
oFile.writeline "("
oFile.writeline " " & strPrimaryKey & " Asc "
oFile.writeline ")WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] "
oFile.writeline ") ON [PRIMARY] "
oFile.writeline "GO"
oFile.writeline strConstraints
'Else
' Debug.Print tdf.Name
End If
Next
oFile.Close
Set fso = Nothing
Set oFile = Nothing
End Function
Function getPrimaryKey(parTablename As String) As String
Dim dbs As DAO.Database, tdf As TableDef, idx As DAO.Index, strPKs As String, n As Long
On Error GoTo Catch_Error
Set dbs = CurrentDb()
Set tdf = dbs.TableDefs(parTablename)
For Each idx In tdf.Indexes
If idx.Primary Then
For n = 0 To idx.Fields.Count - 1
strPKs = strPKs & IIf(Len(strPKs) = 0, "", ", ") & "[" & idx.Fields(n).Name & "]"
Next
Exit For
End If
Next
getPrimaryKey = strPKs
Proc_Exit:
Set dbs = Nothing
Exit Function
Catch_Error:
MsgBox Err.Description, vbInformation, "Error"
Resume Proc_Exit
Resume
End Function
Function goRemove_DBO()
Dim dbs As DAO.Database, tdf As DAO.TableDef, n As Long, boolShowMessages As Boolean, strNewName As String
On Error GoTo Catch_Error
Set dbs = CurrentDb()
boolShowMessages = False
For Each tdf In dbs.TableDefs
If Left(tdf.Name, 4) = "dbo_" Then
strNewName = Trim(Mid(tdf.Name, 5))
If boolShowMessages Then
Select Case MsgBox("About to rename table " & tdf.Name & " to " & strNewName & ". Do you want to suppress further messages?" & vbCrLf & vbCrLf _
& "Click OK to continue processing without warning messages, No to continue processing and continue with warning messages, or Cancel to stop the process.", vbYesNoCancel, "Continue rename process?")
Case vbCancel
GoTo Proc_Exit
Case vbYes
boolShowMessages = False
End Select
End If
tdf.Name = Trim(Mid(tdf.Name, 5))
n = n + 1
End If
Next tdf
MsgBox n & " tables fixed.", vbInformation, "Remove dbo prefix"
Proc_Exit:
Set dbs = Nothing
Exit Function
Catch_Error:
MsgBox Err.Description & vbCrLf & vbCrLf & "Cannot fix table names.", vbInformation, "Error: " & Err.Number
Resume Proc_Exit
Resume
End Function