Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 如何在带有vb.net的ms access数据库中添加缺少的列并忽略现有列?_Database_Vb.net_Ms Access_Visual Studio 2012 - Fatal编程技术网

Database 如何在带有vb.net的ms access数据库中添加缺少的列并忽略现有列?

Database 如何在带有vb.net的ms access数据库中添加缺少的列并忽略现有列?,database,vb.net,ms-access,visual-studio-2012,Database,Vb.net,Ms Access,Visual Studio 2012,情况是这样的。我有一个现有的ms access数据库。数据库内部有表1。假设我不知道已经有哪些列或现有列。我的程序使用vb.net表单,只需单击一个按钮,我就可以添加所有列,如姓名、薪资、地址、日期记录和更新。添加所有这些列没有问题,因为它们在表1中不存在。我的问题是在一些数据库表1中,一些列/字段已经存在,如salary和address,我想添加列name、daterec和Update,但它给了我一个错误“表1”中已经存在字段“name”。 我应该怎么做?我只想添加那些表1中还不存在的列。我想

情况是这样的。我有一个现有的ms access数据库。数据库内部有表1。假设我不知道已经有哪些列或现有列。我的程序使用vb.net表单,只需单击一个按钮,我就可以添加所有列,如姓名、薪资、地址、日期记录和更新。添加所有这些列没有问题,因为它们在表1中不存在。我的问题是在一些数据库表1中,一些列/字段已经存在,如salary和address,我想添加列name、daterec和Update,但它给了我一个错误“表1”中已经存在字段“name”。 我应该怎么做?我只想添加那些表1中还不存在的列。我想忽略那些现有列,继续添加那些缺少的列。任何建议都非常感谢

下面是可以添加列和进行修改的代码。谢谢

Dim ConnString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|addcolumn.accdb"


    Dim SqlString As String = "ALTER TABLE Table1 ADD COLUMN " + "name Text(250)," + "salary Number," + "address Memo," + "daterec DateTime," + "updated YesNo" 'Datatypes: Text is ShortText, Number is Number(Double), Memo is LongText, DateTime is Date or/and Time, YesNo is either checkbox/True or False/On or Off depends in saving format .
    Using conn As New OleDbConnection(ConnString)
        Using cmd As New OleDbCommand(SqlString, conn)
            conn.Open()
            cmd.ExecuteNonQuery()
        End Using
    End Using

这里的挑战是,正如你所注意到的? 有些字段可能存在,有些可能不存在。 因此,您必须逐个字段进行测试+添加

像这样的方法应该会奏效:

Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click

    Dim strCon As String
    strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Test\test44.accdb"

    Using dbCon As New OleDbConnection(strCon)
        dbCon.Open()
        AddFieldExist("table1", "name", "Text(250)", dbCon)
        AddFieldExist("table1", "Salary", "number", dbCon)
        AddFieldExist("table1", "Address", "memo", dbCon)
        AddFieldExist("table1", "Address", "memo", dbCon)
        AddFieldExist("table1", "DateRec", "datetime", dbCon)
        AddFieldExist("table1", "Upated", "YesNo", dbCon)

    End Using

End Sub

Sub AddFieldExist(strTable As String,
                    strField As String,
                    strType As String,
                    dbCon As OleDb.OleDbConnection)

    ' return true/false if field exist.

    Dim tblDef As New DataTable
    Dim oReader As New OleDbDataAdapter("SELECT TOP 1 * FROM " & strTable, dbCon)
    oReader.Fill(tblDef)

    If tblDef.Columns.IndexOf(strField) = -1 Then
        ' add field
        Dim strSQL As String = "ALTER TABLE " & strTable & " ADD COLUMN " & strField & " " & strType
        Dim cmd As New OleDbCommand(strSQL, dbCon)
        cmd.ExecuteNonQuery()
    End If

End Sub

代码确实假设问题中的表确实有数据。如果没有,那么您可能必须在这里引入getSchema,但现在,上面的内容正是我的建议。

我不打算提供答案,因为我认为这个问题没有显示出足够的努力,但是,因为我认为被接受的答案不是我想要的呃,我觉得我需要这样做。虽然我只使用了不同的文件名、表名和列名进行了测试,但这段代码执行了我在这里和其他地方针对同一问题提出的建议,应该按原样工作

Dim tableName=“Table1”
将连接用作新的OleDbConnection($“Provider=Microsoft.ACE.OLEDB.12.0;数据源=| DataDirectory | \addcolumn.accdb”)
connection.Open()
'获取包含指定表中所有列信息的DataTable。
Dim schemaTable=connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns,
{无,无,表名})
'创建要添加的所有新列名和数据类型的列表。
Dim dataTypesByColumnName作为{{{“名称”,“文本(250)”}中的新字典(字符串,字符串),
{“工资”,“数字”},
{“地址”,“备忘录”},
{“daterec”,“DateTime”},
{“更新”,“是的”}
'获取表中已存在列名的列表。
Dim existingColumnNames=schemaTable.AsEnumerable()。
选择(函数(行)行。字段(字符串)(“列名称”)。
ToArray()
'创建要插入SQL代码的列定义片段列表,例如“columnName数据类型”。
Dim ColumnSippets=dataTypesByColumnName.Keys.Exception(existingColumnNames)。
选择(函数(键)String.Format(“{0}{1}”),键,dataTypesByColumnName(键)))。
ToArray()
如果是columnsippets.Any(),则
'构造完整的SQL语句。
Dim sql=String.Format(“ALTER TABLE{0}ADD COLUMN{1}”,tableName,String.Join(“,”,columnsippets))
Dim命令作为新的OleDbCommand(sql,连接)
'对数据库执行单个SQL语句。
command.ExecuteNonQuery()命令
如果结束
终端使用

它从数据库中获取现有列的列表,从要添加的列表中排除这些列,然后使用一条SQL语句添加其余列。

连接对象的
GetSchema
GetOleDbSchemaTable
方法可以提供有关架构的信息,包括列。感谢您的帮助,但它没有ork。提示相同错误。表“Table1”中已存在字段“name”。请进行任何修改。@AlbertKallal为什么如果删除“name”,它会继续添加一些列,但如果仍然存在,则列不会添加?我认为“name”“是一个公认的,如果它存在,你就不能添加列。@阿尔伯特卡尔谢谢我的朋友。我只是把“下一步继续出错”,并将“name”列替换为“fullname”。最后,它起作用了。“你必须在一个字段一个字段的基础上进行测试+添加”。不,你绝对不必那样做。那是一种可怕的方式。实际上,您要做的是先确定哪些列已经存在,然后构造一个SQL语句来添加除这些列以外的所有新列。@RonskyPis,任何包含“错误恢复下一步时<代码>的代码都是错误代码,因此任何需要该列的“解决方案”都不是真正的解决方案。如果要添加的列之一失败,那么哪一个失败了?一列一列地添加并不是一个坏主意,因为这会将问题分解为离散操作。结果是代码将添加可以添加的列,并且只需要解决故障点。这在调试代码或隔离失败的部分方面有很多优点。因此,我在这里不会说“不好”,而是说“不同”,对表使用离散操作有很多优点。一次更新可能更好,但这不是一个全有或全无的命题。@AlbertD.Kallal,我一点也不同意。在测试中一列一列地进行测试是一回事。在生产中这样做完全是另一回事。代码已经确保不能添加重复的列,除非在两个数据库操作之间的瞬间有其他人介入。如果某个列的其他特定内容出错,那么首先是因为您编写了错误的代码,例如,数据拼写错误