日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
使用SQLServer2008的FILESTREAM特性管理文件

SQL Server的FILESTREAM(文件流)特性簡化了基于文件的數(shù)據(jù)(如圖像)和關(guān)系數(shù)據(jù)同步的過程。

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站制作、沈丘網(wǎng)絡(luò)推廣、微信小程序、沈丘網(wǎng)絡(luò)營銷、沈丘企業(yè)策劃、沈丘品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供沈丘建站搭建服務(wù),24小時服務(wù)熱線:028-86922220,官方網(wǎng)址:www.cdcxhl.com

幾乎所有的應(yīng)用程序都需要某種類型的數(shù)據(jù)集,至少在檢索某些數(shù)據(jù)和在用戶界面中顯示時要用到,通常,應(yīng)用程序會使用到結(jié)構(gòu)化數(shù)據(jù)和非結(jié)構(gòu)化數(shù)據(jù),這樣就引入了極大的挑戰(zhàn),你不得不在一個事務(wù)中創(chuàng)建、更新、刪除和讀取這些完全不同的數(shù)據(jù)類型,當(dāng)結(jié)構(gòu)化數(shù)據(jù)駐留在關(guān)系數(shù)據(jù)庫中而非結(jié)構(gòu)化數(shù)據(jù)卻存儲在文件系統(tǒng)中時,這個問題尤為嚴(yán)重。SQL Server 2008新的FILESTREAM(文件流)特性可以幫助解決這個問題,它讓你可以將非結(jié)構(gòu)化數(shù)據(jù)存儲在文件系統(tǒng)中,但仍然保持了事務(wù)的完整性,本文探討FILESTREAM(文件流)的特性和優(yōu)點,以及如何運用它幫助你對非結(jié)構(gòu)化數(shù)據(jù)進(jìn)行更好地控制。

非結(jié)構(gòu)化數(shù)據(jù)選項

在SQL Server 2005中,構(gòu)建一個既依賴于結(jié)構(gòu)化(關(guān)系)數(shù)據(jù)有依賴于非結(jié)構(gòu)化(無關(guān)系)數(shù)據(jù)時,你有兩個選擇:

在數(shù)據(jù)庫中存儲結(jié)構(gòu)化數(shù)據(jù),在一個專用的存儲中存儲非結(jié)構(gòu)化數(shù)據(jù),如文件系統(tǒng)和文件服務(wù)器,雖然這種方法成本合算,但它引入了額外的復(fù)雜度,因為你需要跨關(guān)系和非關(guān)系系統(tǒng)管理事務(wù)的完整性。

將結(jié)構(gòu)化數(shù)據(jù)和非結(jié)構(gòu)化數(shù)據(jù)都存儲在數(shù)據(jù)庫中,多年以來,數(shù)據(jù)庫一直都支持存儲非關(guān)系數(shù)據(jù),如二進(jìn)制大對象,或BLOB,SQL Server稱之為varbinary數(shù)據(jù)類型,雖然在數(shù)據(jù)庫中存儲這種數(shù)據(jù)是很方便的,但成本費用會更高,所需的磁盤空間更多,存儲和檢索時間更長,對應(yīng)用程序的整體性能也會有負(fù)面影響。

在SQL Server 2008中,新的FILESTREAM(文件流)特性和varbinary列配合,你可以在服務(wù)器的文件系統(tǒng)上存儲真實的數(shù)據(jù),但可以在數(shù)據(jù)庫上下文內(nèi)管理和訪問,這個特性讓SQL Server不僅可以維護(hù)好數(shù)據(jù)庫內(nèi)記錄的完整性,也能夠維護(hù)好數(shù)據(jù)庫記錄和外部文件之間的完整性。因為這個特性是在現(xiàn)有的varbinary(max)數(shù)據(jù)類型之上實現(xiàn)的,開發(fā)人員可以輕易地用上這個特性,不用對應(yīng)用程序的架構(gòu)進(jìn)行改動。

什么時候使用FILESTREAM(文件流)

在下列任一情景下你都可以考慮使用FILESTREAM(文件流):

當(dāng)你存儲平均大小不低于1MB的BLOB數(shù)據(jù)類型時。

當(dāng)你需要更快、只讀訪問來自應(yīng)用程序的數(shù)據(jù)時。

當(dāng)你想直接從應(yīng)用程序的中間層代碼訪問BLOB時。

當(dāng)你需要為單個數(shù)據(jù)庫事務(wù)在數(shù)據(jù)庫中存儲非關(guān)系數(shù)據(jù)和關(guān)系數(shù)據(jù)時。

啟用FILESTREAM(文件流)

默認(rèn)情況下,F(xiàn)ILESTREAM(文件流)特性是被禁用了的,因此在使用之前,你必須按照下面的步驟配置服務(wù)器和數(shù)據(jù)庫實例:

1、要啟用服務(wù)器實例上的FILESTREAM(文件流),打開SQL Server配置管理器,在SQL Server服務(wù)上點擊右鍵,然后點擊打開,你會看到一串服務(wù)器,在你想要啟用FILESTREAM(文件流)的SQL Server實例上點擊右鍵,從右鍵菜單中選擇“屬性”,切換到FILESTREAM(文件流)標(biāo)簽,檢查“為Transact-SQL訪問啟用FILESTREAM(文件流)”選項,參考圖1 ,你也可以在這個標(biāo)簽頁為文件I/O流訪問啟用FILESTREAM(文件流)。

圖1 啟用FILESTREAM(文件流)-在為數(shù)據(jù)庫實例配置使用FILESTREAM(文件流)訪問之前必須為想要的SQL Server實例啟用FILESTREAM(文件流)

2、要為數(shù)據(jù)庫實例啟用FILESTREAM(文件流),執(zhí)行系統(tǒng)存儲過程sp_configure,并設(shè)置filestream_access_level參數(shù)的值為2,如下:

EXEC sp_configure filestream_access_level, 2
   GO
   RECONFIGURE
   GO

filestream_access_level參數(shù)有效的值包括:

◆ 0 在該實例上禁用FILESTREAM(文件流),這是默認(rèn)值。

◆ 1 為Transact-SQL訪問啟用FILESTREAM(文件流)

◆ 2 為Transact-SQL和Win32流訪問啟用FILESTREAM(文件流)

完成服務(wù)器和數(shù)據(jù)庫實例配置后,接下來是創(chuàng)建存儲數(shù)據(jù)的真實數(shù)據(jù)庫,因為FILESTREAM(文件流)是專門為存儲在文件系統(tǒng)上的二進(jìn)制數(shù)據(jù)創(chuàng)建的,使用CREATE DATABASE語句時,專門創(chuàng)建一個FILEGROUP標(biāo)記為流:

CREATE DATABASE FILESTREAMExample
   ON
   PRIMARY (
       NAME = FILESTREAMExample_Primary,
       FILENAME =
        'c:\Projects\DevX\Data\FILESTREAMExample.mdf'),
   FILEGROUP FILESTREAMGroup CONTAINS  FILESTREAM (
       NAME = FILESTREAMExample_FileGroup,
       FILENAME = 'c:\Projects\DevX\Data\FILESTREAMExample')
   LOG ON ( NAME = FILESTREAMExample_Log,
       FILENAME = 
        'c:\Projects\DevX\Data\FILESTREAMExample.ldf')
   GO

接下來,創(chuàng)建一個表,將它的一個列指派為VARBINARY(MAX) FILESTREAM數(shù)據(jù)類型:

CREATE TABLE Product
   (
     ProductID INT  NOT NULL  PRIMARY KEY,
     Name VARCHAR(50) NOT NULL,
     Picture VARBINARY(MAX) FILESTREAM  NULL,
     RowGuid UNIQUEIDENTIFIER  NOT NULL  ROWGUIDCOL
     UNIQUE DEFAULT NEWID()
   )
   GO

前面的表定義指定Picture列為varbinary(max)類型,并啟用了FILESTREAM(文件流)屬性,注意:凡是有FILESTREAM(文件流)列的表必須要包括一個非空唯一性ROWGUID列。

所有存儲在Picture列中的二進(jìn)制數(shù)據(jù)都不能通過文件系統(tǒng)訪問,訪問這個二進(jìn)制數(shù)據(jù)的唯一方法是通過標(biāo)準(zhǔn)的CRUD (INSERT,UPDATE和 DELETE)SQL語句,下面的例子是向Product表中插入一行數(shù)據(jù):

INSERT INTO Product VALUES(1, 'Bicycle', 0x00, default)
   GO

插入的新行ProductID等于1,Name包括Bicycle,Picture列為NULL,RowGuid列包括一些默認(rèn)的GUID值,現(xiàn)在你可以在.NET程序中檢索這一行,當(dāng)然也可以覆蓋和擴(kuò)展它的內(nèi)容。

#p#

使用FILESTREAM(文件流)寫入數(shù)據(jù)

在這個例子中,假設(shè)用戶產(chǎn)生了一些輸入,要將這些輸入內(nèi)容轉(zhuǎn)換成字節(jié)數(shù)組,并將其存儲在Product表的Picture列中,接下來創(chuàng)建一個Visual C#視窗應(yīng)用程序,命名為FileStreamExample,在新項目的默認(rèn)表單上,添加一個按鈕,命名為btnWriteFile,一個名叫txtInput的文本輸入框(TextBox),一個命名為lstResults的列表框(ListBox),然后,在按鈕上雙擊創(chuàng)建一個click事件處理器,包括清單1中的代碼。

清單1 使用FILESTREAM存儲數(shù)據(jù)

private void btnWriteFile_Click(object sender, EventArgs e)
{
 string connectionString =   
  ConfigurationManager.ConnectionStrings
  ["fileStreamDB"].ConnectionString;
 using (SqlConnection connection = new 
  SqlConnection(connectionString))
 {
  connection.Open();
  SqlCommand command = new SqlCommand();
  command.Connection = connection;
  //Get the PathName of the File from the database
  command.CommandText = "SELECT Picture.PathName(), "   +   
   "GET_FILESTREAM_TRANSACTION_CONTEXT() FROM Product " +
   "WHERE ProductID = 1";
  SqlTransaction transaction = connection.BeginTransaction
   (IsolationLevel.ReadCommitted);
  command.Transaction = transaction;
  using (SqlDataReader reader = command.ExecuteReader())
  {
   while (reader.Read())
   {
    string path = reader.GetString(0);
    SqlFileStream stream = new SqlFileStream(path,
     (byte[])reader.GetValue(1), FileAccess.Write,
     FileOptions.SequentialScan, 0);
    string contents = txtInput.Text;
    stream.Write((System.Text.Encoding.ASCII.GetBytes(contents)), 
     0, contents.Length);
    stream.Close();
   }
  }
  transaction.Commit();
 }
 MessageBox.Show("File contents successfully written");
}

它從app.config使用ConfigurationManager.ConnectionStrings屬性檢索連接字符串:

string connectionString =  ConfigurationManager.ConnectionStrings
    ["fileStreamDB"].ConnectionString;


連接字符串存儲在app.config中,如下:

<?xml version="1.0" encoding="utf-8" ?>
   <configuration>
    <connectionStrings>
     <add name="fileStreamDB"  
      connectionString="server=localhost\SqlServer2008;
      database=FILESTREAMExample;integrated security=SSPI;
      persist security info=False;"/>
    </connectionStrings>
   </configuration>



接下來它打開一個到數(shù)據(jù)庫的連接,為SqlCommand對象分配屬性值,然后以ProductID=1為條件檢索Products表:

command.Connection = connection;
   //從數(shù)據(jù)庫獲取文件的路徑
   command.CommandText = "SELECT Picture.PathName(), "
    + "GET_FILESTREAM_TRANSACTION_CONTEXT() FROM Product "
    + "WHERE ProductID = 1";




這個SQL語句使用了新的函數(shù)GET_FILESTREAM_TRANSACTION_CONTEXT ()檢索當(dāng)前運行的會話事務(wù),你可以綁定FILESTREAM(文件流)文件系統(tǒng)操作到該事務(wù)上,但這個事務(wù)必須是已經(jīng)啟動了的,并且也不能被異常終止或提交,當(dāng)沒有明確啟動的事務(wù)可用的,它返回NULL值。

因此,下面的代碼調(diào)用SqlConnection.BeginTransaction()方法創(chuàng)建一個新的SqlTransaction對象,并將其分配給SqlCommand對象:

SqlTransaction transaction = 
     connection.BeginTransaction(IsolationLevel.ReadCommitted);
   command.Transaction = transaction;





至此,清單1啟動ExecuteReader()方法執(zhí)行SQL語句,執(zhí)行完查詢后,返回文件流的路徑,并向它分配一個本地變量:

string path = reader.GetString(0);




你需要一個流寫入到文件中,因此,接下來要創(chuàng)建一個SqlFileStream類的實例,提供路徑、事務(wù)上下文、文件訪問目錄、文件選項一覽表和分配大小:

SqlFileStream stream = new SqlFileStream(path,
     (byte[])reader.GetValue(1), FileAccess.Write,
     FileOptions.SequentialScan, 0);





SqlFileStream類是一個新類(SQL Server 2008中才引入的),它提供了以字節(jié)序列方式訪問FILESTREAM(文件流)列的方法,表1對SqlFileStream類暴露在外的屬性做了一個簡單的描述。

表1 SqlFileStream類屬性

接下來清單1開始檢索用戶的輸入,轉(zhuǎn)換成字節(jié)數(shù)組,然后寫入到文件流中:

string contents = txtInput.Text;             
   stream.Write((System.Text.Encoding.ASCII.GetBytes(contents)), 0,
     contents.Length);
   stream.Close();






最后,清單1調(diào)用SqlTransaction.Commit()方法提交事務(wù):

transaction.Commit();






以上就是往由數(shù)據(jù)庫管理的啟用了FILESTREAM(文件流)特性的文件的基本過程,既然已經(jīng)知道如何寫入FILESTREAM列,那從FILESTREAM列讀取就簡單了。

#p#

使用FILESTREAM讀取數(shù)據(jù)

在C#項目的默認(rèn)表單上,添加一個按鈕,命名為btnReadFile,在click事件中插入清單2中的代碼。

清單2 使用FILESTREAM讀取數(shù)據(jù)。這個click事件處理程序從數(shù)據(jù)庫讀取FILESTREAM列中的內(nèi)容。

private void btnReadFile_Click(object sender, EventArgs e)

{

 string connectionString =  ConfigurationManager.ConnectionStrings

  ["fileStreamDB"].ConnectionString;               

 using (SqlConnection connection = new

  SqlConnection(connectionString))

 {

  connection.Open();

  SqlCommand command = new SqlCommand();

  command.Connection = connection;

  //Get the PathName of the File from the database

  command.CommandText = "SELECT Picture.PathName(), "

   + "GET_FILESTREAM_TRANSACTION_CONTEXT() FROM Product "

   + "WHERE ProductID = 1";

  SqlTransaction transaction =

   connection.BeginTransaction(IsolationLevel.ReadCommitted);

  command.Transaction = transaction;

  using (SqlDataReader reader = command.ExecuteReader())

  {

   while (reader.Read())

   {                       

    string path = reader.GetString(0);

    SqlFileStream stream = new SqlFileStream(path,

     (byte[])reader.GetValue(1),FileAccess.Read,

     FileOptions.SequentialScan, 0);                       

    lstResults.Items.Clear();

    int length = (int) stream.Length;

    byte[] contents = new byte[length];

    stream.Read(contents,0,length);                    

    string results = System.Text.Encoding.ASCII.GetString

     (contents);

    lstResults.Items.Add(results);

    stream.Close();

   }

  }

  transaction.Commit();

 }

}       

為了簡單起見,我只討論與前面不同的代碼,當(dāng)你創(chuàng)建一個SqlFileStream時,你需要指出你打開的文件流:

SqlFileStream stream = new SqlFileStream(path,
        (byte[])reader.GetValue(1),FileAccess.Read,
        FileOptions.SequentialScan, 0);







接下來,讀取文件流的內(nèi)容,轉(zhuǎn)換成字節(jié)數(shù)組,再轉(zhuǎn)換成字符串,最后在列表框(ListBox)中顯示出來:

int length = (int) stream.Length;
       byte[] contents = new byte[length];
       stream.Read(contents,0,length);                    
       string results = System.Text.Encoding.ASCII.GetString
        (contents);
       lstResults.Items.Add(results);







當(dāng)你運行這個應(yīng)用程序時,你會看到一個類似于圖2的屏幕,當(dāng)你點擊“寫入文件”按鈕時,應(yīng)用程序把文本框(TextBox)中的內(nèi)容寫入到文件流中;當(dāng)你點擊“讀取文件”按鈕時,應(yīng)用程序從文件流讀取內(nèi)容,將其顯示在列表框(ListBox)中。

圖2 示例項目-通過使用SqlFileStream類讀取和寫入FILESTREAM列中的內(nèi)容

接下來的例子顯示如何擴(kuò)展現(xiàn)有數(shù)據(jù)庫中的文件流。

使用FILESTREAM追加數(shù)據(jù)

增加一個命令按鈕,命名為btnAppendFile,使用清單3中的代碼作為它的click事件處理程序代碼。

清單3 使用FILESTREAM追加數(shù)據(jù)

FILESTREAM. 

  private void btnAppendFile_Click(object sender, EventArgs e)

  {

   string connectionString =  

    ConfigurationManager.ConnectionStrings

    ["fileStreamDB"].ConnectionString;                          

   using (SqlConnection connection = new

    SqlConnection(connectionString))

   {

    connection.Open();

    SqlCommand command = new SqlCommand();

    command.Connection = connection;

    //Get the PathName of the File from the database

    command.CommandText = "SELECT Picture.PathName(), "

     + "GET_FILESTREAM_TRANSACTION_CONTEXT() FROM Product "

     + "WHERE ProductID = 1";

    SqlTransaction transaction =

     connection.BeginTransaction(IsolationLevel.ReadCommitted);

    command.Transaction = transaction;

    using (SqlDataReader reader = command.ExecuteReader())

    {

     while (reader.Read())

     {

      string path = reader.GetString(0);                       

      SqlFileStream stream = new SqlFileStream(path,

       (byte[])reader.GetValue(1), FileAccess.ReadWrite,

       FileOptions.SequentialScan, 0);

      stream.Seek(0, SeekOrigin.End);

      string contents = txtInput.Text;

      stream.Write((System.Text.Encoding.ASCII.GetBytes

       (contents)), 0, contents.Length);                       

      stream.Close();

     }

    }

    transaction.Commit();

   }

   MessageBox.Show("File contents successfully appended");

  }

這次當(dāng)你實例化SqlFileStream對象時,將文件訪問權(quán)設(shè)為ReadWrite,因此你可以讀取和寫入文件流。

SqlFileStream stream = new SqlFileStream(path,
      (byte[])reader.GetValue(1), FileAccess.ReadWrite,
      FileOptions.SequentialScan, 0);








然后移動文件流的指針到文件末尾,這樣你就可以追加數(shù)據(jù)了:

stream.Seek(0, SeekOrigin.End);








接下來使用SqlFileStream.Write()方法將用戶輸入的內(nèi)容寫入到文件流中:

stream.Write((System.Text.Encoding.ASCII.GetBytes
      (contents)), 0, contents.Length);   








最后調(diào)用SqlTransaction.Commit()方法提交事務(wù)。

FILESTREAM的優(yōu)點

這就是全部過程,現(xiàn)在你可以讀取、寫入和追加數(shù)據(jù)到數(shù)據(jù)庫管理的文件中了,雖然這個過程可能比使用文件或在BLOB中存儲數(shù)據(jù)更復(fù)雜一些,你會發(fā)現(xiàn)使用數(shù)據(jù)庫來管理文件由許多好處。

◆ 使用單個數(shù)據(jù)存儲就可以同時訪問非關(guān)系和關(guān)系數(shù)據(jù)。

◆ 在數(shù)據(jù)庫備份和還原期間SQL Server自動包括非關(guān)系數(shù)據(jù)(BLOB)。

◆ 沒有文件大小限制,varbinary(max)數(shù)據(jù)類型最大不能超過2GB,唯一受限的就是NTFS文件系統(tǒng)上的可用空間。

◆ 你可以在單個事務(wù)中同時插入、更新和刪除關(guān)系數(shù)據(jù)和非關(guān)系數(shù)據(jù)。

◆ 使用FILESTREAM效率更高,因為SQL Server不再使用緩沖區(qū)內(nèi)存操作非關(guān)系數(shù)據(jù)(BLOB)。

◆ 你可以使用ADO.NET在中間層代碼直接訪問非關(guān)系數(shù)據(jù),不用再求值于獨立的API了。

◆ 依賴于文件大小,NTFS文件系統(tǒng)可以比SQL Server更快地保存和檢索大型BLOB。

本文向你展示了如何實現(xiàn)新的FILESTREAM特性,正如你所看到的,當(dāng)你想在一個事務(wù)中同時存儲關(guān)系數(shù)據(jù)和非關(guān)系數(shù)據(jù)時,F(xiàn)ILESTREAM提供了一個易于使用的事務(wù)編程模型。

原文:Managing Files with SQL Server 2008's FILESTREAM Feature        

作者:Thiru Thangarathinam

【獨家譯稿,合作站點轉(zhuǎn)載請注明原文譯者和出處為.com】

【編輯推薦】

  1. SQL Server 2008 的恢復(fù)和備份模式
  2. SQL Server 2008新特性——FILESTREAM
  3. 視頻教程下載:SQL Server 2008 的安全性改進(jìn)

本文題目:使用SQLServer2008的FILESTREAM特性管理文件
轉(zhuǎn)載注明:http://m.5511xx.com/article/cdeogih.html