Sql server 用于比较数据库结构MS ACCESS和SQL Server的工具?

Sql server 用于比较数据库结构MS ACCESS和SQL Server的工具?,sql-server,compare,Sql Server,Compare,我最近将一个MS Access数据库迁移到了SQL Server,大部分都是很好地导入的,但是如果可用的话,我希望使用一些工具来发现一些数据类型的差异 到目前为止,我找到的工具将MS Access与MS Access或SQL Server与SQL Server进行了比较。问题在于Access(或JET Red)没有一个用于处理其数据模型的规范API,而您主要使用OLE-DB驱动程序或ODBC驱动程序。我认为(但无法确认)Office Access GUI程序可能有自己的内部API,绕过OLE-D

我最近将一个MS Access数据库迁移到了SQL Server,大部分都是很好地导入的,但是如果可用的话,我希望使用一些工具来发现一些数据类型的差异

到目前为止,我找到的工具将MS Access与MS Access或SQL Server与SQL Server进行了比较。

问题在于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年,与JET Red的较低级别ODBC API相比,微软似乎已经降低了OLE-DB的优先级,但这没关系,因为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 );
            }
        } 
    }
} 
Dictionary jetTables=newdictionary();
使用(OleDbConnection jetConnection=新OleDbConnection(“您的访问连接字符串”))
{
await jetConnection.OpenAsync().ConfigureAwait(false);
DataTable schemaTable=connection.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables,
新对象[]{null,null,null,“表”}
);
foreach(schemaTable.Rows.Cast()中的DataRow行)
{
String tableName=(String)row.ItemArray[2];
DataTable tableSchema=connection.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables,
新对象[]{null,null,tableName,“TABLE”}
);
Add(tableName,tableSchema);
} 
}
字典sqlTables=新字典();
使用(SqlConnection SqlConnection=newsqlconnection(“您的sql server连接字符串”))
{
await sqlConnection.OpenAsync().ConfigureAwait(false);
DataTable allTables=新DataTable();
使用(SqlCommand cmd1=sqlConnection.CreateCommand())
{
cmd1.CommandText=“从信息\u SCHEMA.TABLES中选择表\u名称”;
使用(SqlDataReader rdr1=await cmd1.ExecuteReaderAsync.ConfigureAwait(false))
{
allTables.Load(rdr1);
}
}
foreach(allTables.Rows.Cast()中的DataRow行)
{
String tableName=(String)row.ItemArray[0];
使用(SqlCommand cmd2=sqlConnection.CreateCommand())
{
cmd2.CommandText=“从信息_SCHEMA.COLUMNS中选择列_NAME、数据_TYPE,其中TABLE_NAME=@tableName”;
cmd2.Parameters.Add(“@tableName”,SqlDbType.NVarChar).Value=tableName;
使用(SqlDataReader rdr2=await cmd2.ExecuteReaderAsync.ConfigureAwait(false))
{
DataTable dt=新的DataTable();
dt.荷载(rdr2);
Add(tableName,dt);
}
} 
}
} 
然后将
jetTables
sqlTables
进行比较,如您所愿。

问题在于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年,与JET Red的较低级别ODBC API相比,微软似乎已经降低了OLE-DB的优先级,但这没关系,因为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 );
            }
        } 
    }
} 
Dictionary jetTables=newdictionary();
使用(OleDbConnection jetConnection=新OleDbConnection(“您的访问连接字符串”))
{
await jetConnection.OpenAsync().ConfigureAwait(false);
DataTable schemaTable=connection.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables,
新对象[]{null,null,null,“表”}
);
foreach(schemaTable.Rows.Cast()中的DataRow行)
{
String tableName=(String)row.ItemArray[2];
DataTable tableSchema=connection.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables,
新对象[]{null,null,tableName,“TABLE”}
);
Add(tableName,tableSchema);
} 
}
字典sqlTables=新字典();
使用(SqlConnection SqlConnection=newsqlconnection(“您的sql server连接字符串”))
{
await sqlConnection.OpenAsync().ConfigureAwait(false);
DataTable allTables=新DataTable();
使用(SqlCommand cmd1=sqlConnection.CreateCommand())
{
cmd1.CommandText=“从信息\u SCHEMA.TABLES中选择表\u名称”;
使用(SqlDataReader rdr1=await cmd1.ExecuteReaderAsync.ConfigureAwait(false))
{
allTables.Load(rdr1);
}
}
foreach(allTables.Rows.Cast()中的DataRow行)
{
String tableName=(String)row.ItemArray[0];
使用(SqlCommand cmd2=sqlConnection.CreateCommand())
{
cmd2.CommandText=“从信息\u SCHEMA.COLUMNS中选择列\u名称、数据\u类型,其中TABLE\u NAME=@TABLE