2015-01-29 21 views
6

Posso utilizzare GetSchemaTable e GetXMLSchema per ottenere informazioni su tipi di campo, dimensioni ecc. Da un DBF di Foxpro aperto con VFPOLEDB ma non è possibile ottenere alcuna informazione relativa a quali indici sono presenti nelle tabelle/CDX .Come utilizzare VFPOLEDB per ottenere informazioni DBF

Non voglio usare gli indici, solo i criteri su cui è costruito l'indice per aiutarmi a generare i comandi SQL per creare le tabelle su un server SQL e importare i dati.

È possibile eseguire un output DISPLAY STRUCTURE in un file di testo su tutte le tabelle e analizzarlo in VB.NET ma spero che ci sia qualcosa che sto trascurando perché non sono così familiare con la sintassi VB.NET/OLEDB .

risposta

4

Un po 'di ricerca ha dato via questi risultati. Ho iniziato a dare un'occhiata alla proprietà ForeignKey.FKTableSchema e sfortunatamente non a una proprietà .NET. Più tardi le cose sembravano buone quando ho trovato OleDbSchemaGuid.Indexes Field e tutto sembrava a posto fino a quando ho eseguito l'applicazione e il metodo non è supportato da questo provider. Alla fine il seguente articolo illuminato la strada,

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

e questo trovando

L'OleDb e provider ODBC non fornire un built-in metodo catalogo che restituirà non chiave ("Incluso") colonne indice.

Tuttavia è stato un suggerimento davvero interessante che consente di scrivere questa piccola applicazione Console per raccogliere gli indici disponibili nella tabella. Ciò si ottiene interrogando direttamente la tabella dello schema da SQL. L'esempio seguente si trova nella tabella Employees del famoso database di esempio Northwind. Qui si va,

//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(); 

ed infine i risultati,

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 

Tuttavia, in seguito rimuovendo le restrizioni sono riuscito a superare il metodo non è supportata da questo fornitore. errore e ha finito per riassumere in su come questa soluzione più breve,

//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(); 
} 

che si traduce in un'uscita più tempo per risolvere, ma una parte di esso sarebbe

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

Se potessi invitarvi qui vorrei. Questo era ESATTAMENTE quello di cui avevo bisogno. – CottonHill

1

Perfetto! Tutto ciò di cui avevo bisogno per estrarre. Dato che era nella sezione vb.net ho pubblicato il mio codice approssimativo, ho filtrato i campi restituiti in modo da poterne elencare alcuni qui. Restituisce tutte le informazioni pertinenti relative agli indici, anche complessi creati con le espressioni. Verranno restituite tutte le tabelle nel percorso fornito nella stringa di connessione con indici 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

Sì. Lo stesso approccio pure. Sono felice che tu l'abbia risolto. e dato che posso prevederti, allora potrai andare avanti. – Mehrad

+0

Ho un grande progetto Foxpro per l'aggiornamento a SQL.Un enorme aiuto qui, anche in grado di leggere le definizioni della schermata SCX e auto generare il codice di controllo modulo e anche incollare la sorgente FP ai pulsanti come codice commentato, questi indici erano tutto quello che mi mancava. – CottonHill

Problemi correlati