Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7933258
  • 博文数量: 124
  • 博客积分: 2880
  • 博客等级: 少校
  • 技术积分: 873
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-16 17:08
文章分类

全部博文(124)

文章存档

2011年(28)

2010年(60)

2009年(36)

我的朋友

分类: 数据库开发技术

2009-10-14 19:35:07

 
发贴心情
[转帖]SQL Server:存储图像和BLOB文件
什么是BLOB 

  首先,我们来比较两种文件类型ASCII和二进制。存储在SQL Server中的大部分数据值都是由ASCII(美国信息交换标准代码)字符组成。简单说来,ASCII字符就是能够在计算机键盘上找到的字母、数字和符号。我们可以通过记事本等文本编辑器对只包含了ASCII字符的文件进行修改且不会对文件造成任何破坏。而二进制文件,不仅包含了ASCII字符,还包含了键盘上没有的特殊控制字符和字节组合。如果你用记事本打开一个MP3文件,并删除其中的一些字符企图使歌曲变短,很可能会破坏掉整个文件,导致该MP3不能再正常播放,这是因为记事本只能用来编辑ASCII字符,而无法正确解析或创建二进制位。其他二进制数据包括图像和可执行文件汇编程序。BLOB顾名思义就是大型的二进制文件。

  为什么要在SQL Server存储BLOB

  有人喜欢在SQL server数据库里存储二进制对象,也有人反对这样做,正所谓公说公有理,婆说婆有理。我们应当两方面都考虑周全。举一个看起来比较真实的例子,假设我们在一个典型的销售企业当数据库管理员。这个企业通常有很多待售的产品线,包含不同类别的产品,而产品线以下的水平就是单个产品或部件,我们把他们称之为构件。对于每个构件,都提供了标准的详细目录清单,如价格、成本、现有数量、供应商等等。此外,很多构件可能还有用来描述该构件销售手册或宣传册,这些宣传册往往以PDF、幻灯片或某种类型的图像等电子文档形式出现。处理这些电子文档的一个方法就是把他们都放入一个文件服务器,并为每个构件创建一个目录。这个一开始可能管用,不过当客户或雇员想要设计一个可以调用这些文档的应用程序,只需要输入搜索参数就可以让数据库返回匹配的销售手册时,问题就来了。例如,输入“显示所有售价低于100元的蓝色构件的文档”。这时,就会涉及到将应用程序与数据库绑定的问题了。因此,在这个系列文章的后半部分,我们会创建一个连接到SQL Server的Visual Studio应用程序来检索构件销售手册。

  文件存储位置

  第一个需要解决的问题是要将这些电子宣传小册子存放在哪里。我们可以用一个应用程序来存储导向该文档的文件系统路径信息,例如“e:saleswidgeta-picture.jpg”,将这些信息存放在varchar类型的数据列里,而把实际的文档保留在文件系统;也可以将实际的图像文件直接放在一个二进制或图像类型的数据列里。回答下面几个重要问题将有助于确定最佳的选择方案:

  · 性能:这些二进制对象对性能要求是不是很高,如视频流?如果是的话,保留在文件系统会比用二进制流文件存储要好。

  · 大小:需要检索的二进制对象是不是很大?有没有超过1MB?如果对象很大,那么用文件系统来显示和读取该对象的效率往往比从SQL Server显示和读取的效率更高。如果二进制对象比较小,也就是说每个构件只有很小的图像文件,那么将它们存储在SQL server内则绰绰有余。

  · 安全:对这些二进制对象的访问是否要高度关注安全性。如果这些对象存储在SQL Server中,那么可以通过常规的数据库访问方式来管理其安全性。如果文件存储在文件系统,那么就需要另外设置更安全的替代管理办法了。

  · 客户访问:客户对数据库的访问通过什么方式,是通过ODBC还是Native SQL Drive?对于大型视频流,以ODBC方式连接的客户可能出现连接超时和连接失败的问题。

  · 碎片:如果要对这些二进制对象进行频繁的修改操作,或者这些文件很大,那么文件系统处理碎片的能力可能比SQL Server更好。

  · 事务:是否需要进行事务控制,如果需要,那么SQL Server可能更好,因为其具有内置解决方案。

  如果您想更深入探讨这个关于将BLOB文件存储在数据库还是文件系统的问题,以及想知道上面提到的1MB大小标准的划分有什么依据,可以通过以下链接,参阅微软的技术文献: .

  数据类型

  回到第一个例子,我们将要创建一个应用程序来存储各个产品的相关图片。因为这些文件都很小,所以我们会选择将它们直接存储在SQL Server里。在SQL Server 2000中,有两种不同的数据类型选择类群用来存储这些文件类型:二进制和图像(Image)。二进制类群包括三种不同的数据类型。第一种就是标准二进制数据类型Binary,但其要求固定的数据长度。对于上面的例子,由于我们的图片大小不等,所以我们需要使用varbinary数据类型,这里的“var”就是变量的意思。Varbinary数据类型的最大长度为8000字节。从SQL Server 2005开始,“varbinary(max)”也包含在二进制数据类型的类群当中了。其关键词MAX就表示大小不限。如果SQL Server的版本是2005以前的,而数据长度又超过8000字节的话,就可以使用图像数据类型进行存储了。这种数据类型的文件大小可变,最大可存储2GB的文件。虽然图像数据类型也包含在SQL Server 2005和2008中,但在这些版本下不应当使用这种类型。微软称,还保留图像数据类型是未来向下兼容之需,在将来某个时候就会将其舍弃。因此,本例中将使用二进制数据类型,这个类群的三种类型扼要重述如下:

  · Binary:文件大小固定,最大长度可达8000字节;

  · VarBinary(n): 文件大小可变,最大长度可达8000字节,(n指明最大文件长度);

  · VarBianry(max): 文件大小可变,不限最大长度。

  总结

  在本系列的下一篇文章当中,我们会继续探讨在SQL Server存储BLOB文件的问题,通过创建 Visual Studio应用程序来对SQL Server二进制数据类型进行读写操作。VarBinary(MAX)数据类型的使用技巧将在介绍SQL Server 2008新的文件流数据类型选项后进行探讨。

ip地址已设置保密
2009-4-5 11:22:00
杨桥柳
帅哥哟,离线,有人找我吗?
双子座5-30
头衔:江南烟雨
等级:尊者
威望:4
文章:8236
积分:69186
魅力:31756
现金货币:113486
注册:2008年12月17日
2
 

发贴心情
在本系列的第一篇文章中,我们讨论了二进制和BLOB(二进制大型对象)的定义,以及在什么情况下应当将这些对象存储在SQL Server里。将图像和二进制数据存储在SQL Server内部的原因包括方便安全性管理、客户访问之便和事务控制。本文将着眼于varBinary(MAX)数据类型,在SQL Server 2005和2008中都有这种数据类型,其扩展说明符(MAX)意味着不设置文件大小的上限。“var”指文件大小是可变,不像标准二进制数据类型那样是个固定值。在SQL Server的联机丛书提供了三种二进制数据类型的使用条件说明:当表列的所有输入数据大小为固定值(且长度小于8000字节)时,使用标准二进制Binary数据类型;当表列的输入数据长度有很大差别(且长度均小于8000字节)时,使用varBinary数据类型;当表列输入数据长度超过8000字节时,使用varBinary(max) 数据类型。对于SQL Server 2000,则使用图像(Image)数据类型。不过请记住,微软已经声明图像数据类型是为了向下兼容才保留下来的,而且可能会在未来的版本中停止使用。

  例表

  首先,我们要创建一个测试数据库和表来装载我们的图片。使用以下的T-SQL语句:

  USEmaster;
  GO
  CREATEDATABASETest;
  GO
  USETest;
  GO
  CREATETABLEBLOBTest
  (
  TestIDintIDENTITY(1,1),
  BLOBNamevarChar(50),
  BLOBDatavarBinary(MAX)
  );

  在本例中,列的名称为 BLOBData,不过您可以使用任何标准的SQL名称为列命名。二进制数据类型对命名没有任何限制。

  如果您运行的是SQL Server 2005和2008,找一张小图片,并执行下面的T-SQL语句插入该图像来测试数据库。该语句在SQL Server 2000中无效,因为只有varBinary(MAX)数据类型才能成为插入目标:

INSERT INTO BLOBTest
(BLOBName, BLOBData)
SELECT 'First test file',
 BulkColumn FROM OPENROWSET(
 Bulk 'D:  est.jpg', SINGLE_BLOB) AS BLOB

  这里用“D:  est.jpg”代入作为文件的文件系统路径。OPENROWSET语句允许SQL从外部数据源提供程序来存取数据。Bulk是特别为OPENROWSET插入文件和图像而设计的数据源提供程序。想了解详细的信息,可以查阅SQL Server的联机丛书。执行选择表的操作将产生如下显示的一条记录:

  SELECT*
  FROMBLOBTest

图片点击可在新窗口打开查看

  SELECT语句会核实数据是否已经插入,不过这还不是在SQL中查看该图片的方法。为了查看图片,我们需要创建一个小的Visual Studio应用程序。

  二进制数据读取

  本例将从SQL读取已存储的图像,并利用Visual Studio在网页上展示图像。创建一个没有代码分离的新页面。代码分离的例子稍后再做介绍。

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%
  string sConn = @"server=.; database=Test; Integrated Security=True";
  SqlConnection objConn = new SqlConnection(sConn);
  objConn.Open();
  string sTSQL =

"SELECT BLOBData FROM BLOBTest";
  SqlCommand objCmd = new SqlCommand(sTSQL, objConn);
  objCmd.CommandType = CommandType.Text;
  SqlDataReader dr = objCmd.ExecuteReader();
  dr.Read();
  Response.BinaryWrite((byte[])dr["BLOBData"]);
  objConn.Close();
%>
  
  
  

  Untitled Page


  

  

  

  



   

  该网页将使用sConn变量来查找数据库。“Integatred Security = True”将指定使用的Windows安全机制。Server名称应当是您的服务器名,如果SQL server和网页服务器再同一台本地机上,就可以使用点来代替。SQL语句只是获取图像,不过在后面的例子中,我们还要查询文件名,并构建一个更真实化的应用程序。指令类型设置为“test”的意思是传递一条SQL语句(相对于存储过程的名称)。

  下面要用的语句:

  SqlCommand objCmd = new SqlCommand(sTSQL, objConn);

  创建一个将SQL语句和连接绑定在一起的指令对象,然后在以下的语句中执行该指令对象:

  SqlDataReader dr = objCmd.ExecuteReader();

  此语句为该指令对象返回指定并设置了一个新的DataReader。dr.Read语句加载了第一条结果(也是本例中唯一的结果)。如果我们不能保证能够成功读取数据,那么可以使用IF语句来进行测试,在本系列的下一篇文章会举这样一个例子。

  现在DataReader读取了图像二进制数据,并使用Response.BinaryWrite来将数据流入到指定网页。注意网页的html是空的,没有任何内容。BinaryWrite不需要任何的html对象。事实上,网页上的任何html都不会显示出来,例如我们可以在div之间粘贴一段字符串:


 Enjoy this image
  

  但当打开运行网页时,只显示了图像,并没有显示该字符串: 

图片点击可在新窗口打开查看

  在我们例子里的数据库中,在SQL Server中还存放了相关的其他数据,例如文件名,我们想要让这些数据和该图像一起在页面中显示出来。因为Binary Write会覆盖页面上的任何html,所以我们需要另外想一个解决办法。将该页面存储为GetPicture.aspx。创建一个新页面,并在上面放置一个图像控件,将图像的网址指向GetPicture页,如下所示:

<%@ Page Language="C#" %>
   onal//EN" "">
  
  

  Untitled Page


  


  

    Here is the image
  

  


     

  因为存储在SQL Server的二进制流不能够直接传递给图像空间,所以间接的传递包含该二进制流的网页。

  总结

  二进制数据可以存储在SQL Server,并通过一个网页应用程序进行查询。在本系列的下一篇文章中,我们将创建一个网页应用程序来把图像插入到SQL当中。另外,还会对本文中的例子进行扩展,包括将图片的文件名传递会应用程序,通过传递一个特定的图像名来检索,并对这些应用程序进行转换以使用存储过程和代码分离页面。

  因为存储在SQL Server的二进制流不能够直接传递给图像空间,所以间接的传递包含该二进制流的网页。

  总结

  二进制数据可以存储在SQL Server,并通过一个网页应用程序进行查询。在本系列的下一篇文章中,我们将创建一个网页应用程序来把图像插入到SQL当中。另外,还会对本文中的例子进行扩展,包括将图片的文件名传递会应用程序,通过传递一个特定的图像名来检索,并对这些应用程序进行转换以使用存储过程和代码分离页面。

  因为存储在SQL Server的二进制流不能够直接传递给图像空间,所以间接的传递包含该二进制流的网页。

  总结

  二进制数据可以存储在SQL Server,并通过一个网页应用程序进行查询。在本系列的下一篇文章中,我们将创建一个网页应用程序来把图像插入到SQL当中。另外,还会对本文中的例子进行扩展,包括将图片的文件名传递会应用程序,通过传递一个特定的图像名来检索,并对这些应用程序进行转换以使用存储过程和代码分离页面。

  该网页将使用sConn变量来查找数据库。“Integatred Security = True”将指定使用的Windows安全机制。Server名称应当是您的服务器名,如果SQL server和网页服务器再同一台本地机上,就可以使用点来代替。SQL语句只是获取图像,不过在后面的例子中,我们还要查询文件名,并构建一个更真实化的应用程序。指令类型设置为“test”的意思是传递一条SQL语句(相对于存储过程的名称)。

  下面要用的语句:

  SqlCommand objCmd = new SqlCommand(sTSQL, objConn);

  创建一个将SQL语句和连接绑定在一起的指令对象,然后在以下的语句中执行该指令对象:

  SqlDataReader dr = objCmd.ExecuteReader();

  此语句为该指令对象返回指定并设置了一个新的DataReader。dr.Read语句加载了第一条结果(也是本例中唯一的结果)。如果我们不能保证能够成功读取数据,那么可以使用IF语句来进行测试,在本系列的下一篇文章会举这样一个例子。

  现在DataReader读取了图像二进制数据,并使用Response.BinaryWrite来将数据流入到指定网页。注意网页的html是空的,没有任何内容。BinaryWrite不需要任何的html对象。事实上,网页上的任何html都不会显示出来,例如我们可以在div之间粘贴一段字符串:


 Enjoy this image
  

  但当打开运行网页时,只显示了图像,并没有显示该字符串: 

图片点击可在新窗口打开查看

  在我们例子里的数据库中,在SQL Server中还存放了相关的其他数据,例如文件名,我们想要让这些数据和该图像一起在页面中显示出来。因为Binary Write会覆盖页面上的任何html,所以我们需要另外想一个解决办法。将该页面存储为GetPicture.aspx。创建一个新页面,并在上面放置一个图像控件,将图像的网址指向GetPicture页,如下所示:

<%@ Page Language="C#" %>
  

onal//EN" "">
  
  

  Untitled Page


  

  

    Here is the image
  

  



     

  因为存储在SQL Server的二进制流不能够直接传递给图像空间,所以间接的传递包含该二进制流的网页。

  总结

  二进制数据可以存储在SQL Server,并通过一个网页应用程序进行查询。在本系列的下一篇文章中,我们将创建一个网页应用程序来把图像插入到SQL当中。另外,还会对本文中的例子进行扩展,包括将图片的文件名传递会应用程序,通过传递一个特定的图像名来检索,并对这些应用程序进行转换以使用存储过程和代码分离页面。

  因为存储在SQL Server的二进制流不能够直接传递给图像空间,所以间接的传递包含该二进制流的网页。

  总结

  二进制数据可以存储在SQL Server,并通过一个网页应用程序进行查询。在本系列的下一篇文章中,我们将创建一个网页应用程序来把图像插入到SQL当中。另外,还会对本文中的例子进行扩展,包括将图片的文件名传递会应用程序,通过传递一个特定的图像名来检索,并对这些应用程序进行转换以使用存储过程和代码分离页面。

  因为存储在SQL Server的二进制流不能够直接传递给图像空间,所以间接的传递包含该二进制流的网页。

  总结

  二进制数据可以存储在SQL Server,并通过一个网页应用程序进行查询。在本系列的下一篇文章中,我们将创建一个网页应用程序来把图像插入到SQL当中。另外,还会对本文中的例子进行扩展,包括将图片的文件名传递会应用程序,通过传递一个特定的图像名来检索,并对这些应用程序进行转换以使用存储过程和代码分离页面。

  该网页将使用sConn变量来查找数据库。“Integatred Security = True”将指定使用的Windows安全机制。Server名称应当是您的服务器名,如果SQL server和网页服务器再同一台本地机上,就可以使用点来代替。SQL语句只是获取图像,不过在后面的例子中,我们还要查询文件名,并构建一个更真实化的应用程序。指令类型设置为“test”的意思是传递一条SQL语句(相对于存储过程的名称)。

  下面要用的语句:

  SqlCommand objCmd = new SqlCommand(sTSQL, objConn);

  创建一个将SQL语句和连接绑定在一起的指令对象,然后在以下的语句中执行该指令对象:

  SqlDataReader dr = objCmd.ExecuteReader();

  此语句为该指令对象返回指定并设置了一个新的DataReader。dr.Read语句加载了第一条结果(也是本例中唯一的结果)。如果我们不能保证能够成功读取数据,那么可以使用IF语句来进行测试,在本系列的下一篇文章会举这样一个例子。

  现在DataReader读取了图像二进制数据,并使用Response.BinaryWrite来将数据流入到指定网页。注意网页的html是空的,没有任何内容。BinaryWrite不需要任何的html对象。事实上,网页上的任何html都不会显示出来,例如我们可以在div之间粘贴一段字符串:


 Enjoy this image
  

  但当打开运行网页时,只显示了图像,并没有显示该字符串: 

图片点击可在新窗口打开查看

  在我们例子里的数据库中,在SQL Server中还存放了相关的其他数据,例如文件名,我们想要让这些数据和该图像一起在页面中显示出来。因为Binary Write会覆盖页面上的任何html,所以我们需要另外想一个解决办法。将该页面存储为GetPicture.aspx。创建一个新页面,并在上面放置一个图像控件,将图像的网址指向GetPicture页,如下所示:

<%@ Page Language="C#" %>
  

onal//EN" "">
  
  

  Untitled Page


  

  

    Here is the image
  

  



   

  因为存储在SQL Server的二进制流不能够直接传递给图像空间,所以间接的传递包含该二进制流的网页。

  总结

  二进制数据可以存储在SQL Server,并通过一个网页应用程序进行查询。在本系列的下一篇文章中,我们将创建一个网页应用程序来把图像插入到SQL当中。另外,还会对本文中的例子进行扩展,包括将图片的文件名传递会应用程序,通过传递一个特定的图像名来检索,并对这些应用程序进行转换以使用存储过程和代码分离页面。

  因为存储在SQL Server的二进制流不能够直接传递给图像空间,所以间接的传递包含该二进制流的网页。

  总结

  二进制数据可以存储在SQL Server,并通过一个网页应用程序进行查询。在本系列的下一篇文章中,我们将创建一个网页应用程序来把图像插入到SQL当中。另外,还会对本文中的例子进行扩展,包括将图片的文件名传递会应用程序,通过传递一个特定的图像名来检索,并对这些应用程序进行转换以使用存储过程和代码分离页面。

  因为存储在SQL Server的二进制流不能够直接传递给图像空间,所以间接的传递包含该二进制流的网页。

  总结

  二进制数据可以存储在SQL Server,并通过一个网页应用程序进行查询。在本系列的下一篇文章中,我们将创建一个网页应用程序来把图像插入到SQL当中。另外,还会对本文中的例子进行扩展,包括将图片的文件名传递会应用程序,通过传递一个特定的图像名来检索,并对这些应用程序进行转换以使用存储过程和代码分离页面。

[此贴子已经被作者于2009-4-5 11:23:22编辑过]
ip地址已设置保密
2009-4-5 11:23:00
杨桥柳
帅哥哟,离线,有人找我吗?
双子座5-30
头衔:江南烟雨
等级:尊者
威望:4
文章:8236
积分:69186
魅力:31756
现金货币:113486
注册:2008年12月17日
3
 

发贴心情
内容提要 

  在本系列的前面的文章SQL Server:存储图像和BLOB文件(一)和SQL Server:存储图像和BLOB文件(二)中,对BLOB进行了定义,并阐明了在什么情况下将这些文件存储在SQL Server内部而不存在文件系统中。此外,还通过举例介绍了VARBINARIES的几种不同数据类型,包括本文要集中讨论了VARBINARY(MAX)数据类型。本文第一部分的代码例子将图像加载到数据库,然后通过使用aspx页面对该图像进行检索和显示。本文将创建一个基于网络的应用程序用来将图像插入到SQL Server里。另外,将对前面两篇文章的例子进行扩展和改进。

  SQL测试数据库

  我们先来创建一个测试数据库和表用来存储图像,T-SQL脚本如下:

  USEmaster;
  GO
  CREATEDATABASEBLOBTest3;
  GO
  USEBLOBTest3;
  GO
  CREATETABLEBLOBFromWeb
  (
  BLOBDatavarbinary(max)
  );
  GO

  以上脚本创建了一个包含一个表的数据库,该表只有一列。该测试列“BLOBData”以MAX为关键词,因此无论多大的二进制文件,它都可以存储。接下来,我们创建一个可以存储过程,网页可以使用该存储程序来上传图片:

  CREATEPROCEDUREWebUp
  (
  @FileDatavarbinary(max)
  )
  AS
  INSERTINTOBLOBFromWeb
  (BLOBData)
  VALUES
  (@FileData);

  该存储过程会将变量——图像“@FileData”传递到SQL Server。接下来的例子都将会使用存储过程而不再使用SQL语句了。使用存储过程的好处很多,例如可以增强安全性、防止SQL注入攻击、方便使用、提高运行性能等等。

  从网页将图像插入到SQL Server

  本例将使用Microsoft Visual Studio 2008来创建一个网页表单,该表单会要求终端用户浏览并上传文件到SQL Server。这个应用程序也可以在Visual Studio 2005中使用。首先,创建一个新网站和一个代码分离的aspx页面,如下图所示,拖动FileUpload和按钮控制到该表单上。

  切换到该页面的源视图,并按下文所示更改默认

标签:

  
  “enctype”指定了表单数据如何编码。切换回到设计视图,双击按钮创建OnClick事件,这会将该代码分离的页面调出来,如下显示: 

SQL Server:存储图像和BLOB文件(三)

  在该页面顶部,添加以下using语句:

  usingSystem.Data.Sql;
  usingSystem.Data.SqlClient;
  Andalsoastatementforthefilesystem:
  usingSystem.IO;

  添加如下代码到Button1_Click事件中:

  stringsConn=@"server=.;database=BLOBTest3;IntegratedSecurity=True";
  SqlConnectionobjConn=newSqlConnection(sConn);
  objConn.Open();
SqlCommandobjCmd=newSqlCommand("WebUp",objConn);
  objCmd.CommandType=CommandType.StoredProcedure;
  SqlParameterparamFileData=objCmd.Parameters.Add("@FileData",SqlDbType.VarBinary);
  paramFileData.Direction=ParameterDirection.Input;
  byte[]bImage=newbyte[FileUpload1.PostedFile.ContentLength];
  StreamobjStream=FileUpload1.PostedFile.InputStream;
  objStream.Read(bImage,0,FileUpload1.PostedFile.ContentLength);
  paramFileData.Value=bImage;
  objCmd.ExecuteNonQuery();
  objConn.Close();

  语句的第一行设置了与SQL Server的连接。“Integrated Security”表示使用Windows安全登录,而不是SQL ID登录。接下来打开到数据库的连接。启动该数据库之后,接下来的两行语句用来创建一个SQL指令对象:

  SqlCommandobjCmd=newSqlCommand("WebUp",objConn);
  objCmd.CommandType=CommandType.StoredProcedure;

  “WebUp”是之前创建的存储过程的名称。将该存储过程绑定到开放的数据库连接,然后会告诉SQL指令对象,“WebUp”是一个存储过程,而不是T-SQL文本语句。该存储过程要求传递一个单一的参数,也就是要插入的图像。参数创建如下面的语句。“paramFileData”名称可以取任何名称,没什么特别要注意的,不过对于Parameters.Add,“@FileData”必须和存储过程中的参数名称匹配。

  SqlParameter paramFileData = objCmd.Parameters.Add("@FileData", SqlDbType.VarBinary);

  有了参数以后,就可以指定上传方向了:

  paramFileData.Direction = ParameterDirection.Input;

  任何传递到SQL Server的数据都是Input的指令类型,输出的数据将是ParameterDirection.Output。

  我们设想的理想状态是,现在FileUpload控件应当将图像直接传递给存储过程参数,不过这是行不通的。相反,我们要创建一个可输入图像大小的字节数组:

  byte[] bImage = new byte[FileUpload1.PostedFile.ContentLength];

  紧接着,创建一个流对象指向图像内容:

  Stream objStream = FileUpload1.PostedFile.InputStream;

  最后,流将图像传递给上面的字节数组:

  objStream.Read(bImage, 0, FileUpload1.PostedFile.ContentLength);

  现在,图像数据就可以传递进入SQL参数,并运行了:

  paramFileData.Value=bImage;
  objCmd.ExecuteNonQuery();

  运行该应用程序

  在浏览器中查看该网页,点击浏览按钮。这时会出现一个如下所示的文件选择窗口:  

SQL Server:存储图像和BLOB文件(三) 浏览文件夹选择好文件后点击完成按钮,就会执行上面创建的SQL存储过程。在SQL Server内部查看运行结果,会显示有二进制数据,但不会显示数据的真实内容:  

SQL Server:存储图像和BLOB文件(三)

  因为SQL Server本身不带有BLOB浏览器,所以我们要自动动手制作一个类似于前一篇文章所示的浏览器,不同的是这个浏览器通过存储过程驱动的。

  浏览器

  创建一个简单的可以选择图像数据的存储过程,T-SQL代码如下:

  CREATEPROCEDUREBLOBViewer
  AS
  SELECTBLOBData
  FROMBLOBFromWeb

  接下来,制作一个代码分离的aspx网页。在代码分离页面添加SQL Server的使用语句:

  usingSystem.Data.Sql;
  usingSystem.Data.SqlClient;

  在Page_load的部分,使用下面的代码执行刚刚创建的存储过程:

  stringsConn=@"server=.;database=BLOBTest3;IntegratedSecurity=True";
  SqlConnectionobjConn=newSqlConnection(sConn);
  objConn.Open();
  SqlCommandobjCmd=newSqlCommand("BLOBViewer",objConn);
  objCmd.CommandType=CommandType.StoredProcedure;
  SqlDataReaderdr=objCmd.ExecuteReader();
  dr.Read();
  Response.BinaryWrite((byte[])dr["BLOBData"]);
  objConn.Close();

  这里的网页浏览器代码和前一篇文章中的代码很相似,不过把CommandType变成了Stored Procedure,而且SQLCommand的执行使用了该存储过程名而不是一串SQL字符串。

  总结

  SQL Server可以作为存储图像和BLOB数据的便携容器使用,不过处理二进制数据和处理ASCII有所不同:存储在SQL Server内部的数据并不像字符数据那样能看到它们是什么样子的;此外,在将数据发送到SQL Server之前,还需要对数据进行一些特殊处理,例如使用字节数组。不过总体而言,在SQL Server中使用和存储BLOB文件还是很有价值的。

  语句的第一行设置了与SQL Server的连接。“Integrated Security”表示使用Windows安全登录,而不是SQL ID登录。接下来打开到数据库的连接。启动该数据库之后,接下来的两行语句用来创建一个SQL指令对象:

  SqlCommandobjCmd=newSqlCommand("WebUp",objConn);
  objCmd.CommandType=CommandType.StoredProcedure;

  “WebUp”是之前创建的存储过程的名称。将该存储过程绑定到开放的数据库连接,然后会告诉SQL指令对象,“WebUp”是一个存储过程,而不是T-SQL文本语句。该存储过程要求传递一个单一的参数,也就是要插入的图像。参数创建如下面的语句。“paramFileData”名称可以取任何名称,没什么特别要注意的,不过对于Parameters.Add,“@FileData”必须和存储过程中的参数名称匹配。

  SqlParameter paramFileData = objCmd.Parameters.Add("@FileData", SqlDbType.VarBinary);

  有了参数以后,就可以指定上传方向了:

  paramFileData.Direction = ParameterDirection.Input;

  任何传递到SQL Server的数据都是Input的指令类型,输出的数据将是ParameterDirection.Output。

  我们设想的理想状态是,现在FileUpload控件应当将图像直接传递给存储过程参数,不过这是行不通的。相反,我们要创建一个可输入图像大小的字节数组:

  byte[] bImage = new byte[FileUpload1.PostedFile.ContentLength];

  紧接着,创建一个流对象指向图像内容:

  Stream objStream = FileUpload1.PostedFile.InputStream;

  最后,流将图像传递给上面的字节数组:

  objStream.Read(bImage, 0, FileUpload1.PostedFile.ContentLength);

  现在,图像数据就可以传递进入SQL参数,并运行了:

  paramFileData.Value=bImage;
  objCmd.ExecuteNonQuery();

  运行该应用程序

  在浏览器中查看该网页,点击浏览按钮。这时会出现一个如下所示的文件选择窗口:  

SQL Server:存储图像和BLOB文件(三) 浏览文件夹选择好文件后点击完成按钮,就会执行上面创建的SQL存储过程。在SQL Server内部查看运行结果,会显示有二进制数据,但不会显示数据的真实内容:  

SQL Server:存储图像和BLOB文件(三)

  因为SQL Server本身不带有BLOB浏览器,所以我们要自动动手制作一个类似于前一篇文章所示的浏览器,不同的是这个浏览器通过存储过程驱动的。

  浏览器

  创建一个简单的可以选择图像数据的存储过程,T-SQL代码如下:

  CREATEPROCEDUREBLOBViewer
  AS
  SELECTBLOBData
  FROMBLOBFromWeb

  接下来,制作一个代码分离的aspx网页。在代码分离页面添加SQL Server的使用语句:

  usingSystem.Data.Sql;
  usingSystem.Data.SqlClient;

  在Page_load的部分,使用下面的代码执行刚刚创建的存储过程:

  stringsConn=@"server=.;database=BLOBTest3;IntegratedSecurity=True";
  SqlConnectionobjConn=newSqlConnection(sConn);
  objConn.Open();
  SqlCommandobjCmd=newSqlCommand("BLOBViewer",objConn);
  objCmd.CommandType=CommandType.StoredProcedure;
  SqlDataReaderdr=objCmd.ExecuteReader();
  dr.Read();
  Response.BinaryWrite((byte[])dr["BLOBData"]);
  objConn.Close();

  这里的网页浏览器代码和前一篇文章中的代码很相似,不过把CommandType变成了Stored Procedure,而且SQLCommand的执行使用了该存储过程名而不是一串SQL字符串。

  总结

  SQL Server可以作为存储图像和BLOB数据的便携容器使用,不过处理二进制数据和处理ASCII有所不同:存储在SQL Server内部的数据并不像字符数据那样能看到它们是什么样子的;此外,在将数据发送到SQL Server之前,还需要对数据进行一些特殊处理,例如使用字节数组。不过总体而言,在SQL Server中使用和存储BLOB文件还是很有价值的。

ip地址已设置保密
2009-4-5 11:25:00
杨桥柳
帅哥哟,离线,有人找我吗?
双子座5-30
头衔:江南烟雨
等级:尊者
威望:4
文章:8236
积分:69186
魅力:31756
现金货币:113486
注册:2008年12月17日
4
 

发贴心情
BLOB文件(二进制大对象)是二进制数据,换而言之,就是非文本数据。像MP3、可执行文件、图片等都是BLOB文件。这些类型的文件通常是大型数据库项目的一个组成部分。问题也就随之而来了:要怎样存储这些文件呢?而将它们存到哪里呢?存在文件系统里还是放到SQL Server数据库内部呢?无论采用哪种存储方法,都有其各自的道理。笼统一点说来,如果文件比较小,就将它们存放在SQL Server数据库内部。而且,支持将二进制数据存储在SQL Server内部的另一个原因是有利于事务控制。例如,如果你在进行下一个处理步骤之前需要确认已经更新或删除了某张图片,那可以通过SQL Server内部控制这些过程。而另一方面,如果二进制文件很大,或者是视频流文件,那存储在Windows的文件系统中比存储在SQL Server内部对数据库的性能更有利。再者,文件系统对碎片的处理要优于SQL Server。

  在本系列的前三篇文章中,主要为大家介绍了如何将BLOB文件存储在SQL Server内部。第一篇文章SQL Server:存储图像和BLOB文件(一)简单介绍了BLOB的定义和VARCHAR的数据类型家族,并讨论了将BLOB插入到SQL Server的一些简单方法。第二篇文章SQL Server:存储图像和BLOB文件(二)介绍了如何利用Response.BinaryWrite将从数据库读出的图片显示到浏览器网页上。在第三篇文章SQL Server:存储图像和BLOB文件(三)中,通过创建ASPX页面来接受来自网页的图片并直接将其存储到SQL Server当中。本文将为大家介绍第二种存储BLOB文件的方法,也就是把BLOB文件存储到Windows文件系统当中,并利用SQL Server从一个网页对这些文件进行管理。

  文件系统实例

  首先,我们要构建一个可以用在前面的文章中所举例子的控件——文件上传(File Upload)控件。该控件可以嵌入到网页当中,并搜集文件信息,例如某测试图片的文件名、目录路径,最终将这些信息传递给SQL Server。具体操作就是,创建一个名为FileSystemIn.aspx的代码分离新页面,将四个控件拖拽到该页面上,包括一个文件上传控件、一个按钮控件(button)和两个标签(label),如下图所示:

图片点击可在新窗口打开查看

  为了便于解释,在例图上使用的是默认控件名,实际应用中可自行更改。














  在代码分离页面上,我们将搜集文件名和目录路径,并将它们分别显示到两个标签上。创建点击事件,并插入如下代码:

protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName.ToString()

);
Label2.Text = ystem.IO.Path.GetDirectoryName(FileUpload1.PostedFile.FileName.ToString());
}
   

  当点击button按钮,就会显示通过文件上传控件浏览上传的文件,如下图所示:

图片点击可在新窗口打开查看

  我们还可以通过一个存储过程将该数据传递给SQL Server,这样数据库就可以成为我们的图片管理器了。首先,传见一个文本数据库来保存上述文件信息,T-SQL脚本如下:

  USEmaster;
  GO
  CREATEDATABASEBLOBTest4;
  GO
  USEBLOBTest4;
  GO
  CREATETABLEFileInfo
  (
  TheNamevarchar(50),
  DirPathvarchar(50)
  );

  然后,我们创建一个存储过程,以便网页用来插入信息:

  CREATEPROCEDUREFileSystemIn
  (
  @TheNamevarchar(50),
  @DirPathvarchar(50)
  )
  AS
  INSERTINTOFileInfo
  (TheName,DirPath)
  VALUES
  (@TheName,@DirPath);

  接下来,用存储过程代码来替换代码分离页面代码。现在,文件信息就存储在SQL Server内部,而不是显示在标签上了。

  stringsTheName,sDirPath;
  sTheName=System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName.ToString());
  sDirPath=System.IO.Path.GetDirectoryName(FileUpload1.PostedFile.FileName.ToString());
  stringsConn=@"server=.;database=BLOBTest4;IntegratedSecurity=True";
  SqlConnectionobjConn=newSqlConnection(sConn);
  objConn.Open();
  SqlCommandobjCmd=newSqlCommand("FileSystemIn",objConn);
  objCmd.CommandType=CommandType.StoredProcedure;
  SqlParameterpTheName=objCmd.Parameters.Add("@TheName",SqlDbType.VarChar,50);
  pTheName.Direction=ParameterDirection.Input;
  pTheName.Value=sTheName;
  SqlParameterpDirPath=objCmd.Parameters.Add("DirPath",SqlDbType.VarChar,50);
  pDirPath.Direction=ParameterDirection.Input;
  pDirPath.Value=sDirPath;
  objCmd.ExecuteNonQuery();
  objConn.Close();

  测试该网页,对FileInfo表使用SELECT语句来选择一个对象;结果将返回如下图所示的行:

图片点击可在新窗口打开查看 请查阅本系列的第三篇文章,会有关于onclick存储过程代码的详细解释,在那篇文章中也使用了相同的SQL连接和指令对象。这里,可以通过创建一个网页来从SQL Server数据库获取路径信息以便查看图像。

  SQL Server 2008 的文件流数据类型(FILESTREAM)

  以上这些方法在实施的过程中还会出现一些问题。首先,如果不是通过网页应用程序而是通过其他方法删除或添加文件的话,SQL Server就无法察觉,因此不能做到和文件系统同步。第二个就是备份问题。实施上述方法后,我们不仅需要备份SQL Server,还需要备份文件存储的目录路径。此外,对于这些文件的安全问题,SQL Server也无法控制。

  SQL Server 2008提供了解决这些问题的方法,那就是采用新的FILESTREAM数据类型。FILESTREAM文件就和标准的MDF或LDF文件一样,是存放在Windows的NTFS分区中的,不过FILESTREAM文件是专门为存储二进制数据而设计的。用CREATEDATABASE命令来创建一个特殊的文件组,并将其标记为“流(stream)”。创建该数据库后,可以将表内的一个列指定为“VARBINARY(MAX) FILESTREAM”数据类型。想要从文件系统访问存储在FILESTREAM内的BLOB是不可行的。我们无法打开Windows文件浏览器并访问这些文件,这意味着其安全是由SQL Server数据库负责处理的。此外,可以对这些BLOB文件使用标准的插入、更新和删除指令进行操作。因此对于大型的BLOB文件或像视频流这样性能要求很高的BLOB文件,SQL Server现在就有了一个可行的办法来处理这种类型的文件了。

  总结

  SQL Server提供了多个方法来管理BLOB二进制数据文件,如SQL Server 2005中的VARBINARY (MAX),更老版本中的IMAGE数据类型、以及 SQL Server 2008中新的FILESTREAM选项。与标准的数据类型相比,要熟练运用这些数据类型需要稍微努把力了,不过使用的方法和使用的对象都还是比较简单易用的。需要留意,在上述的例子中并没有包括错误检查。实际应用当中,必须确保文件上传控件测试上传没有问题之后,再将数据传送到SQL Server数据库。

  当点击button按钮,就会显示通过文件上传控件浏览上传的文件,如下图所示:

图片点击可在新窗口打开查看

  我们还可以通过一个存储过程将该数据传递给SQL Server,这样数据库就可以成为我们的图片管理器了。首先,传见一个文本数据库来保存上述文件信息,T-SQL脚本如下:

  USEmaster;
  GO
  CREATEDATABASEBLOBTest4;
  GO
  USEBLOBTest4;
  GO
  CREATETABLEFileInfo
  (
  TheNamevarchar(50),
  DirPathvarchar(50)
  );

  然后,我们创建一个存储过程,以便网页用来插入信息:

  CREATEPROCEDUREFileSystemIn
  (
  @TheNamevarchar(50),
  @DirPathvarchar(50)
  )
  AS
  INSERTINTOFileInfo
  (TheName,DirPath)
  VALUES
  (@TheName,@DirPath);

  接下来,用存储过程代码来替换代码分离页面代码。现在,文件信息就存储在SQL Server内部,而不是显示在标签上了。

  stringsTheName,sDirPath;
  sTheName=System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName.ToString());
  sDirPath=System.IO.Path.GetDirectoryName(FileUpload1.PostedFile.FileName.ToString());
  stringsConn=@"server=.;database=BLOBTest4;IntegratedSecurity=True";
  SqlConnectionobjConn=newSqlConnection(sConn);
  objConn.Open();
  SqlCommandobjCmd=newSqlCommand("FileSystemIn",objConn);
  objCmd.CommandType=CommandType.StoredProcedure;
  SqlParameterpTheName=objCmd.Parameters.Add("@TheName",SqlDbType.VarChar,50);
  pTheName.Direction=ParameterDirection.Input;
  pTheName.Value=sTheName;
  SqlParameterpDirPath=objCmd.Parameters.Add("DirPath",SqlDbType.VarChar,50);
  pDirPath.Direction=ParameterDirection.Input;
  pDirPath.Value=sDirPath;
  objCmd.ExecuteNonQuery();
  objConn.Close();

  测试该网页,对FileInfo表使用SELECT语句来选择一个对象;结果将返回如下图所示的行:

图片点击可在新窗口打开查看 请查阅本系列的第三篇文章,会有关于onclick存储过程代码的详细解释,在那篇文章中也使用了相同的SQL连接和指令对象。这里,可以通过创建一个网页来从SQL Server数据库获取路径信息以便查看图像。

  SQL Server 2008 的文件流数据类型(FILESTREAM)

  以上这些方法在实施的过程中还会出现一些问题。首先,如果不是通过网页应用程序而是通过其他方法删除或添加文件的话,SQL Server就无法察觉,因此不能做到和文件系统同步。第二个就是备份问题。实施上述方法后,我们不仅需要备份SQL Server,还需要备份文件存储的目录路径。此外,对于这些文件的安全问题,SQL Server也无法控制。

  SQL Server 2008提供了解决这些问题的方法,那就是采用新的FILESTREAM数据类型。FILESTREAM文件就和标准的MDF或LDF文件一样,是存放在Windows的NTFS分区中的,不过FILESTREAM文件是专门为存储二进制数据而设计的。用CREATEDATABASE命令来创建一个特殊的文件组,并将其标记为“流(stream)”。创建该数据库后,可以将表内的一个列指定为“VARBINARY(MAX) FILESTREAM”数据类型。想要从文件系统访问存储在FILESTREAM内的BLOB是不可行的。我们无法打开Windows文件浏览器并访问这些文件,这意味着其安全是由SQL Server数据库负责处理的。此外,可以对这些BLOB文件使用标准的插入、更新和删除指令进行操作。因此对于大型的BLOB文件或像视频流这样性能要求很高的BLOB文件,SQL Server现在就有了一个可行的办法来处理这种类型的文件了。

  总结

  SQL Server提供了多个方法来管理BLOB二进制数据文件,如SQL Server 2005中的VARBINARY (MAX),更老版本中的IMAGE数据类型、以及 SQL Server 2008中新的FILESTREAM选项。与标准的数据类型相比,要熟练运用这些数据类型需要稍微努把力了,不过使用的方法和使用的对象都还是比较简单易用的。需要留意,在上述的例子中并没有包括错误检查。实际应用当中,必须确保文件上传控件测试上传没有问题之后,再将数据传送到SQL Server数据库。

  当点击button按钮,就会显示通过文件上传控件浏览上传的文件,如下图所示:

图片点击可在新窗口打开查看

  我们还可以通过一个存储过程将该数据传递给SQL Server,这样数据库就可以成为我们的图片管理器了。首先,传见一个文本数据库来保存上述文件信息,T-SQL脚本如下:

  USEmaster;
  GO
  CREATEDATABASEBLOBTest4;
  GO
  USEBLOBTest4;
  GO
  CREATETABLEFileInfo
  (
  TheNamevarchar(50),
  DirPathvarchar(50)
  );

  然后,我们创建一个存储过程,以便网页用来插入信息:

  CREATEPROCEDUREFileSystemIn
  (
  @TheNamevarchar(50),
  @DirPathvarchar(50)
  )
  AS
  INSERTINTOFileInfo
  (TheName,DirPath)
  VALUES
  (@TheName,@DirPath);

  接下来,用存储过程代码来替换代码分离页面代码。现在,文件信息就存储在SQL Server内部,而不是显示在标签上了。

  stringsTheName,sDirPath;
  sTheName=System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName.ToString());
  sDirPath=System.IO.Path.GetDirectoryName(FileUpload1.PostedFile.FileName.ToString());
  stringsConn=@"server=.;database=BLOBTest4;IntegratedSecurity=True";
  SqlConnectionobjConn=newSqlConnection(sConn);
  objConn.Open();
  SqlCommandobjCmd=newSqlCommand("FileSystemIn",objConn);
  objCmd.CommandType=CommandType.StoredProcedure;
  SqlParameterpTheName=objCmd.Parameters.Add("@TheName",SqlDbType.VarChar,50);
  pTheName.Direction=ParameterDirection.Input;
  pTheName.Value=sTheName;
  SqlParameterpDirPath=objCmd.Parameters.Add("DirPath",SqlDbType.VarChar,50);
  pDirPath.Direction=ParameterDirection.Input;
  pDirPath.Value=sDirPath;
  objCmd.ExecuteNonQuery();
  objConn.Close();

  测试该网页,对FileInfo表使用SELECT语句来选择一个对象;结果将返回如下图所示的行:

图片点击可在新窗口打开查看 请查阅本系列的第三篇文章,会有关于onclick存储过程代码的详细解释,在那篇文章中也使用了相同的SQL连接和指令对象。这里,可以通过创建一个网页来从SQL Server数据库获取路径信息以便查看图像。

  SQL Server 2008 的文件流数据类型(FILESTREAM)

  以上这些方法在实施的过程中还会出现一些问题。首先,如果不是通过网页应用程序而是通过其他方法删除或添加文件的话,SQL Server就无法察觉,因此不能做到和文件系统同步。第二个就是备份问题。实施上述方法后,我们不仅需要备份SQL Server,还需要备份文件存储的目录路径。此外,对于这些文件的安全问题,SQL Server也无法控制。

  SQL Server 2008提供了解决这些问题的方法,那就是采用新的FILESTREAM数据类型。FILESTREAM文件就和标准的MDF或LDF文件一样,是存放在Windows的NTFS分区中的,不过FILESTREAM文件是专门为存储二进制数据而设计的。用CREATEDATABASE命令来创建一个特殊的文件组,并将其标记为“流(stream)”。创建该数据库后,可以将表内的一个列指定为“VARBINARY(MAX) FILESTREAM”数据类型。想要从文件系统访问存储在FILESTREAM内的BLOB是不可行的。我们无法打开Windows文件浏览器并访问这些文件,这意味着其安全是由SQL Server数据库负责处理的。此外,可以对这些BLOB文件使用标准的插入、更新和删除指令进行操作。因此对于大型的BLOB文件或像视频流这样性能要求很高的BLOB文件,SQL Server现在就有了一个可行的办法来处理这种类型的文件了。

  总结

  SQL Server提供了多个方法来管理BLOB二进制数据文件,如SQL Server 2005中的VARBINARY (MAX),更老版本中的IMAGE数据类型、以及 SQL Server 2008中新的FILESTREAM选项。与标准的数据类型相比,要熟练运用这些数据类型需要稍微努把力了,不过使用的方法和使用的对象都还是比较简单易用的。需要留意,在上述的例子中并没有包括错误检查。实际应用当中,必须确保文件上传控件测试上传没有问题之后,再将数据传送到SQL Server数据库。

[此贴子已经被作者于2009-4-5 11:26:27编辑过]
ip地址已设置保密
2009-4-5 11:26:00
杨桥柳
帅哥哟,离线,有人找我吗?
双子座5-30
头衔:江南烟雨
等级:尊者
威望:4
文章:8236
积分:69186
魅力:31756
现金货币:113486
注册:2008年12月17日
5
 

发贴心情

SQL Server事务日志的几个常用操作

我们知道,SQL Server事务日志主要是用来记录所有事务对数据库所做的修改,如果系统出现故障,它将成为最新数据的唯一来源。日志的操作常有以下几个应用:

  一、事务日志文件LDF的丢失

  当我们不小删除或者LDF文件丢失的时候,数据库只剩下MDF文件,此时直接通过附加MDF是无法恢复数据库的,那我们怎么样才能恢复数据库呢?我们可以把SQL Server的日志文件分为两种形式:一类是无活动事务的日志,另一类是有活动事务的日志,我们分别根据两种情况来进行数据库恢复。

  1、无活动事务的日志恢复

  当文件并没有发生活动性的日志,我们就可以很容易的利用MDF文件就可以直接恢复数据库了,具体操作方法如下:

  1)数据库要是没有日志,就会处于置疑的状态,我们先可以通过企业管理器中在对应数据库中点击右键,然后在“所有任务”下选择“分离数据库”把数据库进行分离;

  2)利用MDF文件附加数据库生成新的日志文件,可用企业管理器中数据库点击右键选择“所有任务”下的“附加数据库”把数据库附加上。

  这样就可以直接恢复好数据库了,而如果数据库的日志文件中含有活动事务,利用此方法就不能恢复数据库,所以得使用下面的方法。

  2、有活动事务的日志恢复

  当日志发生了事务的记录,丢失的时候,我们采用如下的方法来实现:

  1)新建一个同名的数据库,如原数据库名为MYDB,然后停止SQL Server服务器,再把数据库主数据MDF文件移走,然后重新启动SQL Server服务器,新建一个同名的数据库MYDB,然后再停止SQL Server服务器,把移走的MDF文件再覆盖回来,然后再重新启动SQL Server服务器,在默认的情况下,系统表是不允许被修改的,我们需要运行以下语句才可以,在查询分析器中,选择Master数据库,然后执行:

  Sp_configure 'allow updates',1

  Reconfigure With Override

  接着运行以下语句,把Sysdatabases表中MYDB数据库的status属性设为‘37268’,把MYDB数据库设置为紧急模式。

  update sysdatabases set status=32768 where name=’MYDB’

  然后再把数据库MYDB设置为单用户模式,然后重启SQL Server服务器,并把数据库MYDB设为单用户模式

  Sp_dboption 'MYDB','single user', 'true'

  再运行以下语句,检查数据库MYDB

  DBCC CHECKDB(‘MYDB’)

  2)还原数据库的状态

  运行以下语句,就可以把数据库的状态还原:

  Update Sysdatabases Set status=28 Where name=’MYDB’

  Sp_Configure ’allow updates’,0

  Reconfigure With Override

  此时的数据库仍不能工作,还要进行以下的操作,才能恢复。

  3)利用DTS的导入导出向导,把数据库MYDB导入到一个新建数据库MYDBNEW中,然后新建一个数据库MYDBNEW,右击MYDBNEW,选择“所有任务”下的“导出数据”功能,打开导入向导,把表结构、数据视图和存储过程导入到MYDBNEW中,然后再用此功能把MYDBNEW库替换成原来的MYDB库即可。

  可以知道,恢复一个有活动事务的日志是麻烦多了,所以在数据库维护的时候,切不要小看事务日志。

  二、事务在不断增大的时候如何缩小日志

  当数据如在频繁修改或者删除的同时,事务的日志就会不断的增加,甚至超过了碰盘的大小,这时候就不能因此而直接删除了事务日志的LDF文件,否则可能会带来很大的麻烦。为了避免这种情况,我们需要有如下的操作:1) 尽量避免tempdb 日志与用户数据库日志放在同一磁盘上,tempdb 数据库和事务日志具有足够的空间来处理索引操作。不能在索引操作完成之前截断 tempdb 事务日志。

  2) 通过执行下列命令来缩小事务日志

  DBCC SHRINKDATABASE

  DBCC SHRINKFILE

  操作会立即尝试将物理日志文件收缩为所要求的大小。

  如果虚拟日志文件中的逻辑日志未超出 target_size 标记,则释放 target_size 标记之后的虚拟日志文件,并成功完成 DBCC 语句,不显示任何信息。

  如果虚拟日志中的逻辑日志超出了 target_size 标记,SQL Server Database Engine 将释放尽可能多的空间并显示一个信息性消息。该消息告诉您必须执行什么操作来从文件尾部的虚拟日志中删除逻辑日志。执行完该操作后,可以重新发出 DBCC 语句以释放剩余的空间。

  DBCC SHRINKFILE 语句还显示一个信息性消息,指出它不能释放所要求的全部空间,并告诉您可以执行 BACKUP LOG 语句来释放剩余的空间。

  三、事务日志的还原

  事务日志在还原的时候可以选择三种恢复模式:简单模式、完整模式和大容量日志模式。

  简单恢复模式

  此模式简略地记录大多数事务,所记录的信息只是为了确保在系统崩溃或还原数据备份之后数据库的一致性。

  由于旧的事务已提交,已不再需要其日志,因而日志将被截断。截断日志将删除备份和还原事务日志。但是,这种简化是有代价的,在灾难事件中有丢失数据的可能。没有日志备份,数据库只可恢复到最近的数据备份时间。如果您使用的是 SQL Server Enterprise Edition,需要考虑此问题。此外,该模式不支持还原单个数据页。

  完整恢复模式

  此模式完整地记录了所有的事务,并保留所有的事务日志记录,直到将它们备份。在 SQL Server Enterprise Edition 中,完整恢复模式能使数据库恢复到故障时间点。

  大容量日志恢复模式

  此模式简略地记录大多数大容量操作(例如,索引创建),完整地记录其他事务。

  大容量日志恢复提高大容量操作的性能,常用作完整恢复模式的补充。大容量日志恢复模式支持所有的恢复形式,但是有一些限制,备份包含大容量日志记录操作的日志时,需要访问数据库内的所有数据文件。如果数据文件不可访问,则无法备份最后的事务日志,而且该日志中所有已提交的操作都将丢失。

阅读(7509) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~