Vb.net 如何在输入新行时检查和更新现有记录日期,或者添加新行

Vb.net 如何在输入新行时检查和更新现有记录日期,或者添加新行,vb.net,Vb.net,在此输入代码SQL表列Clientid、Client_Status、Notes、Startdt、Enddt、Entrydt、Entryid我的当前代码从UI添加数据行,用户输入开始日期、状态和备注 Enddt默认为9/9/9999。我需要将代码更改为-每当新的reord/Status被激怒时,使用该Clientid检查现有记录/状态, 如果存在记录,则将现有记录的EndDt从9999年9月更新为StartDt-1新记录StartDt,新记录StartDt是从界面输入的。否则输入为新客户机 Pri

在此输入代码SQL表列Clientid、Client_Status、Notes、Startdt、Enddt、Entrydt、Entryid我的当前代码从UI添加数据行,用户输入开始日期、状态和备注 Enddt默认为9/9/9999。我需要将代码更改为-每当新的reord/Status被激怒时,使用该Clientid检查现有记录/状态, 如果存在记录,则将现有记录的EndDt从9999年9月更新为StartDt-1新记录StartDt,新记录StartDt是从界面输入的。否则输入为新客户机

Private Sub BtnAddStatus_Click(sender As System.Object, e As System.EventArgs) Handles BtnAddStatus.Click

    Clientid = txtboxClid.Text
    Client_Status = cbboxStatus.Text
    StartDt = txtStartDt.Text
            notes = txtnote.Text


               conn = New SqlClient.SqlConnection("conneting string")
        Dim theQuery As String = "select * from Table name where Clientid = @Clientid and EndDt = '9/9/9999'"
        Dim cmd2 As SqlCommand = New SqlCommand(theQuery, conn)
        cmd2.Parameters.AddWithValue("@Clientid", txtboxClid.Text)

        conn.Open()
        If txtboxClid.Text.Trim <> "" And txtStartDt.Text.Trim <> "" Then
            Using reader As SqlDataReader = cmd2.ExecuteReader()
                If reader.HasRows Then
                    Dim query2 As String = "UPDATETable name SET ([EndDt] = SELECT (todate(StartDt)-1) FROM Table name WHERE Clientid = @Clientid and EndDt ='9/9/9999')"
                    reader.Close()

                End If
            End Using

            Dim query As String = "INSERT INTO Table name (Clientid, Client_Status, Notes, Startdt,Enddt, Entrydt, Entryid) VALUES ('" & Clientid & "','" & Client_Status & "','" & Notes & "','" & StartDt & "',getdate(),'" & UName & "');"
            Dim command = New SqlCommand(query, myconn)
            command.ExecuteNonQuery()

            MsgBox("Status Added ")

            conn.Close()

            Call GetInfoClientid()
    End If
    End If
End Sub

这应该在存储过程中处理。但是,既然你已经完成了这里的大部分工作,我建议在这方面做一个小的改变,这将是可行的。首先,删除更新前的检查,并将更新查询更改为:

Dim query2 As String = "UPDATE Table name SET [EndDt] = todate(@StartDt)-1 WHERE Clientid = @ClientId and EndDt ='9/9/9999'"
Dim cmd As SqlCommand = new SqlCommand(query2, vbConn);
cmd.AddParam(“@StartDt”,StartDt)
cmd.AddParam("@Clientid",ClientId)
假设clientid是varchar,因为在insert语句中使用了单引号


另外,请为query2编写executenonquery语句。

原因很简单,因为您没有执行query2中存储的命令,但您的代码存在其他错误,可能会导致灾难性后果

首先,您应该始终使用参数,而不要连接字符串来构建sql命令。如果您连接字符串,您将启用一个名为的简单技巧,允许任何人攻击您的数据库

其次,您可以直接调用更新,而无需检查是否存在以前的相关记录。如果记录不存在,则更新将返回并更改0条记录

最后,应在需要时创建连接等一次性对象,并尽快进行处理。Using语句用于此目的

Dim Client_Status As String = cbboxStatus.Text
Dim notes As String = txtnote.Text

' Suppose Clientid is a number not a string
Dim Clientid as Integer = Convert.ToInt32(txtboxClid.Text)

' Suppose you have a date in your database, not a string
Dim StartDt as DateTime = Convert.ToDateTime(txtStartDt.Text)
' Calculate here the previous ending date
Dim PrevEnd As DateTime = StartDt.AddDays(-1)

' Conventional max end date
Dim maxEndDate as DateTime = new DateTime(9999,9,9)

If txtboxClid.Text.Trim <> "" And txtStartDt.Text.Trim <> "" Then

    ' Create here the connection to dispose on exit from the using statement
    Using conn As SqlConnection = New SqlClient.SqlConnection("conneting string")
        conn.Open()
        ' USE PARAMETERS EVERYWHERE. DO NOT USE STRINGS TO FIND A DATE
        Dim query2 As String = "UPDATE [Table name] SET [EndDt] = @newEnd 
                                WHERE Clientid = @Clientid 
                                  AND EndDt = @maxEnd"
        Dim command = New SqlCommand(query2, conn)
        command.Parameters.Add("@Clientid", SqlDbType.Int).Value = Clientid
        command.Parameters.Add("@newEnd", SqlDbType.Date).Value = newEnd
        command.Parameters.Add("@maxEnd", SqlDbType.Date).Value = maxEndDate
        command.ExecuteNonQuery()

        ' Prepare the insert. 
        Dim query As String = "INSERT INTO [Table name] 
              (Clientid, Client_Status, Notes, Startdt,Enddt, Entrydt, Entryid) 
               VALUES 
              (@Clientid, @status,@Notes,@StartDt,@maxDate,getdate(), @UName);"
        command.Parameters.Clear()
        command.Parameters.Add("@Clientid", SqlDbType.Int).Value = Clientid
        command.Parameters.Add("@status", SqlDbType.NVarChar).Value = Client_Status
        command.Parameters.Add("@notes", SqlDbType.NVarChar).Value = notes
        command.Parameters.Add("@startdt", SqlDbType.Date).Value = StartDt
        command.Parameters.Add("@maxDate", SqlDbType.Date).Value = maxEndDate
        command.Parameters.Add("@uname", SqlDbType.NVarChar).Value = uname
        command.CommandText = query
        command.ExecuteNonQuery()
    End Using
    Call GetInfoClientid()
End If

请注意,我为您的列类型传递了适当类型的参数。认为像“9/9/9999”这样的字符串是日期是常见的错误。但是对于计算机程序来说,这是一个字符串,如果你想用它作为日期,我们需要将它转换成一个合适的日期。这种转换通常会导致错误的数据传递到数据库引擎。

对于我的当前记录,它不会用新的Startdate更新现有的enddate-1您是否在Sql Server中将列EndDt和StartDt声明为文本或日期?您没有执行update命令,而且我确信UPDATETable是一个输入错误,但如果不是,如果对该语句执行ExecuteOnQuery,至少会出现错误。这些语句看起来都不起作用。Startdt和Enddt是SQLServer中的日期。Update未执行我有正确的查询,因为Update Table name SET EndDt=SELECT todateStartDt-1来自表名,其中Clientid=@Clientid和EndDt='9/9/9999'我的INSERT语句可以完美地添加新记录。请建议更改。我确信表名在这里不起作用。由于sql注入的可能性,最好不要对sql语句使用字符串连接。是的。我确实认识到SQL注入的威胁。理想情况下,这应该在存储过程中。我现在就纠正它。关于更新查询,如果它是MSSQL,我认为“update[table name]set[column name]=value where[condition]”的语法应该起作用。我在这里指的是:。