处理大数据类型
二进制类型
Vastbase G100提供两种不同的方法存储二进制数据。二进制数据可以使用二进制数据类型BYTEA存储在表中,或者使用大对象特性以一种特殊的格式将二进制数据存储在一个独立的表中,然后通过在表中保存一个类型为 OID的值来引用该表。以下为这两种方法的使用示例。
BYTEA
使用BYTEA类型存储二进制数据,可以用.NET自身提供的byte[]类型的操作方式进行读写。
例如:
CREATE TABLE images (imgname text, img bytea);
插入记录
可以通过直接将参数赋值,直接将数据传入Vastbase G100。
FileStream fs = new FileStream(fileUrl, FileMode.Open, FileAccess.Read);
try
{
byte[] buffur = new byte[fs.Length];
fs.Read(buffur, 0, (int)fs.Length); //读取二进制文件
Int Len = (int)fs.Length;
//关闭资源
fs.Close();
....... //建立连接
NpgsqlCommand cmd = new NpgsqlCommand();
cmd.CommandType = CommandType.Text; //指明为文本
cmd.CommandText = "insert into image values (‘I1’, @content)"; //SQL语句
NpgsqlParameter p = new NpgsqlParameter("@content", DbType.Image, Len);
p.Value = buffur ;
cmd.Parameters.Add(p); //给cmd添加参数
cmd.ExecuteNonQuery(); //执行
......
}
还有一种方式,就是上述提到的通过DataSet与数据库连接的方式,通过DataSet,可以直接将数据传入数据库:
DataSet tempDataSet=new DataSet();
string sql = "SELECT * FROM images WHERE 1=0"; //不会有内容,只有表头
NpgsqlDataAdapter objAdapter = new NpgsqlDataAdapter(sql, conn);
objAdapter .Fill(tempDataSet,”temp”); //与数据库建立了连接,并在tempDataSet创建一个空表
//在DataSet的表中插入一条记录
DataRow tempDataRow = tempDataSet.Tables[“temp”].NewRow(); //创建表的新行
tempDataRow["imgname "] =”Image1”; //给新行的imgname 赋值
tempDataRow["img "] =buffur ; //给新行的img 赋值,为二进制数据
//更新至数据库
tempDataSet.Tables[“temp”].Rows.Add(tempDataRow);
stempAdapter.Update(tempDataSet);
读取记录
using(NpgsqlCommand cmd = new NpgsqlCommand("select * from images '", conn));
using(NpgsqlDataReader dr = cmd.ExecuteReader();
{
While(dr.Read())
{
byte[] imageData = (byte[])dr[“img ”];
...... //其它处理
}
}
在这里,二进制数据被读取为byte[]。
大对象功能
使用大对象功能存储二进制数据,需要开启事务来进行读写,使用到LargeObjectManager类对象与LargeObject类对象 。
例如:
CREATE TABLE imageslo (imgname text, imgoid oid);
插入记录
...... //建立conn连接
int noid;
using (NpgsqlTransaction trans = conn.BeginTransaction())
{ //开启事务
try
{
LargeObjectManager lom = new LargeObjectManager(conn); //创建大对象管理器
byte[] buf = new byte[8192];
int readIn = 0;
int noid = lom.Create(LargeObjectManager.WRITE); //创建大对象oid
LargeObject lo = lom.Open(noid, LargeObjectManager.WRITE); //创建大对象
using (FileStream fs = File.OpenRead(fileName)){ //读取文件二进制流
while ((readIn = fs.Read(buf, 0, buf.Length)) > 0)
{ //写入大对象
lo.Write(buf, 0, readIn);
}
}
Lo.Close(); //写完大对象,关闭
string sql = string.Format( "insert into test values ({0},{1})", “Image1”,noid); //格式化字符串构建语句
NpgsqlCommand cmd = new NpgsqlCommand(sql, conn);
cmd .ExecuteNonQuery(); //执行插入记录
trans.Commit(); //事务提交
}
读取记录
...... //建立conn连接
using (NpgsqlTransaction trans = conn.BeginTransaction())
{ //开启事务
/*获取大对象oid*/
int loOid = 0;
string sql = "select imgoid from imageslo where ......";
using (var cmd = new NpgsqlCommand(sql,conn))
{
loOid = Convert.ToInt32(objCommand.ExecuteScalar()); //将结果转换成整数
}
LargeObjectManager lom = new LargeObjectManager(conn); //创建大对象管理器
LargeObject lo = lom.Open(loOid , LargeObjectManager.READ); //打开大对象文件
using (FileStream fs = File.OpenWrite(@"MyFile"))
{ //创建目的文件,将数据写入
int tempmax = lo.Size();
int tempread = 0;
int temppos = 0;
do
{
byte[] buf = lo.Read(8192); //一次性从大对象读取8192个字节
tempread = buf.Length;
if (tempread > 0)
{
fs.Write(buf, 0, tempread);
temppos += tempread;
lo.Seek(temppos); //当前读取位置更新
}
} while (tempread > 0);
fs.Flush();
}
lo.Close(); //读取完毕,关闭大对象
trans.Commit(); //提交事务
}
字符串类型
Vastbase G100中TEXT类型与VARCHAR类型都是可变长的字符串类型,区别在于VARCHAR类型通过VARCHAR(n)中的n来限制最大长度,而TEXT类型没有。TEXT类型与VARCHAR类型几乎没有性能差别,TEXT类型最多可存储1G数据。
使用TEXT类型存储数据时,可用.NET中的Convert功能将二进制数据与文本数据之间来进行转换。例如:
CREATE TABLE images (id int, msg text);
插入记录
Stream s = File.Open(MapPath("MyImage.jpg"), FileMode.Open);
int leng = (int)s.Length;
byte[] by = new byte[leng];
s.Read(by, 0, leng);//把图片读到字节数组中
s.Close();
string str = Convert.ToBase64String(by);//把字节数组转换成字符串
string sql = string.Format( "insert into test values ({0},{1})", “Image1”,noid); //格式化字符串构建语句
NpgsqlCommand cmd = new NpgsqlCommand(sql, conn);
cmd .ExecuteNonQuery(); //执行插入记录
读取记录
在读取记录时,按照获取字符串的方式,就可以获取到在数据库中的TEXT数据。
using (var cmd = new NpgsqlCommand("SELECT * FROM images WHERE id = 1;",conn))
using (NpgsqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// Read
string fieldValue = reader["msg "]; // 获得指定字段的值
...... //后期处理
}
}
reader.Close();
在这里,TEXT数据被读取为string。