最近做一个小程序,功能是把一个软件保存在Oracle11数据表中的人员照片批量导出。保存照片的字段的类型为Long Row格式,代码如下:
class ImportPhotos
{
private const string conn = "Data Source=ds;Password=pw;User ID=user;";
private const string sql = @"select t.zpid, t.zp from photos t;
public void Import()
{
var dbConn = new OracleConnection(conn);
dbConn.Open();
using (var cmd = dbConn.CreateCommand())
{
cmd.CommandText = sql;
cmd.CommandType = CommandType.Text;
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
try
{
var b = reader.GetOracleBinary(1);
var byteZP = b.Value;
var zpid = reader.GetOracleValue(0).ToString();
SavePhoto(byteZP, zpid);
}
catch
{
//todo:
}
}
}
}
}
private void SavePhoto(byte[] stream, string fileName)
{
string baseDir = @"e:\pics\";
string extName = ".jpg";
System.IO.MemoryStream ms = new MemoryStream(stream);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
img.Save(Path.Combine(baseDir, fileName + extName));
}
}
起初使用Oracle官方提供的ODP.NET for Net4.0驱动程序,读取的字段值全部为byte[0]。在网上找了一圈,结果也是抄来抄去,全部没有说出个所以然,也换了用OracleDataAdapter填充DataSet的方法。
var dbConn = new OracleConnection(conn);
dbConn.Open();
using (var cmd = dbConn.CreateCommand())
{
using(var da = new OracleDataAdapter(cmd)){
}
DataSet ds = new DataSet();
da.Fill(ds);
//...
//...
}
问题依旧。
问题的最后解决很出乎意料:
我的同事之前做过个系统,也有照片导出的功能,目标字段也是Long Raw,于是我借来他的代码研究了一下,是用Spring框架做的,可以导出。我发现Spring框架直接引用了微软.net框架的System.Data.OracleClient来访问数据的,于是给了我一个启发,我把程序引用的Oracle的官方驱动用System.Data.OracleClient替换,代码没有做任何更改,运行以后居然成功。
什么意思??