您的位置:首页 > 数据库

SQL Server 2008中的FileStream支持

2009-06-12 01:04 288 查看
该篇文章是我于2009年6月10日通过自己编写的工具,批量从位于在博客园的博客站点(http://chenxizhang.cnblogs.com)同步而来。文章中的图片地址仍然是链接到博客园的。特此说明!

陈希章

原文地址:http://www.cnblogs.com/chenxizhang/archive/2009/04/25/1443283.html

原文标题:SQL Server 2008中的FileStream支持

原文发表:2009/4/24 22:48:00




服务器有一个属性,即指定该服务器是怎么支持文件流的 /* 实际上文件流的出现就是为了解决对大对象的存储中一个矛盾。 对于大对象,第一种方式是存储在数据库里面,这种方式一般使用image字段,或者varbinary(max)来做。好处是可以统一备份,但实际上读取效率比较低。大于1MB的文件就会有问题 第二种方式是文件存储在文件系统,而数据库中存储了一个路径。这种方式数据库压力减轻了,却很不方便统一备份和管理。 SQL SERVER 2008的文件流其实就是二者的统一。文件还是放在文件系统的,但由数据库进行管理。可以统一备份和还原。 FILESTREAM不是一个字段类型,它定义在字段后面,声明该列用于文件流即可。该列依然是用二进制保存的 一般都是在数据库中要特别添加一个文件组和一个或多个文件用来存储FileStream的数据的。



然后,在磁盘上面有一个目录(Test),里面会有一个filestream.hdr文件

      客户端是透明的。无需要什么修改。 */ --这段代码的作用是启用服务器支持文件流 EXEC sp_filestream_configure @enable_level = 3; CREATE DATABASE Archive ON PRIMARY ( NAME = Arch1, FILENAME = 'c:/lab/archdat1.mdf'), FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM( NAME = Arch3, FILENAME = 'c:/lab/filestream1') LOG ON ( NAME = Archlog1, FILENAME = 'c:/lab/archlog1.ldf') GO CREATE TABLE Archive.dbo.Records ( [Id] [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE, [SerialNumber] INTEGER UNIQUE, [Chart] VARBINARY(MAX) FILESTREAM NULL --这一句指示该列要用文件流存储 --这里还可以做一些改进,就是加入文件类型的一个字段(FileName) ) FILESTREAM_ON FileStreamGroup1 --该行指示存储到哪一个文件流文件组 GO --下面代码无法运行,如果一个表要使用文件流,则必须有一个GUID列,而且作为唯一键列 CREATE TABLE Archive.dbo.Records2 ( --[Id] [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE, [SerialNumber] INTEGER UNIQUE, [Chart] VARBINARY(MAX) FILESTREAM NULL --这一句指示该列要用文件流存储 ) FILESTREAM_ON FileStreamGroup1 --该行指示存储到哪一个文件流 GO INSERT INTO Archive.dbo.Records VALUES (newid (), 1, NULL); GO INSERT INTO Archive.dbo.Records VALUES (newid (), 2, CAST ('' as varbinary(max))); GO INSERT INTO Archive.dbo.Records VALUES (newid (), 3, CAST ('Seismic Data' as varbinary(max))); GO UPDATE Archive.dbo.Records SET [Chart] = CAST('Xray 1' as varbinary(max)) WHERE [SerialNumber] = 2; DELETE Archive.dbo.Records WHERE SerialNumber = 1; GO SELECT * FROM Archive.dbo.Records GO 对于客户端编程来说,是没有区别的,这只是服务器的一个存储改变 保存 //保存音乐文件 try { OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = "音乐文件(*.mp3)|*.mp3"; if (dialog.ShowDialog() == DialogResult.OK) { using (SqlConnection conn = new SqlConnection(CONNECTIONSTRING)) { conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = "INSERT INTO BINARYTABLE(BINARYCONTENTS) VALUES(@file)"; FileStream fs = new FileStream(dialog.FileName, FileMode.Open); byte[] bytes = new byte[fs.Length]; fs.Read(bytes, 0, bytes.Length); SqlParameter param = new SqlParameter("@file", SqlDbType.VarBinary,1000000); param.Value = bytes; cmd.Parameters.Add(param); MessageBox.Show(cmd.ExecuteNonQuery() == 1 ? "成功保存文件" : "保存文件失败"); fs.Close(); } conn.Close(); } } else MessageBox.Show("用户取消了操作"); } catch (Exception ex) { MessageBox.Show(ex.Message); } 读取 //读取音乐文件 try { using (SqlConnection conn = new SqlConnection(CONNECTIONSTRING)) { conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = "select top 1 BinaryContents from BinaryTable order by ID desc"; SqlDataReader reader = cmd.ExecuteReader(); SaveFileDialog dialog = new SaveFileDialog(); dialog.Filter = "音乐文件(*.mp3)|*.mp3"; if (dialog.ShowDialog() == DialogResult.OK) { reader.Read(); System.Data.SqlTypes.SqlBinary result = reader.GetSqlBinary(0);//值得注意的是这里并没有什么GetSqlImage的方法 FileStream fs = new FileStream(dialog.FileName, FileMode.Create); fs.Write(result.Value, 0, result.Length); fs.Close(); reader.Close(); } else MessageBox.Show("用户取消操作"); } conn.Close(); } } catch (Exception ex) { MessageBox.Show(ex.Message); }
作者:陈希章

出处:http://blog.csdn.net/chen_xizhang

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: