odp.net 使用
本文指ODAC1110720版本
一,准备dll
共七个oci.dll, ociw32.dll, Oracle.DataAccess.dll,orannzsbb11.dll,oraocci11.dll,oraociicus11.dll, OraOps11w.dll
其中项目中需要引用Oracle.DataAccess.dll,其余6个直接添加至bin目录中即可。 共计30几M,不用安装odp.net。
二.连接字符串
2.1 Data Source=(DESCRIPTION=(ADDRESSLIST=(ADDRESS=
(PROTOCOL=TCP)(HOST=MyHost)(PORT=MyPort)))
(CONNECTDATA=(SERVER=DEDICATED)(SERVICENAME=MyOracleSID)));User Id=myUsername;Password=myPassword;
2.2 Data Source=MyOracleDB;User Id=myUsername;Password=myPassword; ----------此种方式需要把tnsnames.ora文件拷贝至bin目录下,否则会提示连接异常
三. 使用中注意事项
3.1. Command的BindByName属性
此属性默认值为false,即command的Parameter里的参数它是按照你add的顺序进行绑定。(即便你是按照Parameters[Name]=value进行赋值也是如此。)。若sql语句中的参数顺序与add的顺序不一致,则会导致cmd.ExecuteNonQuery()的返回值=0,且不抛异常。此种情况在微软的OracleDataProvider/SqlDataProvider中会感觉很不可思议。
所以,强力建议赋值为true。因为orm工具/手写数据访问经常参数顺序不一致,也很正常。
片段: string sql = "update A_Test set age=:age where name1=:name1";
Oracle.DataAccess.Client.OracleCommand cmd = new Oracle.DataAccess.Client.OracleCommand(sql, conn)
cmd.Parameters.Add(new Oracle.DataAccess.Client.OracleParameter { ParameterName = "name1", DbType = System.Data.DbType.String });
cmd.Parameters["name1"].Direction = System.Data.ParameterDirection.Input;
cmd.Parameters["name1"].Value = name1s;
cmd.Parameters.Add(new Oracle.DataAccess.Client.OracleParameter { ParameterName = "age", DbType = System.Data.DbType.String });
cmd.Parameters["age"].Direction = System.Data.ParameterDirection.Input;
cmd.Parameters["age"].Value = ages;
int i=cmd.ExecuteNonQuery();// i=0
3.2. 批量操作
parameter的dbtype属性是必须的。(当然,非批量操作,dbType不是必须的)默认它是一个事务。
片段:
using (Oracle.DataAccess.Client.OracleConnection conn = new Oracle.DataAccess.Client.OracleConnection(connstring))
{
int recordCount = 10000;
conn.Open();
// Oracle.DataAccess.Client.OracleTransaction trans = conn.BeginTransaction();
try
{
string sql = "insert into A_Test values(:age,:name1,:sex)";
Oracle.DataAccess.Client.OracleCommand cmd = new Oracle.DataAccess.Client.OracleCommand(sql, conn);
// cmd.Transaction = trans;
List<object> ageArray = new List<object>();
List<object> name1Array = new List<object>();
List<object> sexArray = new List<object>();
for (int i = 0; i < recordCount; i++)
{
ageArray.Add("oracle.dataaccess_" + i);
name1Array.Add("name_" + i);
sexArray.Add(i);
}
object ages = ageArray.ToArray();
object name1s = name1Array.ToArray();
object sexs = sexArray.ToArray();
cmd.Parameters.Add(new Oracle.DataAccess.Client.OracleParameter { ParameterName = "age", DbType = System.Data.DbType.String });
cmd.Parameters["age"].Direction = System.Data.ParameterDirection.Input;
cmd.Parameters["age"].Value = ages;
cmd.Parameters.Add(new Oracle.DataAccess.Client.OracleParameter { ParameterName = "name1", DbType = System.Data.DbType.String });
cmd.Parameters["name1"].Direction = System.Data.ParameterDirection.Input;
cmd.Parameters["name1"].Value = name1s;
cmd.Parameters.Add(new Oracle.DataAccess.Client.OracleParameter { ParameterName = "sex", DbType = System.Data.DbType.Decimal });
cmd.Parameters["sex"].Direction = System.Data.ParameterDirection.Input;
cmd.Parameters["sex"].Value = sexs;
cmd.ArrayBindCount = recordCount;
DateTime start = DateTime.Now;
cmd.ExecuteNonQuery();
// trans.Commit();
DateTime end = DateTime.Now;
TimeSpan sp = end - start;
Console.WriteLine("odp 用时:" + sp.TotalSeconds + "----------" + sp.Milliseconds);
}
catch (Exception ex)
{
// trans.Rollback();
}
finally
{
conn.Close();
}
}
3.3 DB中Number类型字段
当执行查询操作时,odp.net在把数据转换成.net数据类型时,会依据此字段的值(或者精度),转换成single,double,decimal等,而不是象微软的OracleDataProvider那样直接转换成decimal类型.
片段:
string sql = "select price from product";//假设price字段的DB类型为number(10,2)
System.Data.DataSet ds= new System.Data.DataSet();
new Oracle.DataAccess.Client.OracleDataAdapter(cmd).Fill(ds) ;
decimal price= (decimal) ds.Tables[0]["price"]; //此处会抛异常,OracleDataReader方法也是一样。
decimal price=Convert.ToDecimal(ds.Tables[0]["price"] )//运行通过。