2015-01-29 2 views
6

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

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

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

ответ

4

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

GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Indexes - How to access included columns on index

и это найти

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 
+0

Если бы я мог поддержать вас здесь, я бы это сделал. Это было ТОЧНО, что мне нужно. – CottonHill

1

идеальный! Все, что мне нужно было извлечь. Поскольку это было в разделе 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 
+0

Да. Тот же подход. Я рад, что вы разобрались. и так как я могу поддержать тебя, я тогда пойду. – Mehrad

+0

У меня есть большой проект Foxpro для обновления до SQL.огромная помощь здесь, даже может читать определения экрана SCX и автоматически генерировать код управления формой и даже вставлять источник FP в кнопки в виде кода с комментариями, эти индексы были все, что мне не хватало. – CottonHill