本帖最后由 群发软件 于 2017-5-25 23:58 编辑
数据库事务简介
数据库事务是由一组 SQL 语句组成的一个逻辑工作单元。您可以把事务看作是一组不可分的 SQL 语句,这些语句作为一个整体永久记录在数据库中或一并撤销。比如在银行帐户之间转移资金:一条 UPDATE语句将从一个帐户的资金总数中减去一部分,另一条 UPDATE语句将把资金加到另一个帐户中。减操作和加操作必须永久记录在数据库中,或者必须一并撤销 — 否则将损失资金。这个简单的示例仅使用了两条 UPDATE 语句,但一个更实际的事务可能包含许多 INSERT、UPDATE和 DELETE 语句。
要永久记录一个事务中的 SQL 语句的结果,您可以通过 COMMIT 语句来执行提交。要撤销 SQL 语句的结果,您可以使用 ROLLBACK 语句来执行回滚,这会把所有的行重设为它们原来的状态。只要您事先没有与数据库断开,则您在执行回滚之前所做的任何修改都将被撤销。您还可以设置一个保存点,以便将事务回滚至该特定的点,同时保持事务中的其他语句原封不动。
使用数据库事务(主要针对VB.net)
您可以使用 OracleTransaction 类的一个对象来表示一个事务。OracleTransaction 类包含多个属性,其中的两个为 Connection(指定与事务关联的数据库连接)和 IsolationLevel(指定事务隔离级别)
Connection,指定与该事务关联的OracleConnection对象;
IsolationLevel,指定该事务的IsolationLevel;枚举类型,用于对事物的锁定,取值有Chaos、ReadCommited、ReadUncommited、RepeatableRead、Serializable、Unspecified。
应用程序通过针对OracleConnection对象调用 BeginTransaction 来创建OracleTransaction对象。对OracleTransaction对象执行与该事务关联的所有后续操作(例如提交或中止该事务)。
Commit:提交SQL数据库事务;
Rollback :从挂起状态回滚事务;
您还可以使用 Save() 在事务中设置一个保存点。
下面的示例创建一个 OracleConnection 和一个 OracleTransaction。它还演示了如何使用 BeginTransaction、Commit 和 Rollback 方法。(这是MSDN里的范例)
需要注意的是,这些操作需要引入命名空间: Oracle.DataAcess.Client
Oracle.DataAccess.Client 命名空间是 ODP.NET 的一部分,它包含许多类,其中有 OracleConnection、OracleCommand 和 OracleTransaction。示例程序就用到了这些类。
事务操作
1Public Sub RunOracleTransaction()Sub RunOracleTransaction(myConnString As String)
2 Dim myConnection As New OracleConnection(myConnString)
3 myConnection.Open()
4
5 Dim myCommand As OracleCommand = myConnection.CreateCommand()
6 Dim myTrans As OracleTransaction
7
8 ' Start a local transaction
9 myTrans = myConnection.BeginTransaction(IsolationLevel.ReadCommitted)
10 ' Assign transaction object for a pending local transaction
11 myCommand.Transaction = myTrans
12
13 Try
14 myCommand.CommandText = "INSERT INTO Dept (DeptNo, Dname, Loc) values (50, 'TECHNOLOGY', 'DENVER')"
15 myCommand.ExecuteNonQuery()
16 myCommand.CommandText = "INSERT INTO Dept (DeptNo, Dname, Loc) values (60, 'ENGINEERING', 'KANSAS CITY')"
17 myCommand.ExecuteNonQuery()
18 myTrans.Commit()
19 Console.WriteLine("Both records are written to database.")
20 Catch e As Exception
21 myTrans.Rollback()
22 Console.WriteLine(e.ToString())
23 Console.WriteLine("Neither record was written to database.")
24 Finally
25 myConnection.Close()
26 End Try
27End Sub
28
在 .NET 程序中设置事务保存点
正如本文前面所提到的那样,您可以设置一个保存点,以便将事务回滚至该特定的点,同时保持事务中的其他语句原封不动。您可以使用 OracleTransaction 类的 Save() 方法在事务中设置保存点。
如果您有一个非常长的事务并且希望能够仅回滚到某个特定的时间点,那么您可能要使用保存点。例如,您可能想对 10 个产品做一些更改,然后设置一个保存点,然后再对另 10 个产品做更改;如果您在进行第二批更改时出现了错误,那么您可以回滚至保存点,使您的第一批更改原封不动。
使用OracleTransaction对象需要注意的几点:
1)你需要在你整个事务执行中只能有唯一OracleConnection ,OracleCommand,
OracleTransaction,也就是说如果你事务处理过程中如果需要与数据库的操作都只能在这唯一的Command中执行,类似于:
imgCommand.CommandText = sSQL
imgCommand.ExecuteNonQuery()或其他操作
若你新建一个连接执行其他数据库操作的话,整个事务过程就会抛出异常
2)如果你需要在你SQL语句中加入参数,则你必须在你执行完提交或相关数据库操作之后将其Command的参数清空,下边举一个实际的项目里的事务函数:
事务函数
1 ''' <summary>
2 ''' 保存热点文本文件信息到数据库
3 ''' </summary>
4 Private Function SaveTextFile()Function SaveTextFile() As Boolean
5 Dim sSQl As String
6 sSQl = "select type_id from sys_file_type where file_extname='TXT'"
7 Try
8 imgCommand.CommandText = sSQl
9 Dim typeID As Int32 = Convert.ToInt32(imgCommand.ExecuteScalar()) '文件类型
10 '读取文本信息
11 Dim Textblob() As Byte = GetText()
12
13 sSQl = "insert into t_watch_textcontent(image_id,text_content,type_id) values(:imageid,:textcontent,:typeid)"
14 '增添SQL参数
15 Dim Param As OracleClient.OracleParameter
16 Param = New OracleClient.OracleParameter("imageid", sNewImageID)
17 imgCommand.Parameters.Add(Param)
18 Param = New OracleClient.OracleParameter("textcontent", Textblob)
19 imgCommand.Parameters.Add(Param)
20 Param = New OracleClient.OracleParameter("typeid", typeID)
21 imgCommand.Parameters.Add(Param)
22
23 '提交信息
24 imgCommand.CommandText = sSQl
25 If imgCommand.ExecuteNonQuery() > 0 Then
26 bResult = True
27 '关键是这里,需要你手动清除参数
28 imgCommand.Parameters.Clear()
29 End If
30 Catch ex As Exception
31 Me.ExceptionMessage = ex
32 bResult = False
33 End Try
34
35 Return bResult
36 End Function
开始事务:
[c-sharp] view plain copy
- OracleTransaction trans = null;
- OracleCommand comm = null;
- trans = con.BeginTransaction();
- comm = con.CreateCommand();
- comm.Transaction = trans;
提交:
[c-sharp] view plain copy
回滚:
[c-sharp] view plain copy
在事件内进行SQL语句相关执行:
[c-sharp] view plain copy
- comm.CommandText = "INSERT INTO .....";
- comm.ExecuteNonQuery();
要注意的是,在事务进行中,不能再对同一个数据库连接(OracleConnection)再进行事务外的数据的查询和读取,也就是说,类似下边的语句是不能执行的:
[c-sharp] view plain copy
- OracleDataAdapter mAdp = new OracleDataAdapter(sSql, mCon);
- DataTable mDst = new DataTable();
- mAdp.Fill(mDst);
而是得加一条语句,在事务内进行查询:
[c-sharp] view plain copy
- OracleDataAdapter mAdp = new OracleDataAdapter(sSql, mCon);
- if (trans != null) mAdp.SelectCommand.Transaction = trans;
- DataTable mDst = new DataTable();
- mAdp.Fill(mDst);
BTW: 转载一些资料:
[c-sharp] view plain copy
- 1. 事务的概念
- 事务可以看作是由对数据库的若干操作组成的一个单元,这些操作要么都完成,要么都取消,从而保证数据满足一致性的要求。事务的一个典型例子是银行中的转帐操作,帐户A把一定数量的款项转到帐户B上,这个操作包括两个步骤,一个是从帐户A上把存款减去一定数量,二是在帐户B上把存款加上相同的数量。这两个步骤显然要么都完成,要么都取消,否则银行就会受损失。显然,这个转帐操作中的两个步骤就构成一个事务.
- 数据库中的事务还有如下ACID特征。
- ACID分别是四个英文单词的首写字母,这四个英文单词是Atomicity、Consistency、Isolation、Durability,分别翻译为原子性、一致性、隔离性、持久性。
- 原子性:指事务中的操作,或者都完成,或者都取消。
- 一致性:指事务中的操作保证数据库中的数据不会出现逻辑上不一致的情况,一致性一般会隐含的包括在其他属性之中。
- 隔离性:指当前的事务与其他未完成的事务是隔离的。在不同的隔离级别下,事务的读取操作,可以得到的结果是不同的。
- 持久性:指对事务发出COMMIT命令后,即使这时发生系统故障,事务的效果也被持久化了。与此相反的是,当在事务执行过程中,系统发生故障,则事务的操作都被回滚,即数据库回到事务开始之前的状态。
- 对数据库中的数据修改都是在内存中完成的,这些修改的结果可能已经写到硬盘也可能没有写到硬盘,如果在操作过程中,发生断电或系统错误等故障,数据库可以保证未结束的事务对数据库的数据修改结果即使已经写入磁盘,在下次数据库启动后也会被全部撤销;而对于结束的事务,即使其修改的结果还未写入磁盘,在数据库下次启动后会通过事务日志中的记录进行“重做”,即把丢失的数据修改结果重新生成,并写入磁盘,从而保证结束事务对数据修改的永久化。这样也保证了事务中的操作要么全部完成,要么全部撤销。
- 2. 事务设置及类型的区别
- 在SQL Server中有三种事务类型,分别是:隐式事务、显式事务、自动提交事务,缺省为自动提交。
- 自动提交,是指对于用户发出的每条SQL语句,SQL Server都会自动开始一个事务,并且在执行后自动进行提交操作来完成这个事务,也可以说在这种事务模式下,一个SQL语句就是一个事务。
- 显式事务,是指在自动提交模式下以Begin Transaction开始一个事务,以Commit或Rollback结束一个事务,以Commit结束事务是把事务中的修改永久化,即使这时发生断电这样的故障。例如下面是SQL Server中的一个显式事务的例子。
- Begin Tran
- Update emp Set ename=’Smith’ Where empno=7369
- Insert Into dept Values(60,’HR’,’GZh’)
- Commit
- 隐式事务,是指在当前会话中用Set Implicit_Transactions On命令设置的事务类型,这时任何DML语句(Delete、Update、Insert)都会开始一个事务,而事务的结束也是用Commit或Rollback。
- 在Oracle中没有SQL Server的这些事务类型,缺省情况下任何一个DML语句都会开始一个事务,直到用户发出Commit或Rollback操作,这个事务才会结束,这与SQL Server的隐式事务模式相似。
- 3. 事务隔离级别
- 在SQL92标准中,事务隔离级别分为四种,分别为:Read Uncommitted、Read Committed、Read Repeatable、Serializable,其中Read Uncommitted与Read Committed为语句级别的,而Read Repeatable与Serializable是针对事务级别的。
- 在Oracle和SQL Server中设置事务隔离级别的语句是相同的,都使用SQL92标准语法,即:
- Set Transaction Isolation Level Read Committed
- 上面示例中的Read Committed可以被替换为其他三种隔离级别中的任意一种。
- 1) SQL Server中的隔离级别及实现机制
- 在SQL Server中提供了所有这四种隔离级别。
- 下面我们讨论在SQL Server中,这几种隔离级别的含义及其实现方式。
- Read Uncommitted:一个会话可以读取其他事务未提交的更新结果,如果这个事务最后以回滚结束,这时的读取结果就可能是错误的,所以多数的数据库应用都不会使用这种隔离级别。
- Read Committed:这是SQL Server的缺省隔离级别,设置为这种隔离级别的事务只能读取其他事务已经提交的更新结果,否则,发生等待,但是其他会话可以修改这个事务中被读取的记录,而不必等待事务结束,显然,在这种隔离级别下,一个事务中的两个相同的读取操作,其结果可能不同。
- Read Repeatable:在一个事务中,如果在两次相同条件的读取操作之间没有添加记录的操作,也没有其他更新操作导致在这个查询条件下记录数增多,则两次读取结果相同。换句话说,就是在一个事务中第一次读取的记录保证不会在这个事务期间发生改变。SQL Server是通过在整个事务期间给读取的记录加锁实现这种隔离级别的,这样,在这个事务结束前,其他会话不能修改事务中读取的记录,而只能等待事务结束,但是SQL Server不会阻碍其他会话向表中添加记录,也不阻碍其他会话修改其他记录。
- Serializable:在一个事务中,读取操作的结果是在这个事务开始之前其他事务就已经提交的记录,SQL Server通过在整个事务期间给表加锁实现这种隔离级别。在这种隔离级别下,对这个表的所有DML操作都是不允许的,即要等待事务结束,这样就保证了在一个事务中的两次读取操作的结果肯定是相同的。
- 2) Oracle中的隔离级别及实现机制
- 在Oracle中,没有Read Uncommitted及Repeatable Read隔离级别,这样在Oracle中不允许一个会话读取其他事务未提交的数据修改结果,从而避免了由于事务回滚发生的读取错误。Oracle中的 Read Committed和Serializable级别,其含义与SQL Server类似,但是实现方式却大不一样。
- 在Oracle中,存在所谓的回滚段(Oracle9i之前版本)或撤销段(Oracle9i版本),Oracle在修改数据记录时,会把这些记录被修改之前的结果存入回滚段或撤销段中,就是因为这种机制,Oracle对于事务隔离级别的实现与SQL Server截然不同。在Oracle中,读取操作不会阻碍更新操作,更新操作也不会阻碍读取操作,这样在Oracle中的各种隔离级别下,读取操作都不会等待更新事务结束,更新操作也不会因为另一个事务中的读取操作而发生等待,这也是Oracle事务处理的一个优势所在。
- Oracle缺省的设置是Read Committed隔离级别(也称为语句级别的隔离),在这种隔离级别下,如果一个事务正在对某个表进行DML操作,而这时另外一个会话对这个表的记录进行读取操作,则Oracle会去读取回滚段或撤销段中存放的更新之前的记录,而不会象SQL Server一样等待更新事务的结束。
- 在Serializable隔离级别(也称为事务级别的隔离),事务中的读取操作只能读取这个事务开始之前已经提交的数据结果。如果在读取时,其他事务正在对记录进行修改,则Oracle就会在回滚段或撤销段中去寻找对应的原来未经更改的记录(而且是在读取操作所在的事务开始之前存放于回滚段或撤销段的记录),这时读取操作也不会因为相应记录被更新而等待。
特郁闷的一件事情,费时费力!记下来,为后来者铺路。
首先,我用VS2010开发对oracle10g数据库的操作,结果发现微软自带的System.Data.OracleClient已经有一些常用对象提示过时;网上说最好用Oracle自带的ODP.NET操作。
我到oracle网站下载ODAC这个安装包,还注册了用户名,200多M,而且下载特慢,下载后结果是调试了很久都不行。
其次,问用oracle的同事,告诉我安装了oracle客户端后在安装目录下有ODP.Net的DLL,直接引用那个就OK了;我在我的oracle客户端安装录D:\oracle\product\10.2.0\db_1\BIN下真的还找到了 Oracle.DataAccess.dll。
最后,VS2010的vb.net工程中引用这个dll,编写对远程oracle数据库的操作测试,通过!
写这么多只是因为忒郁闷!我喜欢开源MySQL、sqlite;还没有自己创业,给别人打工不自由啊,只能按照项目要求来。郁闷!!!
'引入oracle本身提供的.net数据引擎
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Data
Imports System.Xml
Imports System.Collections
Imports Oracle.DataAccess
Imports Oracle.DataAccess.Server
Imports Oracle.DataAccess.Client
Imports Oracle.DataAccess.Types
'引入开源日志类库
Imports log4net
Public Class OracleDbOperations
'定义日志对象 OracleHelper.Logging
'Private Shared Log As log4net.ILog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
Private Shared Log As log4net.ILog = log4net.LogManager.GetLogger("OracleHelper.Logging")
'数据库连接对象
Dim Conn As OracleConnection = Nothing
'事务处理对象
Dim Trans As OracleTransaction = Nothing
'数据库连接字符串
Dim ConnectionStr As String = Nothing
'构造函数
Sub New(ByVal ConnStr As String)
ConnectionStr = ConnStr
Conn = New OracleConnection(ConnectionStr)
End Sub
''' <summary>
''' 关闭数据库连接
''' </summary>
''' <returns>布尔值</returns>
''' <remarks>成功关闭返回true;否则返回false</remarks>
Public Function ConnClose() As Boolean
Try
If Conn.State <> ConnectionState.Closed Then
Conn.Close()
Conn.Dispose()
Conn = Nothing
Log.Info("数据库关闭连接成功!")
Return True
End If
Catch ex As Exception
'写日志
Log.Error("数据库关闭连接失败!")
End Try
Return False
End Function
''' <summary>
''' 打开数据库连接
''' </summary>
''' <returns>布尔值</returns>
''' <remarks>成功关闭返回true;否则返回false</remarks>
Public Function ConnOpen() As Boolean
Try
If Conn.State <> ConnectionState.Open Then
Conn.Open()
Log.Info("数据库打开连接成功!")
Return True
End If
Catch ex As Exception
'写日志
Log.Error("数据库打开连接失败!")
End Try
Return False
End Function
''' <summary>
''' 执行SQL语句或者存储过程(对于输入输出参数值为nothing的字段进行特殊处理为DBNull.Value);此为查询类型,不提供事务处理支持
''' </summary>
''' <param name="cmdType">执行类型</param>
''' <param name="cmdText">执行文本</param>
''' <param name="params">输入输出参数信息</param>
''' <returns>返回影响的行数</returns>
''' <remarks></remarks>
Public Function ExecuteNoneQuery(ByVal cmdType As CommandType, ByVal cmdText As String, ByVal params As OracleParameter()) As Integer
Dim rows As Integer = 0
Try
If ConnOpen() Then
Dim cmd As New OracleCommand
cmd.Connection = Conn
cmd.CommandType = cmdType
cmd.CommandText = cmdText
'有参数时
If params IsNot Nothing AndAlso params.Length > 0 Then
For Each p As OracleParameter In params
'对NULL值的参数数据进行特殊处理(VB中对NULL赋值为Nohting)
If p.Direction = ParameterDirection.InputOutput AndAlso p.Value Is Nothing Then
p.Value = DBNull.Value
End If
cmd.Parameters.Add(p)
Next
End If
rows = cmd.ExecuteNonQuery()
'清理资源
cmd.Parameters.Clear()
cmd.Dispose()
cmd = Nothing
'关闭连接
ConnClose()
Else
'写日志
Log.Error("数据库打开连接失败!")
End If
Catch ex As Exception
'写日志
Log.Error("<" & cmdText & ">执行ExecuteNonQuery出现异常!")
End Try
Return rows
End Function
''' <summary>
''' 执行SQL语句或者存储过程(对于输入输出参数值为nothing的字段进行特殊处理为DBNull.Value);此为增删改,提供事务处理支持
''' </summary>
''' <param name="cmdType">执行类型</param>
''' <param name="cmdText">执行文本</param>
''' <param name="params">输入输出参数信息</param>
''' <returns>返回影响的行数</returns>
''' <remarks></remarks>
Public Function ExecuteNoneQueryTrans(ByVal cmdType As CommandType, ByVal cmdText As String, ByVal params As OracleParameter()) As Integer
Dim rows As Integer = 0
Try
If ConnOpen() Then
Trans = Conn.BeginTransaction
Dim cmd As New OracleCommand
cmd.Connection = Conn
cmd.CommandType = cmdType
cmd.CommandText = cmdText
'有参数时
If params IsNot Nothing AndAlso params.Length > 0 Then
For Each p As OracleParameter In params
'对NULL值的参数数据进行特殊处理(VB中对NULL赋值为Nohting)
If p.Direction = ParameterDirection.InputOutput AndAlso p.Value Is Nothing Then
p.Value = DBNull.Value
End If
cmd.Parameters.Add(p)
Next
End If
rows = cmd.ExecuteNonQuery()
Trans.Commit()
'清理资源
Trans.Dispose()
Trans = Nothing
cmd.Parameters.Clear()
cmd.Dispose()
cmd = Nothing
'关闭连接
ConnClose()
Else
'写日志
Log.Error("数据库打开连接失败!")
End If
Catch ex As Exception
'写日志
Log.Error("<" & cmdText & ">执行ExecuteNonQuery出现异常!")
If IsNothing(Trans) = False Then
Trans.Rollback()
Trans.Dispose()
Trans = Nothing
End If
End Try
Return rows
End Function
''' <summary>
''' 返回记录集
''' </summary>
''' <param name="DsTable">记录集中表名</param>
''' <param name="cmdType">类型</param>
''' <param name="cmdText">文本</param>
''' <param name="params">输入输出参数</param>
''' <returns>返回dateset或者nothing</returns>
''' <remarks>必须首先判断返回值是否是nothing</remarks>
Public Function ExecuteDataSet(ByVal DsTable As String, ByVal cmdType As CommandType, ByVal cmdText As String, ByVal params As OracleParameter()) As DataSet
Dim ds As DataSet = Nothing
Try
If ConnOpen() Then
Dim cmd As New OracleCommand
cmd.Connection = Conn
cmd.CommandType = cmdType
cmd.CommandText = cmdText
'有参数时
If params IsNot Nothing AndAlso params.Length > 0 Then
For Each p As OracleParameter In params
'对NULL值的参数数据进行特殊处理(VB中对NULL赋值为Nohting)
If p.Direction = ParameterDirection.InputOutput AndAlso p.Value Is Nothing Then
p.Value = DBNull.Value
End If
cmd.Parameters.Add(p)
Next
End If
Dim da As New OracleDataAdapter(cmd)
ds = New DataSet
da.Fill(ds, DsTable)
'清理资源
cmd.Parameters.Clear()
cmd.Dispose()
cmd = Nothing
da.Dispose()
da = Nothing
'关闭连接
ConnClose()
Else
'写日志
Log.Error("数据库打开连接失败!")
End If
Catch ex As Exception
'写日志
Log.Error("<" & cmdText & ">执行ExecuteDataSet出现异常!")
End Try
Return ds
End Function
''' <summary>
''' 返回XmlReader
''' </summary>
''' <param name="cmdType">类型</param>
''' <param name="cmdText">文本</param>
''' <param name="params">输入输出参数</param>
''' <returns>返回 或者nothing</returns>
''' <remarks>注意:调用该方法后,一定要对XmlReader进行Close</remarks>
Public Function ExecuteXmlReader(ByVal cmdType As CommandType, ByVal cmdText As String, ByVal params As OracleParameter()) As XmlReader
Dim dr As XmlReader = Nothing
Try
If ConnOpen() Then
Dim cmd As New OracleCommand
cmd.Connection = Conn
cmd.CommandType = cmdType
cmd.CommandText = cmdText
'有参数时
If params IsNot Nothing AndAlso params.Length > 0 Then
For Each p As OracleParameter In params
'对NULL值的参数数据进行特殊处理(VB中对NULL赋值为Nohting)
If p.Direction = ParameterDirection.InputOutput AndAlso p.Value Is Nothing Then
p.Value = DBNull.Value
End If
cmd.Parameters.Add(p)
Next
End If
'执行
dr = cmd.ExecuteXmlReader
'清理资源
cmd.Parameters.Clear()
cmd.Dispose()
cmd = Nothing
Else
'写日志
Log.Error("数据库打开连接失败!")
End If
Catch ex As Exception
'写日志
Log.Error("<" & cmdText & ">执行ExecuteXmlReader出现异常!")
End Try
Return dr
End Function
''' <summary>
''' 执行SQL语句或者存储过程(对于输入输出参数值为nothing的字段进行特殊处理为DBNull.Value);此为查询类型,不提供事务处理支持
''' </summary>
''' <param name="cmdType">执行类型</param>
''' <param name="cmdText">执行文本</param>
''' <param name="params">输入输出参数信息</param>
''' <returns>返回一个object类型的结果</returns>
''' <remarks>对返回值进行ctype()类型装换后使用</remarks>
Public Function ExecuteScalar(ByVal cmdType As CommandType, ByVal cmdText As String, ByVal params As OracleParameter()) As Object
Dim Result As Object = 0
Try
If ConnOpen() Then
Dim cmd As New OracleCommand
cmd.Connection = Conn
cmd.CommandType = cmdType
cmd.CommandText = cmdText
'有参数时
If params IsNot Nothing AndAlso params.Length > 0 Then
For Each p As OracleParameter In params
'对NULL值的参数数据进行特殊处理(VB中对NULL赋值为Nohting)
If p.Direction = ParameterDirection.InputOutput AndAlso p.Value Is Nothing Then
p.Value = DBNull.Value
End If
cmd.Parameters.Add(p)
Next
End If
Result = cmd.ExecuteScalar()
'清理资源
cmd.Parameters.Clear()
cmd.Dispose()
cmd = Nothing
'关闭连接
ConnClose()
Else
'写日志
Log.Error("数据库打开连接失败!")
End If
Catch ex As Exception
'写日志
Log.Error("<" & cmdText & ">执行ExecuteScalar出现异常!")
End Try
Return Result
End Function
''' <summary>
''' 返回datareader
''' </summary>
''' <param name="cmdType">类型</param>
''' <param name="cmdText">文本</param>
''' <param name="params">输入输出参数</param>
''' <returns>返回 或者nothing</returns>
''' <remarks>注意:调用该方法后,一定要对OracleDataReader进行Close</remarks>
Public Function ExecuteDataReader(ByVal cmdType As CommandType, ByVal cmdText As String, ByVal params As OracleParameter()) As OracleDataReader
Dim dr As OracleDataReader = Nothing
Try
If ConnOpen() Then
Dim cmd As New OracleCommand
cmd.Connection = Conn
cmd.CommandType = cmdType
cmd.CommandText = cmdText
'有参数时
If params IsNot Nothing AndAlso params.Length > 0 Then
For Each p As OracleParameter In params
'对NULL值的参数数据进行特殊处理(VB中对NULL赋值为Nohting)
If p.Direction = ParameterDirection.InputOutput AndAlso p.Value Is Nothing Then
p.Value = DBNull.Value
End If
cmd.Parameters.Add(p)
Next
End If
'执行
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
'清理资源
cmd.Parameters.Clear()
cmd.Dispose()
cmd = Nothing
Else
'写日志
Log.Error("数据库打开连接失败!")
End If
Catch ex As Exception
'写日志
Log.Error("<" & cmdText & ">执行ExecuteDataReader出现异常!")
End Try
Return dr
End Function