相关知识

上传二进制大对象(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. RC4加密算法

    RC4是Ron Rivest在1987年设计的密钥长度可变的流加密算法.它加解密使用相同的密钥,因此也属于对称加密算法.RC4是有线等效加密(WEP)中采用的加密算法,也曾经是TLS可采用的算法之一. ...

  2. mysql二进制包安装与配置实战记录

    导读 一般中小型网站的开发都选择 MySQL 作为网站数据库,由于其社区版的性能卓越,搭配 PHP .Linux和 Apache 可组成良好的开发环境,经过多年的web技术发展,在业内被广泛使用的一种 ...

  3. Xutils3的使用

    Xutils是前两年很火的一个三方库(githup地址),是一个工具类,分为4个模块:DbUtils.HttpUtils.ViewUtils. BitmapUtils,还有一个非常使用功能就是LogU ...

  4. Remap BMW F11 2010 all ECUs with E-Sys and ENET cable

    Just wanted to share some experiences remaping all the ECUs in my F11 2010 BMW, hopefully other BMW ...

  5. 【Java的JNI快速学习教程】

    1. JNI简介 JNI是Java Native Interface的英文缩写,意为Java本地接口. 问题来源:由于Java编写底层的应用较难实现,在一些实时性要求非常高的部分Java较难胜任(实时 ...

  6. [wordpress]wp-api-jwt-auth 尝试添加运行在多站点中 need change

    Hi,Thank you this plugin,because i use this plugin on Wordpress one Network,so the request other api ...

  7. 数理方程:Laplace变换 & 留数(更新中)

    更新:25 APR 2016 Laplace变换 设函数\(f(t)\)在\(t>0\)时有定义,积分 \(F(s)=\int_0^{+\infty}f(t)e^{-st}dt \qquad ( ...

  8. Android 百度地图开发(一)--- 申请API Key和在项目中显示百度地图

      标签: Android百度地图API Key  分类: Android 百度地图开发(2)    最近自己想研究下地图,本来想研究google Map,但是申请API key比较坑爹,于是从百度地 ...

  9. SharedPreferences保存用户登录信息

    UI界面:

  10. Android OpenGL ES(三)----编程框架

    首先当然是创建Android项目,你可以选择最新的Android Studio也可以选择eclipse都是一样的.我们重点讲解开发OpenGL ES的流程 1.定义顶点着色器和片段着色器 第一节我们讲 ...