使用 SSIS 加载多个表并保持外键关系

2023-11-22

我正在尝试使用 SSIS 将单个文件(包含数百万条记录)中的数据加载到 SQL Server 上的多个表中,同时维护文件中定义的关系。

为了更好地举例说明,假设我正在尝试加载一个文件,其中包含员工姓名、他们过去占用的办公室以及由选项卡分隔的职位历史记录。

File:

EmployeeName<tab>OfficeHistory<tab>JobLevelHistory
John Smith<tab>501<tab>Engineer
John Smith<tab>601<tab>Senior Engineer
John Smith<tab>701<tab>Manager
Alex Button<tab>601<tab>Senior Assistant
Alex Button<tab>454<tab>Manager

如果我的 Office 数据库架构具有下表:

Employee (nId, name)
Office (nId, number)
JobTitle (nId, titleName)
Employee2Office (nEmpID, nOfficeId)
Employee2JobTitle (nEmpId, nJobTitleID)

如何使用 SSIS 将文件加载到上述自动生成员工、办公室和职位 ID 的架构中,并维护员工与办公室、员工与职位之间的关系?

所以在这种情况下。表格应如下所示:

Employee
1 John Smith
2 Alex Button

Office
1 501
2 601
3 701
4 454

JobTitle
1 Engineer
2 Senior Engineer
3 Manager
4 Senior Assistant

Employee2Office
1 1
1 2
1 3
2 2
2 4

Employee2JobTitle
1 1
1 2
1 3
2 4
2 3

我是 SSIS 的新手,在执行数据流任务时还没有尝试过自动生成 ID 和建立外键关系。任何指示将不胜感激。

Thanks!


一个有趣的问题。这是我的做法(Sql Server 2005)。 (我假设这是每月一次的工作,而不仅仅是一次,因此我添加了可重复性代码。)

  1. 为 Employee、JobTitle 和 Office 表创建三个变量(类型=对象)
  2. 使用三个 sql 任务将这三个表的行选择到相应的变量中。
  3. 添加数据流任务。
  4. 使用平面文件目标从平面文件中进行选择。
  5. 输出进入脚本组件,其中平面文件中的三列作为输入,导入到脚本中的三个表变量,脚本组件中的五个输出,每个输出具有相同的排除组编号,并且输入标记为与该输出同步,七个新列(3 个用于 emp,每个输出对应一个列,2 个用于工作,2 个用于办公室)添加到输出中,并使用以下代码(必须添加对 System.xml.dll 的引用才能使这一切工作。):

    Imports System
    Imports System.Data
    Imports System.Math
    Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
    Imports Microsoft.SqlServer.Dts.Runtime.Wrapper
    Imports System.Collections
    Imports System.Data.OleDb
    
    Public Class ScriptMain
        Inherits UserComponent
    
        Private da As New OleDbDataAdapter
        Private emp As New DataTable
        Private emph As New Hashtable()
        Private job As New DataTable
        Private jobh As New Hashtable()
        Private off As New DataTable
        Private offh As New Hashtable()
        Private maxempid As Integer
        Private maxjobid As Integer
        Private maxoffid As Integer
    
        Public Overrides Sub PreExecute()
            maxempid = 0
            maxjobid = 0
            maxoffid = 0
            da.Fill(emp, Me.Variables.EmpTab)
            For Each dr As DataRow In emp.Rows
                emph.Add(dr.Item("Name"), dr.Item("nID"))
                If (CInt(dr.Item("nID").ToString) > maxempid) Then
                    maxempid = CInt(dr.Item("nID").ToString)
                End If
            Next
            da.Fill(job, Me.Variables.JobTab)
            For Each dr As DataRow In job.Rows
                jobh.Add(dr.Item("titleName"), dr.Item("nID"))
                If (CInt(dr.Item("nID").ToString) > maxempid) Then
                    maxjobid = CInt(dr.Item("nID").ToString)
                End If
            Next
            da.Fill(off, Me.Variables.OffTab)
            For Each dr As DataRow In off.Rows
                offh.Add(dr.Item("number"), dr.Item("nID"))
                If (CInt(dr.Item("nID").ToString) > maxempid) Then
                    maxoffid = CInt(dr.Item("nID").ToString)
                End If
            Next
            emp.Dispose()
            job.Dispose()
            off.Dispose()
            da.Dispose()
            MyBase.PreExecute()
        End Sub
    
    Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
    
        If Not emph.ContainsKey(Row.EmployeeName) Then
            maxempid += 1
            emph.Add(Row.EmployeeName, maxempid)
            Row.EmpId = maxempid
            Row.Emp2Id = maxempid
            Row.Emp3Id = maxempid
            Row.DirectRowToEmployee()
        Else
            Row.EmpId = CInt(emph.Item(Row.EmployeeName).ToString)
            Row.Emp2Id = CInt(emph.Item(Row.EmployeeName).ToString)
            Row.Emp3Id = CInt(emph.Item(Row.EmployeeName).ToString)
        End If
        If Not jobh.ContainsKey(Row.JobLevelHistory) Then
            maxjobid += 1
            jobh.Add(Row.JobLevelHistory, maxjobid)
            Row.JobId = maxjobid
            Row.Job2Id = maxjobid
            Row.DirectRowToJobTitle()
        Else
            Row.JobId = CInt(jobh.Item(Row.JobLevelHistory).ToString)
            Row.Job2Id = CInt(jobh.Item(Row.JobLevelHistory).ToString)
        End If
        If Not offh.ContainsKey(Row.OfficeHistory) Then
            maxoffid += 1
            offh.Add(Row.OfficeHistory, maxoffid)
            Row.OffId = maxoffid
            Row.Off2Id = maxoffid
            Row.DirectRowToOfficeNumber()
        Else
            Row.OffId = CInt(offh.Item(Row.OfficeHistory).ToString)
            Row.Off2Id = CInt(offh.Item(Row.OfficeHistory).ToString)
        End If
        Row.DirectRowToEmp2Job()
        Row.DirectRowToEmp2Off()
    End Sub        
    End Class
    
  6. 该脚本的结果(该脚本为输入数据中的新值生成 id。它通过将现有表加载到脚本预执行部分的哈希表中来实现此目的,然后检查名称是否存在并基于该名称增加 maxid 并将其添加到散列(如果它添加到散列),它还会将该行添加到适当的(emp、job 或 off)输出,或者从每行的散列中检索 maxid。)所有行,无论上述状态将写入其余两个输出(emp2job 和 emp2off)。

  7. 接下来,发送数据流进行查找(检查目标表中的现有行,然后检查目标 oledb 连接器(emp、job 和 off 选中身份插入框,emp2job 和 emp2off 取消选中检查约束)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 SSIS 加载多个表并保持外键关系 的相关文章

  • 对存储过程内容的只读访问

    是否可以设置 SQL Server 来为开发人员提供对生产数据库上存储过程内容的只读访问权限 您可以授予他们VIEW DEFINITION这些进程的特权 See here http msdn microsoft com en us libr
  • 使用 SQL Pivot 显示所有行,包括记录计数为零的行

    有没有办法使用 Pivot 来包含不存在记录的行并在结果中显示 0 或 null 我希望查询的结果看起来像这样 A B C D 5 12 81 107 0 4 0 0 0 0 3 1 12 12 5 2 3 0 0 0 1 0 0 0 0
  • SQL Server 连接池不检测关闭的连接?

    多年来 我在所有连接到 SQL 服务器的 Web 应用程序上都遇到了非常奇怪的问题 问题是 如果数据库服务器发生问题 服务器重新启动或其他问题 de web 应用程序将从那时起停止工作 即使数据库服务器处于活动状态并且之后运行良好 发生的情
  • SQL Server:将数据从一列复制到另一列?

    我有两个具有相同列的表anomaly id 我想复制该行anomaly id使用此代码从第一个表到第二个表 UPDATE amb anamoly log update SET anamoly id t2 anomaly id FROM am
  • 年函数不支持 dt_wstr

    我无法使用下面的代码应用转换 出现错误 年函数不支持 dt wstr 我使用的表达式是 DT I4 DT WSTR 4 YEAR fisc wk end dt RIGHT 0 DT WSTR 2 MONTH fisc wk end dt 2
  • 将查询结果即时导出到文件

    我需要将查询结果导出到 csv 文件并将该文件放在网络共享文件夹中 是否可以在存储过程中实现此目的 如果是 则会出现另一个限制 我可以在没有系统管理员权限的情况下实现此目的 也就是不使用 xp cmdshell BCP 实用程序吗 如果 2
  • Informatica:工作流映射引用的 odbc.ini 文件错误

    我正在尝试从 Informatica Workflow 中执行工作流映射 来源是MSSQL Server和目标Oracle DB 该映射与其他所有映射类似 似乎都指的是系统的 etc odbc ini文件而不是坐在里面的人 INFA HOM
  • 适用于 SQL Server 的 Microsoft ODBC 驱动程序 13:用户“sa”登录失败

    我正在安装 Informatica 的 MDM MDM 10 2 Jboss 6 4 EAP SQL Server 11 Windows Server 2008 R2 在创建模式 sip ant bat create bpm 期间 我收到此
  • 使用具有外键的表将数据从 asp.net 页面插入到我的数据库中

    我是一名初学asp net程序员 我的项目是网上购物课程 我有一些问题 我有 4 个表 它们之间有一些外键 CREATE TABLE dbo orderdetails orderid INT NOT NULL classid INT NOT
  • 存储过程 - 使用 NOT IN where 子句执行查询

    我有一个存储过程 Create PROCEDURE abc sRemovePreviouslySelectedWhereClause nvarchar max AS BEGIN SELECT FROM table WHERE nId NOT
  • 在 T-SQL 中解析 JSON 数组

    在我们的 SQL Server 表中 我们有一个存储有字符串数组的 json 对象 我想以编程方式将该字符串拆分为几列 但是 我似乎无法让它发挥作用 或者即使有可能 是否可以在WITH子句中创建多个列 或者在select语句中创建多个列是更
  • 插入后用触发器更新多行(sql server)

    我有一个表 orderDetails 包含订单的产品 产品编号 color size quantity 和一个表库存 产品编号 size color stock 订单完成后 我使用此查询将项目插入表中orderDetails INSERT
  • Id 或 [TableName]Id 作为主键/实体标识符

    是否首选使用 Id 作为主键的列名或 TableName Id 作为命名约定 表 账户主键 ID 相对 表 账户主键 AccountId 在我见过的实现中 它似乎分为 50 50 左右 每种方法的优点和缺点是什么 跟进 在我的数据库中使用一
  • 如何在 SQL Server 中的特定字符后分割字符串并将该值更新到特定列

    我有包含数据的表格1 1 to 1 20在一列中 我想要值 1 到 20 即 前斜杠 之后的值更新到 SQL Server 中同一表中的其他列 Example 专栏有价值1 1 1 2 1 3 1 20新列值1 2 3 20 也就是说 我要
  • PDO SQLSRV 和 PDO MySQL 在获取 int 或 float 时返回字符串

    当您获取时 PDO MS SQL Server 和 PDO MySQL 都会返回一个字符串数组 即使列的 SQL 类型本应是数字类型 例如 int 或 float 我设法解决了这个问题 但我想了解为什么它们一开始就这样设计 是不是因为PDO
  • 如何使用 DateTime 执行 SQL NOT NULL?

    一个人如何处理DateTime with a NOT NULL 我想做这样的事情 SELECT FROM someTable WHERE thisDateTime IS NOT NULL But how 嗯 它有效吗 我刚刚测试过 Obje
  • SQL服务器事务

    我需要了解sql server事务 我浏览了谷歌上的一些文章 但我什么也没理解 谁能帮我 您可以通过写入显式启动事务BEGIN TRANSACTION 您可以通过运行来结束事务COMMIT TRANSACTION 之前COMMIT运行时 受
  • SQL Server,插入 Excel“链接服务器”时出现“无效列名”错误

    我有一个简单的 Excel 电子表格文档 运行 Office 2013 我使用 Microsoft Office 15 0 Access 数据库引擎 OLE DB 提供程序 将其用作数据库 我可以使用 MS SQL Server Manag
  • sql server 按组排名

    问题看似简单 但我却无法理解 这是针对 sql 服务器的 what I have in a table What I need as a output cksum id cksum id 2162514679 204 2162514679
  • 对多个数据库执行 SQL 查询

    我知道我的帖子与该论坛中的其他帖子的标题非常相似 但我真的找不到我需要的答案 这是我的问题 我的 Windows Server 上运行着 SQL Server 在我的 SQL Server 中 我有大约 30 个数据库 它们都具有相同的表和

随机推荐

  • 如何使用 PostgreSQL 中的函数插入多行

    我想使用 PostgreSQL 中的函数在表中插入多行 这是我的桌子 CREATE TABLE mahasiswa nim CHAR 10 nama VACHAR 40 CONSTRAINT pk nim PRIMARY KEY nim 这
  • 请帮助测试 Firefox jQuery ajax 出现 401 时的 CORS 问题

    这让我发疯 jQuery 1 4 2 Windows XP SP3 这是我的测试 加载火狐浏览器3 5 http plungjan name test testcors html works 将文件保存到硬盘并从那里运行 从我的办公室来看
  • 如何从 Visual Studio Code 中使用 Electron 和 Angular 调试应用程序?

    我正在尝试使用最新版本的 Angular 和 Electron 开发一个非常简单的应用程序 为此 我遵循了 Angular 和 Electron 的教程 经过大量的试验和错误 我终于可以启动我的应用程序 源代码在 GitHub 上 我使用
  • jquery 多个事件处理程序

    我已经根据我正在处理的最新项目中的类名定义了事件处理程序 对于前 所有具有类名 foo 的元素都应该以特定的方式响应更改事件 所有类名为 bar 的元素都应该以其他方式响应 现在我的一些元素属于这两个类 即 class foo bar 并且
  • 基类方法可以返回派生类的类型吗?

    根据我读过的其他帖子 这似乎不可能 但我想我会发布我正在尝试做的事情 看看是否有人知道解决方案 我正在尝试将 Clone 方法添加到从 Telerik 开放访问域模型生成的类中 没问题 我能够弄清楚如何将基类添加到生成的实体模型中 以便我可
  • 从 lapply 或带有 print 语句的函数调用时 kable 出现意外行为

    我试图理解使用 knit 包 在 Ubuntu 14 04 上的 RStudio 0 98 977 中 编织 HTML 时 kable 函数的以下两个意外行为 当从 lapply 中两次调用 kable 时 只有第一个调用会在最终的 HTM
  • TObject 包含哪些数据?

    TObject InstanceSize 返回 8 但 TObject 未声明任何数据成员 根据TObject ClassType的实现 前4个字节可以解释为指向对象的TClass元数据的指针 有人知道另外 4 个字节的开销是做什么用的吗
  • WSFederationAuthenticationModule.IsSignInResponse 中存在潜在危险的 Request.Form

    在我的 MVC3 站点中 我避免使用新的 ValidateInput 属性设置 requestValidationMode 2 0 但现在我尝试切换到 WIF 进行身份验证 当 STS 重定向回我的站点时 我收到异常 因为WSFederat
  • 如何检查函数的模板参数是否具有某种类型?

    假设我有一个具有模板类型的函数T和另外两个班级A and B template
  • 如何运行 GCC 预处理器来获取 #define 等宏扩展后的代码?

    GCC 预处理器是否可以生成 C 源代码并过滤掉不相关的源代码 例如 一个 c文件有一个 define切换以定义许多不同的平台 我只对一个平台感兴趣 并且我希望 C 预处理器过滤掉不相关的代码 Does GCC支持这个吗 是的 使用 E o
  • 从 C# 将二进制数据插入 SQL,无需存储过程

    有谁知道是否可以在不使用存储过程的情况下从 C 将二进制数据插入 SQL 字段 例如 将字节数组转换为 base64 或类似的东西 然后使用如下所示的文本命令 String Format update A set B 0 where C D
  • 在 ASP.NET 中使用依赖注入和工厂模式传递服务

    我正在使用 ASP NET Core 我知道框架已经提供了这样的日志记录机制 但用这个来说明我的问题 我正在使用工厂模式来构建 Logger 类 因为我不知道日志记录的类型 因为它存储在数据库中 ILogger 合约 Log string
  • 以编程方式将 Excel 2003 文件转换为 2007+

    我正在寻找一种方法 基本上获取 2003 年旧文件扩展名 xls 的 excel 文件文件夹 并将它们转换为 xlsm 我知道你可以自己进入Excel表并手动完成 但是有没有办法用代码来完成呢 具体使用任何类型的库 这不是我的代码 但我以前
  • SQL 按日期范围内的频率进行分组

    我需要编写一个存储过程 它接受开始日期 结束日期和频率 日 周 月 季度 年 并根据这些参数输出结果集 显然 简单的部分是按日期范围查询 但是如何按频率分组呢 因此 如果有一组像这样的原始数据 Date Count 11 15 2011 6
  • SonarQube 6.1:如何在没有仪表板的情况下查看随时间的变化?

    SonarQube 曾经有仪表板 可以非常方便地显示指标如何随时间变化 甚至还有一个名为 时间机器 的仪表板 如何在 SonarQube 6 1 中查看此类信息 我很欣赏对 泄漏期 的新关注 但这并不是我关心的全部 转到项目的 度量 空间并
  • LibUsbDotNet 调用 UsbDevice.AllDevices 时未找到设备

    我正在执行 LibUsbDotNet 的示例代码 它将返回所有连接的 USB 设备的信息 您可以在下面找到此代码 using System using LibUsbDotNet using LibUsbDotNet Info using L
  • 尝试在 Windows 上重定向 stdout 和 stderr - _fileno(stdout) 返回 -2

    这是我的第一个问题 我即将将一些运行良好的 C 代码从 UNIX 移植到 Windows 它通过管道将 stdout 和 stderr 重定向到自定义 GUI 组件 我需要它来显示来自第三方库的反馈 该第三方库仅将消息输出到 GUI 上的标
  • 在C python中,访问字节码评估堆栈

    给定一个 C Python 帧指针 如何查看任意计算堆栈条目 一些特定的堆栈条目可以通过locals 我说的是其他堆栈条目 我不久前问了一个更广泛的问题 获取 C python exec 参数字符串或访问计算堆栈 但在这里我想重点关注能够在
  • 使用多语句 lambda 进行返回类型推导

    我一直在编写代码 最近发现 g 不会警告我某一类问题 根据 C 11 5 1 2 4 如果您的 lambda 不是单个返回语句 则返回类型必须声明为尾随返回类型或为 void 尽管 g 允许编译无效代码 如果它足够有意义 但有没有办法关闭此
  • 使用 SSIS 加载多个表并保持外键关系

    我正在尝试使用 SSIS 将单个文件 包含数百万条记录 中的数据加载到 SQL Server 上的多个表中 同时维护文件中定义的关系 为了更好地举例说明 假设我正在尝试加载一个文件 其中包含员工姓名 他们过去占用的办公室以及由选项卡分隔的职