【问题标题】:How to use VFPOLEDB to get DBF information如何使用VFOLEDB获取DBF信息
【发布时间】:2015-01-29 19:23:25
【问题描述】:

我可以使用GetSchemaTableGetXMLSchema 从使用 VFPOLEDB 打开的 Foxpro DBF 中获取有关字段类型、大小等的信息,但无法获取有关表/CDX 中的索引的任何信息。

我不想使用索引,只是建立索引的条件来帮助我生成 SQL 命令以在 SQL 服务器上创建表并导入数据。

我可以将DISPLAY STRUCTURE 输出到所有表上的文本文件并在 VB.NET 中解析它,但我希望有一些我忽略的东西,因为我对 VB.NET/OLEDB 语法不太熟悉还没有。

【问题讨论】:

    标签: vb.net oledb foxpro visual-foxpro


    【解决方案1】:

    一点点研究就泄露了这些结果。我开始查看ForeignKey.FKTableSchema 属性,不幸的是不是.NET 属性。后来,当我找到 OleDbSchemaGuid.Indexes Field 时,一切看起来都很好,直到我运行应用程序并得到 此提供程序不支持该方法。 最终,以下文章点亮一路走来,

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

    这个发现

    OleDb 和 Odbc 提供程序不提供内置目录方法 这将返回非键(“包含”)索引列。

    然而,这是一些非常有趣的建议,可以让您编写这个小控制台应用程序来获取表中可用的索引。这是通过直接从 SQL 查询模式表来实现的。以下示例在著名的Northwind 示例数据库的Employees 表上。给你,

    //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
    

    【讨论】:

    • 如果我能在这里投票给你,我会的。这正是我所需要的。
    【解决方案2】:

    完美! 我需要提取的一切。由于它在 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
    

    【讨论】:

    • 是的。同样的方法也是如此。我很高兴你把它整理好了。既然我可以投票给你,我会的,那么你就可以开始了。
    • 我有一个大型 Foxpro 项目要升级到 SQL.huge 帮助在这里,甚至可以读取 SCX 屏幕定义并自动生成表单控制代码,甚至将 FP 源代码粘贴到按钮作为注释代码,这些索引是我所缺少的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 2018-07-10
    • 2021-01-09
    • 2013-04-23
    • 2011-03-07
    相关资源
    最近更新 更多