Как использовать VFPOLEDB для получения информации DBF

Я могу использовать GetSchemaTable а также GetXMLSchema получить информацию о типах полей, размерах и т. д. из DBF Foxpro, открытого с помощью VFPOLEDB, но не может получить никакой информации, касающейся индексов в таблицах /CDX.

Я не хочу использовать индексы, только критерии, на которых построен индекс, чтобы помочь мне в создании команд SQL для создания таблиц на сервере SQL и импорта данных.

Я мог бы сделать DISPLAY STRUCTURE вывод в текстовый файл на всех таблицах и анализ его в VB.NET, но я надеюсь, что есть что-то, что я упускаю из виду, так как я еще не настолько знаком с синтаксисом VB.NET/OLEDB.

2 ответа

Решение

Немного исследований дали эти результаты. Я начал с того, что посмотрел на ForeignKey.FKTableSchema Собственность и, к сожалению, не собственность.NET. Позже все выглядело хорошо, когда я нашел поле OleDbSchemaGuid.Indexes, и все выглядело хорошо, пока я не запустил приложение и не получил метод, который не поддерживается этим провайдером. В конце концов следующая статья озарила путь,

GetOleDbSchemaTable (OleDb.OleDbSchemaGuid.Indexes - как получить доступ к включенным столбцам в индексе

и это открытие

Поставщики OleDb и Odbc не предоставляют встроенный метод каталога, который будет возвращать неключевые ("включенные") столбцы индекса.

Однако это было действительно интересное предложение, которое позволило написать это маленькое консольное приложение для вас, чтобы собрать индексы, доступные в таблице. Это достигается путем прямого запроса таблицы схемы из SQL. Следующий пример включен Employees стол знаменитых Northwind Пример базы данных. Ну вот,

//Open a connection to the SQL Server Northwind database.
var connectionString =
    "Provider=SQLOLEDB;Data Source=SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=SSPI;Encrypt=False;TrustServerCertificate=False";

using (var connection = new OleDbConnection(connectionString))
{
    connection.Open();

    var select = "SELECT " +
        "    T.name                  AS TABLE_NAME" +
        "  , IX.name                 AS INDEX_NAME" +
        "  , IC.index_column_id      AS IX_COL_ID" +
        "  , C.name                  AS COLUMN_NAME" +
        "  , IC.is_included_column   AS INCLUDED_NONKEY" +
        "  " +
        "FROM " +
        "    sys.tables T " +
        "    INNER JOIN sys.indexes IX" +
        "        ON T.object_id = IX.object_id     " +
        "    INNER JOIN sys.index_columns IC" +
        "        ON IX.object_id = IC.object_id " +
        "        AND IX.index_id = IC.index_id " +
        "    INNER JOIN sys.columns C" +
        "        ON IC.object_id = C.object_id " +
        "        AND IC.column_id = C.column_id " +
        "  " +
        "WHERE T.name = 'Employees'" +
        "ORDER BY IC.index_column_id";
    OleDbCommand cmd = new OleDbCommand(@select, connection);
    cmd.CommandType = CommandType.Text;
    var outputTable = new DataSet("Table");
    var my = new OleDbDataAdapter(cmd).Fill(outputTable);

    foreach (DataTable table in outputTable.Tables)
    {
        foreach (DataRow myField in table.Rows)
        {
            //For each property of the field...
            foreach (DataColumn myProperty in table.Columns)
            {
                //Display the field name and value.
                Console.WriteLine(myProperty.ColumnName + " = " +
                                  myField[myProperty].ToString());
            }
            Console.WriteLine();
        }
    }
}
Console.ReadLine();

и наконец результаты,

TABLE_NAME = Employees
INDEX_NAME = PK_Employees
IX_COL_ID = 1
COLUMN_NAME = EmployeeID
INCLUDED_NONKEY = False

TABLE_NAME = Employees
INDEX_NAME = LastName
IX_COL_ID = 1
COLUMN_NAME = LastName
INCLUDED_NONKEY = False

TABLE_NAME = Employees
INDEX_NAME = PostalCode
IX_COL_ID = 1
COLUMN_NAME = PostalCode
INCLUDED_NONKEY = False

Однако позже, сняв ограничения, которые мне удалось преодолеть, этот метод не поддерживается этим провайдером. ошибка и в итоге суммировать это как это более короткое решение,

//Open a connection to the SQL Server Northwind database.
var connectionString =
    "Provider=SQLOLEDB;Data Source=SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=SSPI;Encrypt=False;TrustServerCertificate=False";

using (OleDbConnection cnn = new OleDbConnection(connectionString))
{
    cnn.Open();
    DataTable schemaIndexess = cnn.GetSchema("Indexes",
        new string[] {null, null, null});
    DataTable schemaIndexes = cnn.GetOleDbSchemaTable(
        OleDbSchemaGuid.Indexes,
        new object[] {null, null, null});

    foreach (DataRow myField in schemaIndexes.Rows)
    {
        //For each property of the field...
        foreach (DataColumn myProperty in schemaIndexes.Columns)
        {
            //Display the field name and value.
            Console.WriteLine(myProperty.ColumnName + " = " +
                              myField[myProperty].ToString());
        }
        Console.WriteLine();
    }


    Console.ReadLine();
}

Что приводит к более длинному выводу, чтобы разобраться, но часть его будет

TABLE_CATALOG = Northwind
TABLE_SCHEMA = dbo
TABLE_NAME = Employees
INDEX_CATALOG = Northwind
INDEX_SCHEMA = dbo
INDEX_NAME = LastName
PRIMARY_KEY = False
UNIQUE = False
CLUSTERED = False
TYPE = 1
FILL_FACTOR = 0
INITIAL_SIZE =
NULLS =
SORT_BOOKMARKS = False
AUTO_UPDATE = True
NULL_COLLATION = 4
ORDINAL_POSITION = 1
COLUMN_NAME = LastName
COLUMN_GUID =
COLUMN_PROPID =
COLLATION = 1
CARDINALITY =
PAGES = 1
FILTER_CONDITION =
INTEGRATED = False

Отлично! Все, что мне нужно было извлечь. Так как это было в разделе vb.net, я разместил свой грубый код, я отфильтровал возвращаемые поля, чтобы я мог перечислить несколько здесь. Он возвращает всю соответствующую информацию, относящуюся к индексам, даже сложные, созданные с помощью выражений. Будут возвращены все таблицы в пути, указанном в строке подключения с индексами CDX.

 TABLE_NAME = schematest
 INDEX_NAME = char3ascen
 NULLS = 1
 EXPRESSION = char3ascen

 TABLE_NAME = schematest
 INDEX_NAME = expressn
 NULLS = 2
 EXPRESSION = LEFT(char1null,4)+SUBSTR(char2,4,2)

 TABLE_NAME = schematest
 INDEX_NAME = multifld
 NULLS = 2
 EXPRESSION = char1null+char2

 TABLE_NAME = customer
 INDEX_NAME = zip
 NULLS = 1
 EXPRESSION = zip


    Private Sub GetIndexInfo_Click(sender As Object, e As EventArgs) Handles GetIndexInfo.Click
    Dim cnnOLEDB As New OleDbConnection
    Dim SchemaTable As DataTable
    Dim myField As DataRow
    Dim myProperty As DataColumn
    Dim ColumnNames As New List(Of String)
    Dim strConnectionString = "Provider=vfpoledb;Data Source=D:\ACW\;Collating Sequence=general;DELETED=False"
    cnnOLEDB.ConnectionString = strConnectionString
    cnnOLEDB.Open()
    ColumnNames.Add("TABLE_NAME")
    columnnames.Add("INDEX_NAME")
    columnnames.Add("NULLS")
    columnnames.Add("TYPE")
    columnnames.Add("EXPRESSION")

    SchemaTable = cnnOLEDB.GetSchema("Indexes")
    'For Each myProperty In SchemaTable.Columns
    For Each myField In SchemaTable.Rows
        For Each myProperty In SchemaTable.Columns
            If ColumnNames.Contains(myProperty.ColumnName) Then
                Console.WriteLine(myProperty.ColumnName & " = " & myField(myProperty).ToString)
            End If
        Next
        Console.WriteLine()
    Next
    Console.ReadLine()
    DGVSchema.DataSource = SchemaTable

End Sub
Другие вопросы по тегам