vbastringpostgresqlms-accessdata-migration

How do I escape database table and column names for PostgreSQL in VBA?


I'm trying to migrate an Access database to a PostgreSQL DB, and lots of table names or column names have space or number, for instance, table name: "test history" and "123 people", and column name: "test history". I'm keeping getting SQL syntax errors because of these spaces and numbers.

 'create tables in PostgreSQL database
Dim tdf As DAO.TableDef
For Each tdf In CurrentDb.TableDefs
    If Left(tdf.Name, 4) <> "MSys" Then
        Dim strCreateTable As String
        strCreateTable = "CREATE TABLE " &  tdf.Name  & " ("
        For Each fld In tdf.fields
            strCreateTable = strCreateTable &  fld.Name  & " " & GetPostgreSQLDataType(fld.Type) & ","
        Next fld
        strCreateTable = Left(strCreateTable, Len(strCreateTable) - 1) & ")"
        'MsgBox strCreateTable
        cnn.Execute strCreateTable
    End If
Next tdf

Just wondering if there is a way to transfer the output of table name and column name to a string.


Solution

  • I'm trying to migrate an Access database to a PostgreSQL DB

    Good (I'm of the opinion MS Access needs to die a dignified death instead of circling the drain for another 20 years...)

    and lots of table names or column names have space or number, for instance, table name: "test history" and "123 people", and column name: "test history". I'm keeping getting SQL syntax errors because of these spaces and numbers.

    PostgreSQL follows ANSI/ISO SQL so it uses double-quotes " to delimit object-identifiers, whereas Access (aka JET Red and ACE) uses square-brackets [].

    So it's just a matter of ensuring object-identifiers in your SQL strings are delimited with " within the VBA Strings - which isn't that bad as VBA uses "" within a string as an escape-sequence for double-quotes.

    So this should work for you (I've also added some additional whitespace and NULL/NOT NULL` handling too):

    Sub GenerateAndExecuteCreateTableStatements()
    
        ' Create tables in PostgreSQL database
        Dim tdf As DAO.TableDef
        For Each tdf In CurrentDb.TableDefs
            If Left(tdf.Name, 4) <> "MSys" Then
            
                Dim createStmt As String
                createStmt = GetCreateTableSql(tdf)
    
                ' Consider using Debug.Print instead of MsgBox to dump variables:
                Debug.Print createStmt
                cnn.Execute createStmt
    
            End If
        Next tdf
    
    End Sub
    
    Function GetCreateTableSql(tbl As DAO.TableDef)
    
        Dim createStmt As String
        createStmt = "CREATE TABLE """ &  tbl.Name  & """ ("
        
        Dim fld As DAO.Field
        Dim i As Integer
        i = 0
        For Each fld In tbl.Fields
    
            Dim column As String
            column = vbTab & """" & fld.Name & """" & " " & GetPostgreSQLDataType(fld.Type) & Iif(fld.Required, " NOT NULL", " NULL")
    
            If i > 0 Then
                column = "," & vbCrLf & column
            End If
            i = i + 1
    
            createStmt = createStmt & column
         Next
         
        ' Add closing parenthesis:
        createStmt = createStmt & vbCrLf & ")"
    
        ' Return it:
        GetCreateTableSql = createStmt
    
    End Function