Инструмент для сравнения структуры БД MS ACCESS и SQL Server?

#sql-server #compare

#sql-сервер #Сравнить

Вопрос:

Недавно я перенес базу данных MS Access на SQL Server, в основном она была импортирована просто отлично, но есть некоторые различия в типах данных, которые я хотел бы найти с помощью какого-нибудь инструмента, если он доступен.

Инструменты, которые я нашел до сих пор, сравнивают MS Access с MS Access или SQL Server только с SQL Server.

Комментарии:

1. Не знаю насчет сравнения, но для миграции базы данных вы можете проверить свой ispirer.

Ответ №1:

Проблема в том, что Access (или JET Red) не имеет единого канонического API для работы со своей моделью данных, вместо этого вы в основном используете драйвер OLE-DB или ODBC-драйвер. Я думаю (но не могу подтвердить), что у программы Office Access GUI, вероятно, есть собственный внутренний API, который обходит абстракции OLE-DB или ODBC, к сожалению, программа GUI не использует специальную техническую терминологию в таких вещах, как конструктор таблиц (например, Number > Integer не указывает, является ли это 16, 32 или 64-разрядным целым числом, и Number > Replication ID это вообще не число, а Win32 GUID).

По состоянию на 2019 год Microsoft, по-видимому, понизила приоритетность OLE-DB по сравнению с низкоуровневым ODBC API для JET Red, но это нормально, потому что ODBC по-прежнему предоставляет нам необходимые детали для определения дизайна таблицы базы данных.

В любом случае — хорошей новостью является то, что вам не обязательно нужен инструмент для сравнения базы данных Access (JET Red) с базой данных SQL Server, потому что спецификации таблицы ODBC легко получить самостоятельно.

Что-то вроде этого:

 Dictionary<String,DataTable> jetTables = new Dictionary<String,DataTable>();

using( OleDbConnection jetConnection = new OleDbConnection( "your-access-connection-string") )
{
    await jetConnection.OpenAsync().ConfigureAwait(false);

    DataTable schemaTable = connection.GetOleDbSchemaTable(
        OleDbSchemaGuid.Tables,
        new object[] { null, null, null, "TABLE" }
    );

    foreach( DataRow row in schemaTable.Rows.Cast<DataRow>() )
    {
        String tableName = (String)row.ItemArray[2];

        DataTable tableSchema = connection.GetOleDbSchemaTable(
            OleDbSchemaGuid.Tables,
            new object[] { null, null, tableName, "TABLE" }
        );

        jetTables.Add( tableName, tableSchema );
    } 
}

Dictionary<String,DataTable> sqlTables = new Dictionary<String,DataTable>();

using( SqlConnection sqlConnection = new SqlConnection( "your-sql-server-connection-string" ) )
{
    await sqlConnection.OpenAsync().ConfigureAwait(false);

    DataTable allTables = new DataTable();
    using( SqlCommand cmd1 = sqlConnection.CreateCommand() )
    {
        cmd1.CommandText = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES";

        using( SqlDataReader rdr1 = await cmd1.ExecuteReaderAsync.ConfigureAwait(false) )
        {
            allTables.Load( rdr1 );
        }
    }

    foreach( DataRow row in allTables.Rows.Cast<DataRow>() )
    {
        String tableName = (String)row.ItemArray[0];

        using( SqlCommand cmd2 = sqlConnection.CreateCommand() )
        {
            cmd2.CommandText = "SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName";
            cmd2.Parameters.Add( "@tableName", SqlDbType.NVarChar ).Value = tableName;

            using( SqlDataReader rdr2 = await cmd2.ExecuteReaderAsync.ConfigureAwait(false) )
            {
                DataTable dt = new DataTable();
                dt.Load( rdr2 );
                sqlTables.Add( tableName, dt );
            }
        } 
    }
} 
  

Затем сравните jetTables с sqlTables по своему усмотрению.