vb.net中的SQL事务语句
Posted
技术标签:
【中文标题】vb.net中的SQL事务语句【英文标题】:SQL transaction statement in vb.net 【发布时间】:2016-07-18 13:03:11 【问题描述】:我正在制作一个链接到 Microsoft SQLServer 的项目,用于输入、删除、编辑有关客户和订单的数据。完整的系统可以工作,但是我被建议使用事务而不是常规 SQL 语句来添加/删除/编辑数据等。
问题是,我之前和过去几个小时的研究都没有使用过这些,我什至不知道如何开始使用它们。
谁能告诉我如何把下面的代码变成一个事务?
Public Shared Function SaveNewPerson(ByVal firstName As String, lastName As String, ByVal age As Integer, ByVal postcode As String, m_cn As OleDbConnection)
Dim Dc As New OleDbCommand
Dc.Connection = m_cn
m_cn.Open()
Dc.CommandText = "INSERT INTO tblPerson([firstName], [lastName], [age], [postcode]) VALUES('" & firstName & "', '" & lastName & "', '" & age & "', '" & postcode & "')"
Dc.ExecuteNonQuery()
Dim personID As Integer
Dc.CommandText = "SELECT @@IDENTITY"
Dc.CommandType = CommandType.Text
personID = CType(Dc.ExecuteScalar(), Integer)
m_cn.Close()
End Function
【问题讨论】:
在您做任何其他事情之前,您需要阅读、理解并开始使用参数化查询。您的代码对 sql 注入是开放的。您还应该考虑使用 SCOPE_IDENTITY 而不是 @@Identity。希望您被告知的是使用参数化查询。事务本身不执行插入等。 您还应该小心Shared
函数,例如SaveNewPerson
。如果你在其中使用共享变量,这可能会在多线程系统中搞砸。
另一个建议是存储生日而不是年龄。年龄是根据当前现实世界时间计算得出的值,而不是作为事实存储在表中。
@AlexB。多线程系统是什么意思?
@SeanLange 虽然我个人同意将 SqlClient 与此类程序一起使用更有意义,但我也使用 OleDb,但这只是因为我在大学就是这样教它的,而在我工作的软件公司也在 SqlClient 上使用它。真的很奇怪。
【参考方案1】:
我刚刚在学习 TSQL,看看这种代码是否适合你(注意你需要 Dim tr
(如果你愿意,可以使用不同的变量名)并在多个地方使用它,但不像在某些语言中,您不需要为不同的方法设置对象。
Public Shared Function SaveNewIncident(ByVal clientName As String, dateStart As Date, dateEnd As Date, ByVal incidentProblem As String, ByVal timeStart As String, ByVal timeEnd As String,
ByVal incidentSolved As Boolean, ByVal incidentSolution As String, _con As OleDbConnection)
Dim tr As OleDbTransaction = Nothing
Try
Dim Dc As New OleDbCommand
Dc.Connection = _con
tr = _con.BeginTransaction()
Dc.CommandType = CommandType.Text
Dc.CommandText = "INSERT INTO dbo.tblIncidents VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)"
Dc.Transaction = tr
Dc.Parameters.Add("@clientName", OleDbType.VarChar).Value = clientName
Dc.Parameters.Add("@dateStart", OleDbType.Date).Value = dateStart
Dc.Parameters.Add("@dateEnd", OleDbType.Date).Value = dateEnd
Dc.Parameters.Add("@incidentProblem", OleDbType.LongVarChar).Value = incidentProblem
Dc.Parameters.Add("@timeStart", OleDbType.VarChar).Value = timeStart
Dc.Parameters.Add("@timeEnd", OleDbType.VarChar).Value = timeEnd
Dc.Parameters.Add("@incidentSolved", OleDbType.Boolean).Value = incidentSolved
Dc.Parameters.Add("@incidentSolution", OleDbType.LongVarChar).Value = incidentSolution
Dim personID As Integer
Dc.CommandText = "SELECT SCOPE_IDENTITY() AS personID"
Dc.CommandType = CommandType.Text
personID = CType(Dc.ExecuteScalar(), Integer)
tr.Commit()
Catch ex As Exception
tr.Rollback()
Throw
End Try
End Function
【讨论】:
这行得通,如何参数化代码以减少对 sql 注入的开放性? 请不要像这样发布对 sql 注入开放的答案。需要参数化。 @SeanLange 我只是发布这个来帮助解决最初的问题。我自己并不完全确定 paramatizing 是如何工作的,这可能是一个不同的问题。但谁说这将是一个上线的程序?如果它不被使用并且仅用于课程/学位等,甚至可能不用担心 可悲的是,人们在学校学习的技术与他们在现实世界中编程的方式相同。学习正确地做最初会促进良好的编码实践。并且错误地学习这样做会促进不良的开发实践。这应该是参数化的,它应该使用 SCOPE_IDENTITY 代替。那么这将是一个很好的答案。 @SeanLange 我可以/已经在 SCOPE_IDENTITY 语句中添加(虽然我没有看到太多缺点,但我确实读到@@IDENTITY 在插入带有条件语句的记录时会导致问题?)我可以看到这个比较好,以后会经常用这个,谢谢!以上是关于vb.net中的SQL事务语句的主要内容,如果未能解决你的问题,请参考以下文章
在 sql 语法中出现错误,vb.net 中的 mysql update 语句