2012-05-12 26 views
0

SQL Serverでファイルをエクセル:店は、私は、このシナリオに適したソリューションを探しています

  • 私は、SQL Server 2008 R2のバックエンドとのasp.netアプリケーションを持っています。
  • ファイルをアップロードして後で取得できるように保存する必要があります。
  • また、私はこのファイルをdb側のクエリの目的で解析する必要があります。ですから、私はこのファイルのデータとdatatableとSQLの結果の両方を組み合わせる必要があります。

だからここに私が考えたものだ:

  1. Storeはvarbinary(max)としてSQL Serverでファイルをエクセル - これは.NETかなり簡単通過後のファイルを取得することができます。
  2. 解析:ユーザーがファイルをアップロードするときに行う方法の1つは、openxmlやサードパーティのライブラリを解析してデータテーブルにし、結果セットを返すストアドプロシージャに渡すことです。

データセットを渡すとき、それは我々が全体のファイルを渡すときにまず(データベースへの2回の大量のデータを渡す必要があることを意味し、そして第二ので、私は、このアプローチは好きではありません。

??これより効率的に行う方法について

任意の提案は、それが可能このようなものを使用してvarbinary型の最大のデータを読むことです:

SELECT * 
FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0', 
        'Data Source=D:\TestJET.xls; 
        Extended Properties=''Excel 12.0;HDR=NO;IMEX=1;ImportMixedTypes=Text''')...[Sheet1$] 

が、実際にファイルを作成せずに

をそれともそれがありますDBにファイル全体を渡すことはできませんが、データテーブルからファイルを取り戻すことは可能ですか?

多分varbinary(max)はXMLのような異なるデータ型を使用するのに最適なソリューションではありませんか?

Excelファイルはかなりシンプルです。マクロや数式を持たない1つのスタイル付きテーブル。 (ただし、CSVに変換することはできません)ファイルサイズは200〜800kbです。

+0

エクセルファイルのデータを構造化できますか?どのようなテーブルですか? –

+0

Excelファイルを共有ドライブに残して、単にパス名を保存することはできますか?データベースに必要な場合は、すぐにデータをロードしてから、オフ時間にExcelロードをバッチすることができますか? –

答えて

0

SQL 2008 r2のFILESTREAM機能を調べて、ファイルをサーバーに格納することができます。ここにはoverviewといい、blog postがあります。あなたがファイルタイプを知っているかどうかわからないのですが、バルクインサートを使用するオプションがあるか、OPENDATASOURCEを既に指摘していたり​​、後でFILESTREAMのIDを使用してデータをロードしたりデータ。

0

FileUploadコントロールを使用してファイルをサーバーにアップロードすると、必要なたびにファイルを取得できます。

OleDbConnectionを使用してExcelファイルを読み込んで、取得した各レコードをリストに追加して、1つずつ繰り返してデータベースに挿入することができます。

これは、CConexion(OleDbConnectionプロセスを処理する)、ExcelParser(フェッチしたレコードをデータベースに読み込んで読み込んで、必要に応じてクエリを実行できるようにする)、およびデータのコンテナを表すExcelRecord ExcelFileの各レジストリに保存します。

これらのOleDbライブラリは、コンピュータにMS Office Excel 2010をインストールするとインストールされます。私はコードをテストし、うまく動作します。

例では、excelファイルはHoja1.xlsxと呼ばれ、TestAppのルートにあるFilesというフォルダに格納されています。開いたときに、(A1、B1)、

''CConexion Class: 

    Imports System.Data.SqlClient 
    Imports System.Data.OleDb 
    Imports System.Data 

    Public Class CConexion 

    #Region "Private Variables" 

     Dim sOleDbConnectionString As String = String.Empty 
     Dim conexionOleDb As New OleDbConnection() 

    #End Region 

    #Region "Con_Ole" 

     Public Interface IConexionOleDb 

      Property retConexionOleDb() As OleDbConnection 
      Sub retOpenOleDb() 
      Sub retCloseOleDb() 

     End Interface 

     Public Property retConexionOleDb() As OleDbConnection 

      Get 
       Return conexionOleDb 
      End Get 
      Set(ByVal value As OleDbConnection) 

      End Set 

     End Property 

     Public Sub retOpenOleDb() 

      If Not conexionOleDb.State = System.Data.ConnectionState.Open Then 
       conexionOleDb.Open() 
      End If 

     End Sub 

     Public Sub retCloseOleDb() 

      If Not conexionOleDb.State = ConnectionState.Closed Then 
       conexionOleDb.Close() 
      End If 

     End Sub 

    #End Region 

    #Region "Constructors" 

     Public Sub New() 

     End Sub 

     Public Sub New(ByVal rutaOleDb As String) 

      sOleDbConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" _ 
                 & "Data Source=" & rutaOleDb _ 
                 & ";" & "Extended Properties=Excel 12.0;" 
      conexionOleDb.ConnectionString = sOleDbConnectionString 

     End Sub 

    #End Region 

    End Class 

    ''ExcelRecord Class: 

    Public Class ExcelRecord 

     Private _RId As Short = 0 
     Public Property RId() As Short 
      Get 
       Return _RId 
      End Get 
      Set(ByVal value As Short) 
       _RId = value 
      End Set 
     End Property 

     Private _RText As String = String.Empty 
     Public Property RText() As String 
      Get 
       Return _RText 
      End Get 
      Set(ByVal value As String) 
       _RText = value 
      End Set 
     End Property 

     Public Sub New() 

     End Sub 

     Public Sub New(ByVal Rid As Short, ByVal RText As String) 
      Me.RId = Rid 
      Me.RText = RText 
     End Sub 

    End Class 

    ''ExcelParser Class: 

    Imports System.Data.OleDb 
    Imports System.Collections.Generic 

    Public Class ExcelParser 

     Private Function InsertRecords(ByVal objExcelRecords As List(Of ExcelRecord)) As Boolean 
     ''Your code for insertion here 
      Return True 
     End Function 

     Public Function ReadExcel(ByVal filePath As String) As Short 

      Dim cn As New CConexion(filePath) 
      Dim dr As OleDbDataReader 
      Dim OperationState As Boolean = False 
      Dim objExcelRecords As New List(Of ExcelRecord) 

      Try 

       Dim cmd As New OleDbCommand("Select * from [Hoja1$]", cn.retConexionOleDb) 

       cn.retOpenOleDb() 
       dr = cmd.ExecuteReader 

       While dr.Read  

        Dim objExcelRecord As New ExcelRecord(CShort(dr(0)), CStr(dr(1))) 
        objExcelRecords.Add(objExcelRecord) 

       End While 

       OperationState = InsertRecords(objExcelRecords) 
       CType(dr, IDisposable).Dispose() 

      Catch ex As Exception 

      Finally 

       cn.retCloseOleDb() 
       cn.retConexionOleDb.Dispose() 

      End Try 

      Return OperationState 

     End Function 

    End Class 


''Test Page ExcelReader.aspx.vb 
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 

     If Not Page.IsPostBack Then 

      Dim filePath As String = Server.MapPath("~\Files\Hoja1.xlsx") 
      Dim objExcelParser As New ExcelParser() 

      If objExcelParser.ReadExcel(filePath) Then 
       Response.Write("Read!") 
      Else 
       Response.Write("No Read!") 
      End If 

     End If 

    End Sub 

Hoja1.xlsx

とも呼ばれ、ファイルの最初のシートのA2、B2)、(A3、B3)は、これがあなたのために働くなら、私に教えてください。それが役に立てば幸い。

1

DBからExcelファイルを構築するあなたのアイデアは面白いです - これは、それがアップロードされた同じファイルバック、同じ情報が含まれているだけのものを取得することが重要ではないことを示唆しています。あれは正しいですか?

もしそうなら、私はサーバー上でアップロード時にファイルを解析します(私はClosedXMLがC#excelの仕事のために好きです)。データベースにクエリに適した形式で関連データを格納して元のファイルを破棄します。ユーザーがファイルを尋ねると、正しい内容で新しいファイルを作成します。

XMLデータ型の列には注意してください。これらの列でできることはrestrictionsです。

関連する問題