2016-09-29 31 views
0

何か方法はありますか?varbinaryとしてSQL Serverに保存された関連プログラムを含むファイル(.doc、.xls、.pdfなど)を開きますか?varbinaryとしてSQL Serverに保存された関連プログラムを含むファイル(.doc、.xls、.pdfなど)を開きますか?

サーバーにデータベースを作成します。

create database DEV 
GO 
USE DEV 
GO 
create Table FileWarehouse 
(
Id int identity (1,1), 
FileType Nvarchar (50), 
StoredFile Varbinary (MAX) 
) 

私は表示されているようにデータベースにファイルを保存しています。

insert into FileWarehouse 
select 'docx' as FileType,* 
from OPENROWSET (BULK 'C:\SQLDOC\WILLBESAVEDINSERVER.docx', SINGLE_BLOB) 
AS X 

サーバーからファイルを取得し、表示されているとおりにフォルダに保存できます。

DECLARE 
@SQLIMG VARCHAR (MAX), 
@File VARBINARY (MAX), 
@OutputPath VARCHAR (MAX), 
@ObjectToken INT 

Select @File = StoredFile FROM FileWarehouse where FileType ='docx' -- or use id 
SET @OutputPath = 'C:\SQLDOC\OUTPUT\output_word_fromServer.docx' 
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT 
EXEC sp_OASetProperty @ObjectToken, 'Type',1 
EXEC sp_OAMethod @ObjectToken, 'Open' 
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @File 
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @OutputPath,2 
EXEC sp_OAMethod @ObjectToken, 'Close' 
EXEC sp_OADestroy @ObjectToken 
GO 

ただし、データベースから直接ファイルを開くことはできません。以下のコードを使用する。

private void btnOpenDocument_Click(object sender, EventArgs e) 
    { 
     int id = (int)dataGridView1.CurrentRow.Cells["ID"].Value; 


     SqlDataAdapter adp = new SqlDataAdapter(); 
     adp.SelectCommand = new SqlCommand("GetDocument"); 
     adp.SelectCommand.CommandType = CommandType.StoredProcedure; 
     adp.SelectCommand.Connection = ResimGaleri.ORM.Tools.Baglanti; 
     adp.SelectCommand.Parameters.Add("@ID", SqlDbType.Int).Value = sd.ID; 

     // add here extension that depends on your file type 
     string fileName = Path.GetRandomFileName() + ".txt"; 

     using (SqlConnection conn = ResimGaleri.ORM.Tools.Baglanti) 
     { 
      ResimGaleri.ORM.Tools.Baglanti.Open(); 
      using (SqlCommand cmd = adp.SelectCommand) 
      { 
       // you have to distinguish here which document, I assume that there is an `id` column 


       using (SqlDataReader dr = cmd.ExecuteReader()) 
       { 
        while (dr.Read()) 
        { 
         int size = 1024 * 1024; 
         byte[] buffer = new byte[size]; 
         int readBytes = 0; 
         int index = 0; 

         using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) 
         { 
          while ((readBytes = (int)dr.GetBytes(0, index, buffer, 0, size)) > 0) 
          { 

           fs.Write(buffer, 0, readBytes); 
           index += readBytes; 

          } 


         } 

        } 



       } 

      } 
     } 

     // open your file, the proper application will be executed because of proper file extension 
     ResimGaleri.ORM.Tools.Baglanti.Close(); 
     Process prc = new Process(); 
     prc.StartInfo.FileName = fileName; 
     prc.Start(); 

    } 
} 
+3

ので、私はあなたのデータベースとデータベース・サーバー上で実行、SQLサーバーを使用するよりも、この列にウイルスを挿入することができるように。私はSQLサーバーがこれを許可するかどうかわからないが、私は望んでいない – GuidoG

+0

あなたはどのようにウイルスを挿入することができますか?面白い。 –

+0

私はこのテーブルを埋めることができるいくつかのクライアントがあると思いますか? – GuidoG

答えて

0

あなたのコードで見られる問題は、ファイル「someRandomName」.txtを保存することです。

Process.Startを呼び出すと、メモ帳(またはtxtファイルの既定のプログラム)が起動します。

元のファイル名(または少なくとも私が間違っていない場合は元の拡張子)を保存する必要がありますので、(一時的な)ファイル "someRandomName" .OriginalExtension

string fileName = Path.Combine(Path.GetRandomFileName(), dr.GetString("FileType"); 

@GuidoGが言うように、DBに保存されているすべてのファイルが安全であることを確認してください!

+0

拡張子とファイル名を別のテーブルにも追加しました。 –

+0

あなたの(一時的な)ファイルを保存するためにそれを使用してください! –

+0

一時ファイルが作成されましたが、何とか開いていません。 –

0

確かに、ファイルを一時的な場所に保存しておきます。 ファイルを開き、オプションをSystem.Diagnosticsにします。

Process.Start(fileName); 

それとも、あなたがより多くのオプションのためProcessStartInfoを使用することができます:

ProcessStartInfo processInfo = new ProcessStartInfo(fileName); 
processInfo.WindowStyle = ProcessWindowStyle.Maximized; 
Process.Start(processInfo); 
+0

一時ファイルが作成されましたが、何とか開いていません。 –

+0

メッセージがありますか?例外?手動で開くことはできますか? – Jacob

+0

残念ながら、私はマニュアルでそれを開くことはできません。 –

関連する問題