【问题标题】:Fill SQL database from a CSV File从 CSV 文件填充 SQL 数据库
【发布时间】:2017-04-17 17:44:09
【问题描述】:

我需要使用带有 SSIS 的 CSV 文件创建数据库。 CSV 文件包括四列:

我需要使用该表的信息来填充我在下面的 SQL 中创建的三个表。

我意识到我需要使用 Employee 表的一列 EmployeeNumber 和 Group 表 GroupID 来填充 EmployeeGroup 表。为此,我认为我需要一个 Join Merge 表,但是我在 SSIS 中创建了数据流任务,结果是一样的,没有显示数据。

中间的表是用来关联其他表的。

我在 SSIS 中创建了包,并填充了 Employee 和 Group 表,但 EmployeeGroup 表没有。 EmployeeGroup 只会显示没有数据的 EmployeeNumber 和 Group ID 列。

我是使用 SSIS 的新手,我真的不知道还能做什么。非常感谢您的帮助。

【问题讨论】:

  • 您是否尝试过使用一个数据流来完成所有这些操作?您可能需要几个。
  • 在我看来,您需要先填充 EmployeeGroup 表,然后 - 在另一个数据流中,在第一个数据流之后运行 - 从在您的初始数据源和您的 Group 表之间连接。
  • 我建议先将您的文件加载到临时表中,然后查询临时表以插入到您的其他表中。

标签: sql-server csv ssis etl ssis-2012


【解决方案1】:

由于您已经知道如何导入 csv 并提取两个表(Employee 和 Group),我建议您以相同的方式填充 EmployeeGroup。并停止使用 group_id。如果你这样做,你会得到如下的 sql 语句:

select [Employee Number], [Employee Name], LoginName from Employee
select [Group Name] from Employee
select distinct [Employee Number], [Group Name] from Employee

您很可能已经有类似的语句适用于 Employee 和 Group。在此选项中,您可以使其以相同的方式工作,而无需使用 Join Merge。这是一个有用的选项,但显然该组件的某个地方出了问题。

【讨论】:

    【解决方案2】:

    我认为最简单的解决方案是将 csv 导入平面临时表,然后使用一些 insert into...select 语句填充目标表。 假设你知道如何导入到平面表中,剩下的就很简单了:

    INSERT INTO Employee (EmployeeNumber, EmployeeName, LoginName)
    SELECT DISTINCT EmployeeNumber, EmployeeName, LoginName
    FROM Stage
    
    INSERT INTO [Group] (GroupName)
    SELECT DISTINCT GroupName 
    FROM Stage
    
    INSERT INTO EmployeeGroup(EmployeeNumber, GroupId)
    SELECT DISTINCT EmployeeNumber, GroupId
    FROM Stage s
    INNER JOIN [Group] g ON s.GroupName = g.GroupName
    

    You can see a live demo on rextester.

    【讨论】:

      【解决方案3】:

      概述

      1. 使用 SSIS 的解决方案
        • 使用 3 个数据流任务
        • 使用 2 个数据流任务
      2. 使用 T-SQL 的解决方案
        • 使用 Microsoft.Ace.OLEDB
        • 使用 Microsoft 文本驱动程序
      3. 使用 PowerShell 的解决方案

      第一个解决方案 - SSIS

      使用 3 个数据流任务

      这可以仅使用 2 个数据流任务来完成,但根据问题 I am new using SSIS, and I really do not know what else to do 中提到的 OP,我将提供最简单的解决方案,即 3 个数据流任务,以避免使用更多组件,如 MultiCast .

      解决方案概述

      因为要构建关系数据库并从 csv 中提取关系,所以必须读取 csv 3 次-将其视为 3 个单独的文件 -

      首先你必须导入员工和组数据,然后你必须导入它们之间的关系表。

      每个导入步骤都可以在单独的数据流任务中完成

      详细解决方案

      1. 添加平面文件连接管理器(Csv 文件)
      2. 添加一个 OLEDB 连接管理器(SQL 目标)
      3. 添加 3 个DataFlow 任务,如下图所示

      第一个数据流任务

      1. 添加一个平面文件源、一个脚本组件OLEDB目标,如下图所示

      1. 脚本组件中选择组名列作为输入

      1. 选择输出缓冲区并将SynchronousInputID Property更改为None并添加一个输出列OutGroupname,类型为DT_STR

      1. 脚本部分写下以下代码:

         Imports System.Collections.Generic
        
         Private m_List As New List(Of String)
         Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
        
        If Not Row.GroupName_IsNull AndAlso
                Not String.IsNullOrEmpty(Row.GroupName.Trim) Then
        
            If Not m_List.Contains(Row.GroupName.Trim) Then
        
                m_List.Add(Row.GroupName.Trim)
        
                CreateOutputRows(Row.GroupName.Trim)
        
            End If
        
        
        End If
        End Sub
        
        Public Sub CreateOutputRows(ByVal strValue As String)
        
        
        Output0Buffer.AddRow()
        Output0Buffer.OutGroupName = strValue
        End Sub
        
      2. OLEDB 目的地 映射 OutGroupNameGroupName

      第二个数据流任务:导入员工数据

      • Groupname 列重复相同的步骤:唯一的区别是您必须选择 EmployeeIDEmployee NameLoginName 列作为 脚本组件中的输入并在比较中使用ID 列而不是Groupname

      第三个数据流任务:导入Employees_Group数据

      1. 您必须添加 平面文件源查找转换OLEDB 目标

      1. LookUp Transformation 组件中选择 Groups Table 作为 Lookup table

      2. 映射GroupName 列并获取Group ID 作为输出

      1. 错误输出配置中选择Ignore Failure

      2. Oledb Destination 映射列如下

      注意:GroupID 必须是一个 Identity(在 sql server 中设置)

      使用 2 个数据流任务

      您必须执行与 3 个数据流任务解决方案相同的步骤,但不要将 2 个数据流任务添加到 GroupEmployee,只需添加一个数据流任务,然后在 @987654364 之后@ 添加一个MultiCast 组件来复制流程。然后对于第一个流使用与Employee 数据流任务中相同的Script ComponentOLEDB Destination,对于第二个流使用与Group 相关的Script ComponentOLEDB Destination


      第二个解决方案 - 使用 TSQL

      通过 T-SQL 命令将平面文件导入 SQL 的方法有很多

      使用 Microsoft ACE OLEDB 提供程序的 OPENROWSET

      假设安装的 Microsoft ACE OLEDB 版本为Microsoft.ACE.OLEDB.12.0,csv 文件位置为C:\abc.csv

      1. 首先将数据导入员工和组表

        INSERT INTO [GROUP]
            ([Group Name])
        SELECT 
            [Group Name] 
        FROM 
            OPENROWSET
                (
                    'Microsoft.ACE.OLEDB.12.0','Text;Database=C:\;IMEX=1;','SELECT * FROM abc.csv'
                ) t
        
        
        INSERT INTO [Employee]
            ([Employee Number],[Employee Name],[LoginName])
        SELECT 
            [Employee Number],[Employee Name],[LoginName] 
        FROM 
            OPENROWSET
                (
                    'Microsoft.ACE.OLEDB.12.0','Text;Database=C:\;IMEX=1;','SELECT * FROM abc.csv'
                ) t
        
      2. 导入 Employee_Group 数据

        INSERT INTO [EmployeeGroup]
            ([Employee Number],[GroupID])
        SELECT 
            t1.[Employee Number],t2.[GroupID]
        FROM 
            OPENROWSET
                (
                    'Microsoft.ACE.OLEDB.12.0','Text;Database=C:\;IMEX=1;','SELECT * FROM abc.csv'
                ) t1 INNER JOIN GROUP t2 ON t1.[Group Name] = T2.[Group Name]
        

      带有 Microsoft 文本驱动程序的 OPENROWSET

      1. 首先将数据导入员工和组表

        INSERT INTO [GROUP]
            ([Group Name])
        SELECT 
            [Group Name] 
        FROM 
            OPENROWSET
                (
                    'MSDASQL',
                    'Driver={Microsoft Text Driver (*.txt; *.csv)};
                    DefaultDir=C:\;',
                    'SELECT * FROM abc.csv'
                ) t
        
        
        INSERT INTO [Employee]
            ([Employee Number],[Employee Name],[LoginName])
        SELECT 
            [Employee Number],[Employee Name],[LoginName] 
        FROM 
            OPENROWSET
                (
                    'MSDASQL',
                    'Driver={Microsoft Text Driver (*.txt; *.csv)};
                    DefaultDir=C:\;',
                    'SELECT * FROM abc.csv'
                ) t
        
      2. 导入 Employee_Group 数据

        INSERT INTO [EmployeeGroup]
            ([Employee Number],[GroupID])
        SELECT 
            t1.[Employee Number],t2.[GroupID]
        FROM 
            OPENROWSET
                (
                    'MSDASQL',
                    'Driver={Microsoft Text Driver (*.txt; *.csv)};
                    DefaultDir=C:\;',
                    'SELECT * FROM abc.csv'
                ) t1 INNER JOIN GROUP t2 ON t1.[Group Name] = T2.[Group Name]
        

      注意:您可以将数据导入临时表,然后查询该表,以避免多次连接到 csv 文件


      使用 PowerShell 的解决方案

      将 csv 文件导入 SQL Server 有多种方法,您可以查看以下链接以获取更多信息。


      参考文献

      【讨论】:

      • 为什么不添加第三个选项 Powershell?
      • @MarkKram 我在 Powershell 方面没有很好的经验,但我很想看看它是如何完成的。如果你知道它请写一个答案。我一定会赞成的
      • @MarkKram 我在我的回答中添加了一些关于使用 powershell 将 csv 导入到 sql-server 的有用链接。
      • 借助 Powershell (PoSh),您可以在脚本环境中利用 .Net 框架(想想 CLR)。您还可以在 SQL 代理作业中本地运行 PoSh 脚本。我一直使用它来导入 CSV、Excel 和 Access 数据。它非常强大且易于使用。
      • 你在回答中付出了多大的努力+1
      猜你喜欢
      • 2011-02-22
      • 2013-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-17
      相关资源
      最近更新 更多