【问题标题】:Update data from tables on different servers从不同服务器上的表中更新数据
【发布时间】:2019-06-29 16:12:42
【问题描述】:

我有 2 个表 Employee 和 Department 表

员工: (SQL 服务器)

EmpID EmpName DOJ
1      Mohan      NULL
2      Manasa     NULL

部门: (Teradata)

DepID     DepName EmpName        DOJ
1        Maths    Mohan K       2017-08-01
2        English  Mohan Kumar 2018-08-01
3        Science  Manasa K    2016-08-01
1        Social   Manasa       2017-09-01

我需要使用 Department 表更新 Employee 表加入列的日期。 我需要根据 MA​​X Condition 获取最新加入日期,并且需要使用 SSIS 使用 LIKE Con​​dition。

最初我使用 EXECUTE SQL TASK 并通过变量发送 FULL RESULT SET 并将该 SQL TASK 放入 For Each 循环容器中

并且需要在 Employee 表中更新如下:

EmpID  EmpName   DOJ
1         Mohan   2018-08-01
2         Manasa  2017-09-01

我用过

  • EXECUTE SQL TASK :我写了查询SELECT EMPNAME FROM EMPLOYEE 并给出了完整的结果集并存储在一个变量中
  • FOR EACH LOOP CONTAINER:使用 ADO.ENUMERATOR 并使用该变量。

请提出实现此目的的方法

Employee 表来自 SQL Server,Department 表来自 Teradata

【问题讨论】:

  • 您使用什么逻辑将Employee 表中的EmpName 值与Department 表中的值匹配?当两名员工的名字或姓氏相同时会发生什么?
  • Department 中可以更新多少行,Employee 中要更新多少行?

标签: sql sql-server ssis teradata etl


【解决方案1】:

(1) 如果Source和Destination在同一台服务器上

我认为您可以使用没有 Foreach 循环容器的执行 SQL 任务来实现这一点:

(a) Employee.EmpName = Department.EmpName

With CTE_1 AS (SELECT EmpName  , MAX(DOJ) as mx FROM Department GROUP BY EmpName) 
    UPDATE T1
    SET T1.DOJ = CTE_1.mx
    FROM Employee T1 INNER JOIN CTE_1 ON CTE_1 EmpName = T1.EmpName;

(b) Employee.EmpName = Department.FirstName

如果 Department 表包含全名,而 Employee 表只包含名字,则应使用以下查询:

With CTE_1 AS (CASE WHEN CHARINDEX(' ', EmpName) > 0
               THEN SUBSTRING(EmpName, 1, LEN(EmpName) - CHARINDEX(' ', REVERSE(EmpName)))
               ELSE EmpName END AS   EmpName  
     , MAX(DOJ) as mx FROM Department GROUP BY CASE WHEN CHARINDEX(' ', EmpName) > 0
               THEN SUBSTRING(EmpName, 1, LEN(EmpName) - CHARINDEX(' ', REVERSE(EmpName)))
               ELSE EmpName END) 
    UPDATE T1
    SET T1.DOJ = CTE_1.mx
    FROM Employee T1 INNER JOIN CTE_1 ON CTE_1 EmpName = T1.EmpName;

(c) Department.FirstName 以 Employee.EmpName 开头

或者,如果您希望使用不太准确的开始条件加入:

With CTE_1 AS (SELECT EmpName  , MAX(DOJ) as mx FROM Department GROUP BY EmpName) 
    UPDATE T1
    SET T1.DOJ = CTE_1.mx
    FROM Employee T1 INNER JOIN CTE_1 ON CTE_1 EmpName LIKE T1.EmpName + '%';

(2) 如果Source和Destination在不同的服务器上

(a) 在 SQL SERVER Management Studio 中创建链接服务器

我认为最简单的方法是在 SSMS 中 create a linked server 或通过 T-SQL 对 Teradata 数据库执行上述查询。

(b) 使用临时表

另一种方法是将部门表导入 SQL Server 中的临时表,然后执行上述查询之一。

(c) 通过 OLEDB 命令使用查找

如果您没有创建链接服务器或将数据导入临时表的权限,您可以使用类似命令从部门表中获取 OLE DB 源:

SELECT CASE WHEN CHARINDEX(' ', EmpName) > 0
           THEN SUBSTRING(EmpName, 1, LEN(EmpName) - CHARINDEX(' ', REVERSE(EmpName)))
           ELSE EmpName END AS   EmpName  
 , MAX(DOJ) as mx FROM Department GROUP BY CASE WHEN CHARINDEX(' ', EmpName) > 0
           THEN SUBSTRING(EmpName, 1, LEN(EmpName) - CHARINDEX(' ', REVERSE(EmpName))) ELSE EmpName END From Department

并使用 OLEDB 命令(SQL Server 连接) 逐行执行更新操作,使用类似的命令:

Update Employee SET DOJ = ? WHERE EmpName = ?

并且在 Column Mappings 选项卡中,将 DOJ 列映射到第一个参数,将 EmpName 列映射到第二个参数。如果您不熟悉 OLE DB 命令,请查看以下示例以了解更多详细信息。


参考文献

【讨论】:

  • 我认为 OP 说他想使用 LIKE,因为 Employee 表中的 EmpName 值与 Department 表中的名称不同。
  • @digital.aaron 我更新了我的答案,我按名字分组
  • @Hadi 感谢您的回答 Employee 表来自 SQL SOURCE,Department 表是 Teradata 源。如何通过变量将 emp 名称传递到条件表中的部门表
  • 确定@Hadi 我会在我的代码中实现这个并回复你
  • 但我希望通过使用 For each 循环容器和变量来做到这一点。对此您有什么建议吗
猜你喜欢
  • 2016-06-06
  • 1970-01-01
  • 1970-01-01
  • 2020-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
  • 2016-10-10
相关资源
最近更新 更多