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