相关知识

上传二进制大对象(Binary Large Object)(如图片、视频等)的基本编程步骤是:

  • 在数据库中使用varbinary(MAX)、varchar(MAX)或者nvarchar(MAX)等数据类型记录BLOB
  • 使用INSERT INTO语句,在表中建立一个新行
  • 使用 UPDATE xxx.WRITE 语句,逐段将BLOB写入大数据字段中

代码示例

  1. 数据库:沿用AccountDBforSQLInjection,使用下列的SQL语句建立一个包含varbinary(MAX)字段类型的表:

        CREATE TABLE [dbo].[Photo](
    [PhotoID] [int] IDENTITY(1,1) NOT NULL,
    [PhotoName] [nvarchar](50) NULL,
    [PhotoData] [varbinary](max) NULL,
    CONSTRAINT [PK_Photo] PRIMARY KEY CLUSTERED
    (
    [PhotoID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

    该表的主键PhotoID是自增长列

  2. SQL语句定义:
    static string strConn = @"server=Joe-PC;database=AccountDBforSQLInjection;uid=sa;pwd=root";
    //以下SQL命令在Photo表中创建一个新行,并且返回新行的PhotoID(该字段是自增长的)
    //PhotoData不能初始化为NULL,因为.WRITE字句无法在NULL字段上操作
    static string strInsertCmd = @"INSERT INTO Photo(PhotoName, PhotoData) Values(@PhotoID, 1);SELECT @PhotoID=@@IDENTITY";
    //@@identity的作用是返回最后插入的标识值,使用它来获取插入数据后的标识符。
    //但有一点是需要注意的,@@identity返回的是最后的标识符,所以,要想正确的返回插入后的标识符,那么就必须保证,你想要的结果是最后的标识符,否则就会隐藏bug。
    //以下SQL语句用于更新PhotoData字段中的一部分数据
    //@data表示待写入的数据,@offset表示在该字段的哪个位置开始写起,@length表示写入多少个字节
    static string strUploadCmd = @"UPDATE Photo SET PhotoData.WRITE(@data, @offset, @length) WHERE PhotoID=@PhotoID";
  3. 创建新行:
            // 在图片表中创建新行
    static int InsertPhoto()
    {
    using (SqlConnection conn = new SqlConnection(strConn))
    {
    conn.Open();
    SqlCommand cmd = new SqlCommand(strInsertCmd, conn);
    cmd.Parameters.Add("@PhotoName", SqlDbType.NVarChar, ).Value = "flower.jpg";
    SqlParameter id = cmd.Parameters.Add("@PhotoID", SqlDbType.Int);
    id.Direction = ParameterDirection.Output;
    cmd.ExecuteNonQuery();
    return Convert.ToInt32(id.Value);
    }
    }
  4. 向新行中写入图片数据:
            //从磁盘文件读入图片数据,然后逐段写入数据库
    static void UploadPhoto(int photoID)
    {
    using (SqlConnection conn = new SqlConnection(strConn))
    {
    SqlCommand cmd = new SqlCommand(strUploadCmd, conn);
    cmd.Parameters.Add("@PhotoID", SqlDbType.Int).Value = photoID;
    SqlParameter data = cmd.Parameters.Add("@data", SqlDbType.VarBinary, -);
    SqlParameter offset = cmd.Parameters.Add("@offset", SqlDbType.Int);
    offset.Value = ;
    SqlParameter length = cmd.Parameters.Add("@length", SqlDbType.Int); int BUF_SIZE = ;
    string fileName = "..\\..\\picture.jpg"; FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
    byte[] buf = new byte[BUF_SIZE];
    int read = fs.Read(buf, , BUF_SIZE);
    conn.Open(); while (read > )
    {
    length.Value = read;
    data.Value = buf;
    cmd.ExecuteNonQuery();
    offset.Value = Convert.ToInt32(offset.Value) + read;//偏移量逐次递进
    read = fs.Read(buf, , BUF_SIZE);
    } fs.Close();
    }
    }
  5. 下载图片数据,检测上传是否成功:
            //将前述写入的图片从数据库读出来,保存到文件中
    static void DownloadPhoto(int photoID)
    {
    using (SqlConnection conn = new SqlConnection(strConn))
    {
    string strCmd = "select * From photo where PhotoID=" + photoID.ToString();
    SqlCommand cmd = new SqlCommand(strCmd, conn);
    conn.Open();
    SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
    dr.Read();
    FileStream fs = new FileStream("..\\..\\savedpicture.jpg", FileMode.OpenOrCreate, FileAccess.Write);
    byte[] buf = new byte[];
    long bytesRead = ;
    long startIndex = ;
    while ((bytesRead = dr.GetBytes(, startIndex, buf, , )) > )
    {
    fs.Write(buf, , (int)bytesRead);
    startIndex += bytesRead;
    }
    fs.Close();
    }
    }
  6. 主函数:
            static void Main(string[] args)
    {
    int photoID = InsertPhoto();
    UploadPhoto(photoID);
    DownloadPhoto(photoID);
    }

程序说明

本程序将从项目文件夹上传picture.jpg文件至数据库,然后又从数据库中下载数据保存为savedpicture.jpg文件,以便检查上传是否成功

ADO.NET笔记——存储二进制大对象(BLOB)的更多相关文章

  1. ADO.NET笔记——读取二进制大对象(BLOB)

    相关知识: 在SQL Server中,一般情况下,每行数据的总长度不能超过8K字节.因此,下列数据类型的长度,也不能超过8K字节:binary,char(),nchar(),varchar(),nva ...

  2. 3.2 配置构建Angular应用——简单的笔记存储应用

    本节我们会通过构建一个简单的笔记存储应用(可以载入并修改一组简单的笔记)来学习如何应用Angular的特性.这个应用用到的特性有: 在JSON文件中存储笔记 展示.创建.修改和删除笔记 在笔记中使用M ...

  3. memcached学习笔记——存储命令源码分析下篇

    上一篇回顾:<memcached学习笔记——存储命令源码分析上篇>通过分析memcached的存储命令源码的过程,了解了memcached如何解析文本命令和mencached的内存管理机制 ...

  4. memcached学习笔记——存储命令源码分析上篇

    原创文章,转载请标明,谢谢. 上一篇分析过memcached的连接模型,了解memcached是如何高效处理客户端连接,这一篇分析memcached源码中的process_update_command ...

  5. ADO学习笔记之注入漏洞与参数化查询

    ADO学习笔记之注入漏洞与参数化查询 作为新手,在学习ADO程序时,使用 sql 语言查询数据时,很容易写类似如下代码: using (SqlConnection con = new SqlConne ...

  6. 3.2.1 配置构建Angular应用——简单的笔记存储应用——编辑功能

    本节我们会接着上节课的内容,继续来完成使用Angular来创建简单的笔记存储应用,上一节课,我们完成了笔记的展示功能,本节课,我们来完成编辑功能. 编辑主要是两个功能:编辑现有的笔记以及创建新笔记.首 ...

  7. 3.2.1 配置构建Angular应用——简单的笔记存储应用——展示功能

    本节我们会通过构建一个简单的笔记存储应用(可以载入并修改一组简单的笔记)来学习如何应用Angular的特性.这个应用用到的特性有: 在JSON文件中存储笔记 展示.创建.修改和删除笔记 在笔记中使用M ...

  8. 【mysql】关于InnoDB存储引擎 text blob 大字段的存储和优化

    最近在数据库优化的时候,看到一些表在设计上使用了text或者blob的字段,单表的存储空间已经达到了近100G,这种情况再去改变和优化就非常难了 一.简介 为了清楚大字段对性能的影响,我们必须要知道i ...

  9. ADO.net笔记

    1.DbConnectionConnection对象也称为数据库连接对象,Connection对象的功能是负责对数据源的连接.所有Connection对象的基类都是DbConnection类.Conn ...

随机推荐

  1. 全栈一路坑之使用django创建博客

    最近在看一篇全栈增长工程师实战,然后学习里面的项目,结果发现作者用的技术太过老旧,好多东西都已经被抛弃了,所以结合着官方文档和自己的一些理解将错误的信息替换一下,边写边学习 准备工作和工具 作者说需要 ...

  2. c++ 设计模式6 (Decorator 装饰模式)

    4. “单一职责”类模式 在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式代表: Decorato ...

  3. 1.4.2 solr字段类型--(1.4.2.3)使用货币和汇率

    1.4.2 solr字段类型 (1.4.2.1) 字段类型定义和字段类型属性. (1.4.2.2) solr附带的字段类型 (1.4.2.3) 使用货币和汇率 (1.4.2.4) 使用Dates(日期 ...

  4. 查找字符对应Unicode码的十进制数字

    //将字符转换为Unicode码中字符对应十进制数字 int byte0 = 'A' & 0xff;//byte0=65 参考文档:http://baike.baidu.com/view/26 ...

  5. [转]DllMain中不当操作导致死锁问题的分析——DllMain中要谨慎写代码(完结篇)

    在CSDN中发现这篇文章,讲解的比较详细,所以在这里备份一个.原文链接:http://blog.csdn.net/breaksoftware/article/details/8167641 DllMa ...

  6. 《Cortex-M0权威指南》之体系结构---嵌套中断控制器(NVIC)

    转载请注明来源:cuixiaolei的技术博客 为了管理中断请求的优先级并处理其他异常,Cortex-M0处理器内置了嵌套中断控制器(NVIC).NVIC的一些可编程控制器控制着中断管理功能,这些寄存 ...

  7. flexpaper 在线观看 PPT,PDF,DOC等文档

    0.安装环境.可以参考http://www.cnblogs.com/star-studio/archive/2011/12/09/2281807.html     百度关键字 仿百度文库方案 1.借用 ...

  8. IE浏览器部分版本不支持opacity透明度属性问题

    半透明部分设置样式:opacity:0.7在ie9/ie10/ff/chrome/opera/safari显示正常. 但是这样在ie6-ie8中是不支持的,需要加上下面这句话: filter: pro ...

  9. sql 游标例子 根据一表的数据去筛选另一表的数据

    sql 游标例子 根据一表的数据去筛选另一表的数据 DECLARE @MID nvarchar(20)DECLARE @UTime datetime DECLARE @TBL_Temp table( ...

  10. oracle 常用技巧及脚本

    [Q]怎么样查询特殊字符,如通配符%与_ [A]select * from table where name like 'A/_%' escape '/' [Q]如何插入单引号到数据库表中 [A]可以 ...