zoukankan      html  css  js  c++  java
  • SQL SERVER 2008中使用VARBINARY(MAX)进行图像存取的实现方法

          在数据库应用项目开发中,经常会使用一些二进制的图像数据,存储和读取显示图像数据主要采用的是路径链接法和内存流法。路径链接法是将图像文件保存在固定的路径下,数据库中只存储图像文件的路径和名称,此方法数据库容量小,存取速度快,但安全性较差;内存流法是将二进制数据直接存储在数据库中,此方法对数据的共享非常方便,安全性相对较高,常用于图像容量不是很大的时候。
    本文主要讨论通过SQL Server 2008使用内存流法如何实现二进制图像数据的存储。
     
    1 VARBINARY(MAX)数据类型简介
      在SQL Server 2000和更早的版本中,如果每条记录的数据量远远超过了一个单独记录的8K,我们常用IMAGE数据类型以二进制存储该数据,在使用IMAGE数据类型时,数据是不和普通数据存储在一起的。一个被称作指针的很小的二进制值,和普通数据存储在一起,这个二进制值指向数据文件里的数据实际存储的位置。对IMAGE数据进行读取、插入数据时需要使用READTEXT[1]及WRITETEXT命令,这两个命令需使用TEXTPTR函数来获得正确的二进制指针,这个二进制指针用于定位物理文件中的数据,使用起来较麻烦。
      虽然在SQL Server 2008中依然提供IMAGE数据类型,但微软计划在未来的SQL Server版本中删除IMAGE数据类型, 用VARBINARY(MAX)数据类型来代替,在该版本下不应当使用IMAGE这种类型。
      VARBINARY(MAX) 为可变长度二进制数据,不限最大长度,常用于数据超出 8,000 字节时,可以直接使用insert命令添加数据,使用起来较简单。
     
    2 使用T-SQL语句将图像文件直接读入VARBINARY(MAX)字段
      首先在SQL Server 2008的查询窗口中创建测试数据库ImageDB,并建立ImageTable表来存储图像数据:
      
       CREATE DATABASE ImageTest
      GO
      USE ImageTest;
      GO
      CREATE TABLE ImageTable
      (
      ImageData varBinary(MAX)
      );
      然后使用Insert命令将其插入到ImageTest表中(此处图像文件为C:aa.jpg),OPENROWSET函数包含访问OLE DB数据源中的远程数据所需的全部连接信息,内置的 BULK 访问接口支持大容量操作,实现的代码为:
    INSERT INTO ImageTable (ImageData)
       SELECT  *
       FROM OPENROWSET(BULK N'C:aa.jpg', SINGLE_BLOB) AS Photo
    GO
      运行Select * from ImageTable语句将会看到该图像的二进制编码,但SQL Server 2008不提供直接查看图片的方法,为了查看图片,我们需要创建应用程序,本文第4部分介绍其实现的方法。
     
    3 在SQL Server中将二进制数据复制到图像文件
      在SQL Server 2008中将二进制数据复制到图像文件,要对Windows的文件进行操作,我们需要用到xp_cmdshell扩展存储过程,在使用之前我们需获得执行该命令的权限:
       
         EXEC sp_configure 'show advanced options', 1
       GO
       RECONFIGURE
       GO
       EXEC sp_configure 'xp_cmdshell', 1
       GO
       RECONFIGURE
       GO
      通过执行xp_cmdshell将二进制数据复制到图像文件:
      
    EXEC   master..xp_cmdshell   'bcp "SELECT ImageData FROM ImageTest.dbo.ImageTable" queryout "c:b.jpg"-T -c'
    Go
      可以看到C盘下增加了一个图像文件bb.jpg。
     
    4 使用C#.NET存取SQL Server 2008中的图像数据
      为在2中创建的ImageTable表添加一个ImagePath字段,用于记录图像的路径及文件名。
    在窗体上添加一个按钮,用于实现将图像文件读入SQL Server,实现的基本过程是先通过openFileDialog控件选择要读入的图像文件,将图像文件转换成二进制流,连接数据库后使用insert命令将二进制流数据存储到SQL Server,实现的代码如下:
      
    public static bool StoreImages(string[] fileNames, string[] filePaths)
            {
                try
                {
                    for (int i = 0; i < fileNames.Length; i++)
                    {
                        string fileName = fileNames[i];
                        string filePath = filePaths[i];
    
                        using (SqlConnection connection = new SqlConnection(PubVariant.ConnectionString))
                        {
                            connection.Open();
                            FileStream byteStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                            byte[] byteImage = new byte[byteStream.Length];
                            byteStream.Read(byteImage, 0, (int)byteStream.Length);
                            string strSql = "insert into Data(Name,Data,DataPath) values(@Name,@Data,@DataPath)";
                            using (SqlCommand cmd = new SqlCommand(strSql, connection))
                            {
                                cmd.Parameters.Add("@Name", SqlDbType.Text);
                                cmd.Parameters.Add("@Data", SqlDbType.Binary);
                                cmd.Parameters.Add("@DataPath", SqlDbType.Text);
                                cmd.Parameters["@Name"].Value = fileName;
                                cmd.Parameters["@Data"].Value = byteImage;
                                cmd.Parameters["@DataPath"].Value = filePath;
                                cmd.ExecuteNonQuery();
                            }
                        }
                    }
    
                    return true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return false;
                }            
            }
      再添加一个按钮,用于实现将SQL Server中二进制数据显示为图像,连接数据库后将ImageTable表的记录绑定到dataGridView控件,虽然dataGridView控件可以将二进制数据显示为图片,但行列间距太小,不好看,所以同时还将图像显示在pictureBox控件中,实现的代码如下:
     
    public static Image GetImageFromName(string fileName)
            {
                try
                {
                    using (SqlConnection connection = new SqlConnection(PubVariant.ConnectionString))
                    {
                        connection.Open();
                        string strSql = "select Data from Data where Name = '" + fileName + "'";
                        SqlCommand cmd = new SqlCommand(strSql, connection);
                        SqlDataReader dr = cmd.ExecuteReader();
                        dr.Read();
                        MemoryStream ms = new MemoryStream((byte[])dr[0]);
                        Image img = Image.FromStream(ms);
                        return img;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return null;
                }
            }
  • 相关阅读:
    Windows 显示隐藏文件
    Python 程序一行代码解决乘法口诀表
    【转发】基于Bert-NER构建特定领域的中文信息抽取框架(上)
    【转发】GET和POST两种基本请求方法的区别
    【转发】实现yolo3模型训练自己的数据集总结
    第十章集合总结
    2016-2017 201671010134 异常处理
    JAVA基础编程
    2016-2017 201671010134 第六章总结
    java总结
  • 原文地址:https://www.cnblogs.com/qxzy/p/3835483.html
Copyright © 2011-2022 走看看