如何让我的datatable更新-vb.net?

如何让我的datatable更新-vb.net?,vb.net,datatable,Vb.net,Datatable,当Rows.Count>0(屏幕名称在表中)时,状态将不会更新 当我从DataTable中删除所有行以便运行Else子句时,没有添加新行 所以。。。我一定是错过了它是如何更新表的,需要一些帮助。我打赌它相当简单,我只是错过了它:(虽然您已经用选择命令创建了SqlDataAdapter,以便它可以获取数据,但您没有告诉它如何更新或插入数据 这些需要显式地添加到SqlDataAdapter,以便它了解如何执行这些数据更新 我已经模拟了一个如何执行此操作的示例,但它可能不起作用,因为确切的SQL语法将

当Rows.Count>0(屏幕名称在表中)时,状态将不会更新

当我从DataTable中删除所有行以便运行Else子句时,没有添加新行


所以。。。我一定是错过了它是如何更新表的,需要一些帮助。我打赌它相当简单,我只是错过了它:(

虽然您已经用
选择
命令创建了
SqlDataAdapter
,以便它可以获取数据,但您没有告诉它如何
更新
插入
数据

这些需要显式地添加到
SqlDataAdapter
,以便它了解如何执行这些数据更新

我已经模拟了一个如何执行此操作的示例,但它可能不起作用,因为确切的SQL语法将取决于您的表定义:

Dim strSQL as string = "select ScreenName, Status from ScreenCheckDuplicates where ScreenName='" & ScreenName & "'"
Dim aObj as new SqlDataAdapter(strSQL,conn)

dim dtObj as New DataTable
aObj.Fill(dtObj)

If dtObj.Rows.Count > 0 Then
   dtObj.Rows(0)("Status") = Status
   dtObj.AcceptChanges()
Else
   Dim drNew as DataRow = dtObj.NewRow()
   drNew("ScreenName") = ScreenName
   drNew("Status") = Status
   dtObj.Rows.Add(drNew)
   dtObj.AcceptChanges()
End If

描述可用于实现目标的精确方法。

首先,不要连接字符串以创建sql命令。如果字符串包含单引号,则会导致sql注入攻击和语法错误。而应使用参数

Dim aObj As New SqlDataAdapter(strSQL, conn)

' Create the update command
aObj.UpdateCommand = New SqlCommand("UPDATE ScreenCheckDuplicates SET Status = ? WHERE ScreenName = ?")
aObj.UpdateCommand.Parameters.Add("Status", SqlDbType.VarChar)
aObj.UpdateCommand.Parameters.Add("ScreenName", SqlDbType.VarChar)

' Create the insert command
aObj.InsertCommand = New SqlCommand("INSERT INTO ScreenCheckDuplicates VALUES (?, ?)")
aObj.InsertCommand.Parameters.Add("Status", SqlDbType.VarChar)
aObj.InsertCommand.Parameters.Add("ScreenName", SqlDbType.VarChar)
现在一个常见的错误是认为更新了数据库表。这是错误的,AcceptChanges将DataTable对象中每一行的属性从(或其他值)更改为
“DataRowState.Unchanged”
调用后,无法知道哪些行已更改,也无法简单地更新数据库。因此,请删除该行

Dim strSQL as string = "select ScreenName, Status 
                        from ScreenCheckDuplicates 
                        where ScreenName=@name"
Dim aObj as new SqlDataAdapter(strSQL,conn)
aObj.SelectCommand.Parameters.Add("@name", SqlDbType.NVarChar).Value = ScreenName 
dim dtObj as New DataTable
aObj.Fill(dtObj)
此时,您已准备好将更改提交到数据库。您可以使用该对象创建更新行所需的sql命令。但只有在检索到数据库表的主键后,此操作才有效。
因此,假设
ScreenName
是主键,那么您可以编写

If dtObj.Rows.Count > 0 Then
   dtObj.Rows(0)("Status") = Status
Else
   Dim drNew as DataRow = dtObj.NewRow()
   drNew("ScreenName") = ScreenName
   drNew("Status") = Status
   dtObj.Rows.Add(drNew)
End If

我假设ScreenName是ScreenCheckDuplicates表的主键。更新表的方法使用主键

将数据库对象保持在本地,以便您可以控制它们是否已关闭和释放。即使出现错误,也可以使用…End Using块来处理此问题

总是使用参数来避免Sql注入。我不得不猜测SqlDbType和字段大小。检查数据库中的实际值,并相应地调整代码

使用DataAdapter时,您需要提供所需的命令。命令生成器将为您执行此操作。在对DataAdapter使用Update方法之前,不要对DataTable调用.AcceptChanges

Dim builder As SqlCommandBuilder = new SqlCommandBuilder(aObj)
aObj.Update(dtObj)
下面的替代方法要好一点,因为它只需要对数据库进行一次点击

Private Sub OpCode(ScreenName As String, Status As String)
    Using conn As New SqlConnection("Your connection string"),
        cmd As New SqlCommand("select ScreenName, Status from ScreenCheckDuplicates where ScreenName= @ScreenName", conn)
        cmd.Parameters.Add("@ScreenName", SqlDbType.VarChar, 100).Value = ScreenName
        Using aObj As New SqlDataAdapter(cmd)
            Dim dtObj As New DataTable
            aObj.Fill(dtObj)
            Dim cb As New SqlCommandBuilder(aObj)
            If dtObj.Rows.Count > 0 Then
                dtObj.Rows(0)("Status") = Status
                cb.GetUpdateCommand()
            Else
                Dim drNew As DataRow = dtObj.NewRow()
                drNew("ScreenName") = ScreenName
                drNew("Status") = Status
                dtObj.Rows.Add(drNew)
                cb.GetInsertCommand()
            End If
            aObj.Update(dtObj)
            dtObj.AcceptChanges()
        End Using
    End Using
End Sub

您已经创建了一个
SqlDataAdapter
,但没有指定任何方法让它用您的更改更新数据库。您只为它提供了一个
SELECT
语句,您是否正在使用该查询检索表的PrimaryKey?(可能是屏幕名?)这个小表没有主键,但如果我要创建一个,它将是ScreenName,是的。是的,添加主键总是一个好主意。(从我的回答中可以看出,您可以删除许多代码来更新表)
Private Sub BetterWay(ScreenName As String, Status As String)
    Dim strSql = "If EXISTS(SELECT ScreenName, Status FROM ScreenCheckDuplicates where ScreenName= @ScreenName)
        UPDATE ScreenCheckDuplicates SET Status = @Status WHERE ScreenName = @ScreenName
        Else
        INSERT INTO ScreenCheckDuplicates ScreenName, Status VALUES (@ScreenName, @Status)"
    Using cn As New SqlConnection("Your connection string"),
        cmd As New SqlCommand(strSql, cn)
        cmd.Parameters.Add("@ScreenName", SqlDbType.VarChar, 100).Value = ScreenName
        cmd.Parameters.Add("@Status", SqlDbType.VarChar, 50).Value = Status
        cn.Open()
        cmd.ExecuteNonQuery()
    End Using
End Sub