将 excel 文件存储在 SQL Server 中

本文关键字:SQL Server 存储 excel 文件 | 更新日期: 2023-09-27 18:33:55

我正在寻找适合这种情况的好解决方案:

  • 我有一个带有 SQL Server 2008 R2 后端的 asp.net 应用程序。
  • 我需要允许用户上传文件并保存以供以后检索。
  • 我还需要解析此文件以在数据库端进行查询。所以我需要这个文件中的数据作为数据表和来自sql的数据来合并结果。

所以这就是我想到的:

  1. 将excel文件存储在SQL Server中作为varbinary(max) - 这将允许以后通过.net非常容易地检索文件。
  2. 解析:一种方法是在用户上传文件时,使用OpenXML或某些第三方库将其解析为Datatable,并将其传递给将返回结果集的存储过程。

我不喜欢这种方法,因为这意味着我们将不得不将大量数据传递到数据库两次(第一次在传递整个文件时,第二次在传递数据集时。

关于如何更有效地做到这一点的任何建议?是否可以使用这样的东西从varbinary max读取数据:

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$]

但没有实际创建文件?

或者,也许可以不将整个文件传递给数据库,而是从数据表构造 excel 文件?

或者也许varbinary(max)不是最好的解决方案,最好使用不同的数据类型,如XML?

Excel文件非常简单。一个没有宏或公式的带样式的表。(但无法转换为CSV(文件大小为200-800kb。

将 excel 文件存储在 SQL Server 中

您从数据库构建 excel 文件的想法很有趣 - 这表明取回上传的相同文件并不重要,只需一个包含相同信息的文件。这是对的吗?

如果是这样,我会在服务器上上传时解析文件(我喜欢 ClosedXML for C# excel 工作(,以查询友好的形式将相关数据存储在您的数据库中,然后扔掉原始文件。当用户要求取回文件时,请为他们创建一个包含正确内容的新文件。

小心使用 XML 数据类型列 - 它们对您可以使用它们执行的操作有限制。

您可能需要查看 SQL 2008 r2 的 FILESTREAM 功能,以将文件存储在服务器中。这是一个概述和一篇很好的博客文章。我不确定您的文件类型或您需要从中获取什么,但您可以选择使用批量插入或正如您已经指出的那样 OPENDATASOURCE 或稍后执行进程,然后使用 ID 加载数据从 FILESTREAM 链接数据。

您可以使用 FileUpload 控件将文件上载到服务器,然后每次需要时都可以检索文件。

从那里,您可以使用 OleDbConnection 读取 excel 文件,将每个提取的记录添加到列表中,以逐个迭代,然后将它们插入数据库。

这是一个使用三个类的小示例:CConexion(处理OleDbConnection进程(,ExcelParser(读取提取的记录并将其插入到数据库中,以便您可以在需要时查询它们(和ExcelRecord,它表示ExcelFile的每个注册表上数据的容器。

当您的计算机上有MS Office Excel 2010时,将安装这些OleDb库。我已经测试了代码并且运行良好。

excel 文件在示例中称为 Hoja1.xlsx存储在 TestApp 根目录上名为"文件"的文件夹中,当您打开它时,有三条记录,每个记录有两个字段(A1,B1(,(A2,B2(,(A3,B3( 在文件的第一张纸上,也称为 Hoja1.xlsx

    ''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

让我知道这是否适合您。希望对您有所帮助。