以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.net/bbs/index.asp)
--  专家坐堂  (http://foxtable.net/bbs/list.asp?boardid=2)
----  按照程版的“自动更新表结构”的代码,怎么在我这只能增加的是内部表?  (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=146852)

--  作者:有点蓝
--  发布时间:2020/3/4 11:04:00
--  
看看:http://www.foxtable.com/webhelp/topics/2122.htm
--  作者:有点蓝
--  发布时间:2020/3/4 11:16:00
--  
这段代码只是根据外部数据库的结构创建内部表,并不是创建外部表。

使用外部数据源

前面的代码都是针对内部数据源的,如果要为外部数据源动态创建表和列,只需在定义ADOXBuilder的时候,指定数据源名称即可:

Dim Builder As New ADOXBuilder("数据源名称")

例如在名为nwnd的外部数据源中创建一个订单表:

Dim Builder As New ADOXBuilder("nwnd"\'要指定数据源名称
Dim
 tbl As ADOXTable
Builder.Open() 
tbl = Builder.NewTable(
"订单"\'创建表
With
 tbl
    .AddColumn(
"日期" ,ADOXType.DateTime)
    .AddColumn(
"产品" ,ADOXType.String12)
    .AddColumn(
"客户" ,ADOXType.String20)
    .AddColumn(
"数量" ,ADOXType.Integer)
    .AddColumn(
"备注" ,ADOXType.Text)
End With
Builder.AddTable(tbl) 
\'增加表
Builder.Close()


--  作者:chen37280600
--  发布时间:2020/3/4 11:29:00
--  
我给你外部数据源的,我修改过

\'非开发者才需要检测表升级
If User.Type <> UserTypeEnum.Developer  Then
    If FileSys.FileExists(ProjectPath & "\\Attachments\\addtable.txt") = True \'判断addtable.txt文件是否存在
        Dim s As String = FileSys.ReadAllText(ProjectPath & "\\Attachments\\addtable.txt",Encoding.Default) \'读取该文本文件的内容
        s = s.Replace(chr(10),"").Replace(chr(13),";").Replace(chr(-23636),",") \'支持英文分号和回车分隔多表,支持中英文逗号分割字符列属性和指定长度,以避免手误
        
        Dim Values(),Value1s(),Value2s() As String \'定义字符型数组用于存储多表分割字符串?表名称?列名称和列属性
        
        Values = s.split(";") \'分割多行内容,将分割的内容添加到数组
        
        \'-----------------------------------------------以下代码创建表
        
        For Index As Integer = 0 To Values.Length - 1 \'循环遍历数组
            Value1s = Values(Index).split("/") \'提取表名称到数组
            Dim Builder As New ADOXBuilder("DB") \'定义一个新的ADOXBuilder
            Dim tbl As ADOXTable \'定义一个新的ADOXTable
            If DataTables.Contains(Value1s(0)) = False \'如果已经加载的datatable中不存在已经提取到的表
                Dim lst As List(Of String) \'定义一个字符型集合
                lst = Connections("DB").GetTableNames \'将远程数据库的所有表名称返回到字符串集合【注数据库名称需要根据您的项目自己修改】
                If lst.Contains(Value1s(0))= False Then \'如果后台数据库也不存在已经提取到的表
                    Builder.Open() \'打开ADOXBuilder
                    tbl = Builder.NewTable(Value1s(0)) \'以提取到的表名称创建一个新表
                    Builder.AddTable(tbl,True,True) \'将刚刚创建的表添加到远程数据源中
                    Builder.Close() \'关闭ADOXBuilder
                End If
                DataTables.Load(Value1s(0)) \'动态加载刚刚直接在数据源中已经新添的表
            End If \'到此,从文本文件提取的表肯定已经存在并动态加载了该datatable
            
            \'-----------------------------------------------以下代码创建列
            
            Builder = New ADOXBuilder("DB") \'生成一个新的ADOXBuilder
            Builder.Open() \'打开ADOXBuilder
            Value2s = Value1s(1).split("|") \'分割各列名称和列属性标识的符串,并添加到数组
            With Builder.Tables(Value1s(0))
                For i As Integer = 0 To Value2s.Length - 1 \'循环遍历数组(所需增加的各列)
                    If  DataTables(Value1s(0)).DataCols.Contains(Value2s(i).split("(")(0)) = False \'如果从文本文件提出到的表中不存在刚刚从文本文件中提取到的列
                        
                        If Value2s(i).split("(")(1).split(")")(0) Like "String*" \'判断提取到的列属性标识包含以String为首的字符串,则肯定该列为字符串
                            Dim n As Integer = Value2s(i).split("(")(1).split(")")(0).split(",")(1) \'提取字符型列所需指定的字符长度
                            .AddColumn(Value2s(i).split("(")(0),ADOXType.String,n) \'添加为字符型列并指定字符长度
                        Else \'该列如果属性标识不是字符串列
                            output.show(1)
                            If Value2s(i).split("(")(1).split(")")(0) = "DateTime" \'如果提取到的列属性标识为DateTime,则肯定该列为日期时间型
                                .AddColumn(Value2s(i).split("(")(0),ADOXType.DateTime) \'添加为日期时间型列
                            End If
                            output.show(1)
                            If Value2s(i).split("(")(1).split(")")(0) = "Byte" \'如果提取到的列属性标识为Byte,则肯定该列为微整数型
                                .AddColumn(Value2s(i).split("(")(0),ADOXType.Byte) \'添加为微整数型列
                            End If
                            If Value2s(i).split("(")(1).split(")")(0) = "Short" \'如果提取到的列属性标识为Short,则肯定该列为短整型
                                .AddColumn(Value2s(i).split("(")(0),ADOXType.Short)  \'添加为短整数型列
                            End If
                            If Value2s(i).split("(")(1).split(")")(0) = "Integer"  \'如果提取到的列属性标识为Integer,则肯定该列为整数型
                                .AddColumn(Value2s(i).split("(")(0),ADOXType.Integer)  \'添加为整数型列
                            End If
                            If Value2s(i).split("(")(1).split(")")(0) = "Single" \'如果提取到的列属性标识为Single,则肯定该列为单精度小数型
                                .AddColumn(Value2s(i).split("(")(0),ADOXType.Single)  \'添加为单精度小数型列
                            End If
                            If Value2s(i).split("(")(1).split(")")(0) = "Double" \'如果提取到的列属性标识为Double,则肯定该列为双精度小数型
                                .AddColumn(Value2s(i).split("(")(0),ADOXType.Double) \'添加为双精度小数型列
                            End If
                            If Value2s(i).split("(")(1).split(")")(0) = "Decimal" \'如果提取到的列属性标识为Decimal,则肯定该列为高精度小数型
                                .AddColumn(Value2s(i).split("(")(0),ADOXType.Decimal) \'添加为高精度小数型列
                            End If
                            If Value2s(i).split("(")(1).split(")")(0) = "备注" \'如果提取到的列属性标识为备注,则肯定该列为备注型
                                .AddColumn(Value2s(i).split("(")(0),ADOXType.Text) \'添加为备注型列
                            End If
                            If Value2s(i).split("(")(1).split(")")(0) = "Boolean" \'如果提取到的列属性标识为Boolean,则肯定该列为逻辑型
                                .AddColumn(Value2s(i).split("(")(0),ADOXType.Boolean) \'添加为逻辑型列
                            End If
                        End If
                    End If
                Next
            End With
            Builder.Close() \'关闭ADOXBuilder
            DataTables(Value1s(0)).Fill("sel去掉我ect  * From {" & Value1s(0) & "}","DB",False) \'重新执行提取到的表的fill方法

            
        Next
        FileSys.DeleteFile(ProjectPath & "\\Attachments\\addtable.txt",2,2) \'彻底删除这个addtable.txt文本文件,下次启动系统找不到这个文件,再无需增加列.
    End If
End If
[此贴子已经被作者于2020/3/4 11:30:05编辑过]

--  作者:有点蓝
--  发布时间:2020/3/4 13:48:00
--  
给出完整可测试的代码看看
--  作者:有点蓝
--  发布时间:2020/3/4 15:18:00
--  
addtable.txt这个文件发上来看看
--  作者:程兴刚
--  发布时间:2020/3/4 15:53:00
--  
外部数据源这一句应该这样:

Dim Builder As New ADOXBuilder("远程数据库") \'定义一个新的ADOXBuilder,这一行用于外部数据源!

因为我发布的是内部表示例文件,当时忘记说明了,我去重新编辑一下!


--  作者:程兴刚
--  发布时间:2020/3/4 18:05:00
--  

先删除本楼回复,改时间再仔细研究!



[此贴子已经被作者于2020/3/4 18:18:38编辑过]

--  作者:有点蓝
--  发布时间:2020/3/4 18:11:00
--  
还是有问题的,如果外部表管理中没有添加的表,使用DataTables.Load(Value1s(0))是无法加载进来的,所以下面代码会出错

if  DataTables(Value1s(0)).DataCols.Contains(tn) = False 

因此,如果是外部表,应该使用SQLcommand获取表结构进行判断是否存在列。同时这种方式添加的表是无法DataTables(xxx)这样直接使用的,只能是使用SQLcommand,或者是Fill,或者是绑定到sqltable使用

--  作者:程兴刚
--  发布时间:2020/3/4 18:15:00
--  
哦,我只是修改了以前的,没有测试,明白了,谢谢!
--  作者:chnfo
--  发布时间:2023/2/12 22:54:00
--  
如果要更新数据库表,首先要确保项目、后台数据库里都有这些表。
想通过代码增加后台中没有的表,而且要把项目中的表与后台的表绑定,是不可能的。