以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.net/bbs/index.asp)
--  专家坐堂  (http://foxtable.net/bbs/list.asp?boardid=2)
----  [求助]遍历ql server数据源的列时出错  (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=179432)

--  作者:2425004926
--  发布时间:2022/8/23 13:53:00
--  [求助]遍历ql server数据源的列时出错
老师指点一下,问题在哪里
我在遍历数据源 - 表 - 列时,如果全部是Access数据源,也不判断数据源类型(就是绿色代码不用)时,没有任何问题; 如果是sql server数据源遍历时就会出错
显示 name不是system.data.DataColumn的成员

Dim ss As New StringBuilder \'定义长字符串

For Each cn As Connection In Connections \'----------------------------------遍历数据源
    \'Output.Show("数据源名称:" & cn.Name)
    \'Output.Show("链接字符串:" & cn.ConnectionString)
    
    Dim lst As List(Of String)
    lst = Connections(cn.Name).GetTableNames \'返加数据源的所有表集合
    
    For Each nm As String In lst \'------------------------------------------遍历表
        \'Output.Show("表名称:" & nm)
        
        Dim ada As New Data.OleDB.OleDbDataAdapter("Select *  F rom " & nm & " Where [_indentify] is null", cn.ConnectionString)
        Dim dt As New Data.DataTable
        ada.FillSchema (dt, System.Data.SchemaType.Source)
        For Each dc As data.DataColumn In dt.Columns \'----------------------遍历列
            \'数据源|表名称|列名称|列标题|列类型|列长度---共6个
            
            If cn.SourceType = 1 Then \'-------------------------------------Access类型,用dc.caption,用dc.name出错
                If dc.DataType.name = "String" Then \'不能用dc.IsString
                    ss.Appendline(cn.Name & "|" & nm & "||" & dc.caption & "|" & dc.DataType.name & "|" & dc.MaxLength) \'字符串列+长度
                Else
                    ss.Appendline(cn.Name & "|" & nm & "||" & dc.caption & "|" & dc.DataType.name)
                End If
            ElseIf cn.SourceType = 2 Then \'---------------------------------SQL Server类型,用dc.name
                If dc.DataType.name = "String" Then \'不能用dc.IsString
                    ss.Appendline(cn.Name & "|" & nm & "|" & dc.name & "||" & dc.DataType.name & "|" & dc.MaxLength) \'字符串列+长度
                Else
                    ss.Appendline(cn.Name & "|" & nm & "|" & dc.name & "||" & dc.DataType.name)
                End If
            End If

        Next
    Next
Next

Dim dlg As New SaveFileDialog \'定义一个新保存文件对话框
dlg.Filter = "文本文件|*.txt" \'设置筛选器
If dlg.ShowDialog = DialogResult.Ok Then \'如果用户单击了确定按钮
    FileSys.WriteAllText(dlg.FileName, ss.Tostring, False, Encoding.Default) \'保存为记事本文件
End If

--  作者:有点蓝
--  发布时间:2022/8/23 13:59:00
--  
name是Foxtable自己包装的名称。如果使用.net的方法,列名是ColumnName。
--  作者:2425004926
--  发布时间:2022/8/23 14:29:00
--  
 那要怎么改,红色的部分我都试着改了,测试还是没成
For Each dc As data.DataColumn In dt.Columns \'----------------------遍历列
    If dc.DataType.Name = "String" Then \'不能用dc.IsString
        ss.Appendline(cn.Name & "|" & nm & "|" & dc.ColumnName & "||" & dc.DataType.ColumnName & "|" & dc.MaxLength) \'字符串列+长度
    Else
        ss.Appendline(cn.Name & "|" & nm & "|" & dc.ColumnName & "||" & dc.DataType.ColumnName )
    End If
Next
--  作者:有点蓝
--  发布时间:2022/8/23 14:38:00
--  
不是一个人叫张三,所有人都叫张三。DataType是数据类型,不是列名

ss.Appendline(cn.Name & "|" & nm & "|" & dc.ColumnName & "||" & dc.DataType.Name 
--  作者:2425004926
--  发布时间:2022/8/23 16:42:00
--  
问题终于找到了,红色标记
SQL Server类型_indentify会出错,显示列名无效,用_SortKey则可以
Access类型_indentify_SortKey都可以


Dim ss As New StringBuilder \'定义长字符串

For Each cn As Connection In Connections \'----------------------------------遍历数据源
    \'Output.Show("数据源名称:" & cn.Name)
    \'Output.Show("链接字符串:" & cn.ConnectionString)
    
    Dim lst As List(Of String)
    lst = Connections(cn.Name).GetTableNames \'返加数据源的所有表集合
    
    For Each nm As String In lst \'------------------------------------------遍历表
        \'Output.Show("表名称:" & nm)
        If cn.SourceType = 1 Then \'----------------------------------Access类型,dc.ColumnName和dc.caption一样
            Dim ada As New Data.OleDB.OleDbDataAdapter("Select *  F rom " & nm & " Where [_indentify] is null", cn.ConnectionString)
            Dim dt As New Data.DataTable
            ada.FillSchema (dt, System.Data.SchemaType.Source)
            For Each dc As data.DataColumn In dt.Columns \'------------------遍历列
                \'数据源|表名称|列名称|列类型|列长度---共5个
                
                If dc.DataType.name = "String" Then \'不能用dc.IsString
                    ss.Appendline(cn.Name & "|" & nm & "|" & dc.ColumnName & "|" & dc.DataType.name & "|" & dc.MaxLength) \'字符串列+长度
                Else
                    ss.Appendline(cn.Name & "|" & nm & "|" & dc.ColumnName & "|" & dc.DataType.name)
                End If
            Next
        ElseIf cn.SourceType = 2 Then \'------------------------------SQL Server类型,dc.ColumnName和dc.caption一样
            Dim ada As New Data.OleDB.OleDbDataAdapter("Select *  F rom " & nm & " Where [_SortKey] is null", cn.ConnectionString)
            Dim dt As New Data.DataTable
            ada.FillSchema (dt, System.Data.SchemaType.Source)
            For Each dc As data.DataColumn In dt.Columns \'-------------------遍历列
                \'数据源|表名称|列名称|列类型|列长度---共5个
                
                If dc.DataType.name = "String" Then \'不能用dc.IsString
                    ss.Appendline(cn.Name & "|" & nm & "|" & dc.ColumnName & "|" & dc.DataType.name & "|" & dc.MaxLength) \'字符串列+长度
                Else
                    ss.Appendline(cn.Name & "|" & nm & "|" & dc.ColumnName & "|" & dc.DataType.name)
                End If
            Next
        End If
    Next
Next

Dim dlg As New SaveFileDialog \'定义一个新保存文件对话框
dlg.Filter = "文本文件|*.txt" \'设置筛选器
If dlg.ShowDialog = DialogResult.Ok Then \'如果用户单击了确定按钮
    FileSys.WriteAllText(dlg.FileName, ss.Tostring, False, Encoding.Default) \'保存为记事本文件
End If
--  作者:2425004926
--  发布时间:2022/8/23 16:47:00
--  
再补充一点,就是无论什么数据源,表名最好不要加 “(",")" ,否则遍历也出错,
例:有些表不用了,我就在表名后面加了个(暂不用)遍历就出错了

--  作者:有点蓝
--  发布时间:2022/8/23 16:48:00
--  
如果是内置的主键列,名称是_Identify,不是_indentify,不过记得要加中括号
--  作者:2425004926
--  发布时间:2022/8/23 17:01:00
--  
 哎!真让大家见笑了

最终版,OK

Dim ss As New StringBuilder \'定义长字符串

For Each cn As Connection In Connections \'----------------------------------遍历数据源
    \'Output.Show("数据源名称:" & cn.Name)
    \'Output.Show("链接字符串:" & cn.ConnectionString)
    
    Dim lst As List(Of String)
    lst = Connections(cn.Name).GetTableNames \'返加数据源的所有表集合
    
    For Each nm As String In lst \'------------------------------------------遍历表
        \'Output.Show("表名称:" & nm)
        
        Dim ada As New Data.OleDB.OleDbDataAdapter("Select *  F rom " & nm & " Where [_identify] is null", cn.ConnectionString)
        Dim dt As New Data.DataTable
        ada.FillSchema (dt, System.Data.SchemaType.Source)
        
        For Each dc As data.DataColumn In dt.Columns \'----------------------遍历列
            \'数据源|表名称|列名称|列类型|列长度---共5个
            
            If dc.DataType.name = "String" Then \'不能用dc.IsString
                ss.Appendline(cn.Name & "|" & nm & "|" & dc.ColumnName & "|" & dc.DataType.name & "|" & dc.MaxLength) \'字符串列+长度
            Else
                ss.Appendline(cn.Name & "|" & nm & "|" & dc.ColumnName & "|" & dc.DataType.name)
            End If
        Next
    Next
Next

Dim dlg As New SaveFileDialog \'定义一个新保存文件对话框
dlg.Filter = "文本文件|*.txt" \'设置筛选器
If dlg.ShowDialog = DialogResult.Ok Then \'如果用户单击了确定按钮
    FileSys.WriteAllText(dlg.FileName, ss.Tostring, False, Encoding.Default) \'保存为记事本文件
End If