【发布时间】:2019-05-11 01:02:55
【问题描述】:
我有 Oracle 12C 源和 SQL Server 目标。在事实表中,我需要拍摄每日快照(不是整个数据),在维度表中,我只需要拍摄新行,而不是整个表。似乎不可能在 Oracle 端使用变量。 最好的方法是什么?
【问题讨论】:
标签: sql-server oracle ssis etl sql-server-data-tools
我有 Oracle 12C 源和 SQL Server 目标。在事实表中,我需要拍摄每日快照(不是整个数据),在维度表中,我只需要拍摄新行,而不是整个表。似乎不可能在 Oracle 端使用变量。 最好的方法是什么?
【问题讨论】:
标签: sql-server oracle ssis etl sql-server-data-tools
**
**
我使用 Attunity Oracle 连接器取得了非常好的成功。当您使用它们设置 Oracle 源时,您可以将源定义为表/视图名称或 SQL 查询。执行此操作时,您可以在查询中添加 WHERE 条件。
但如果您想在查询中使用未硬编码的日期,则需要创建一个表达式。类似,但您在数据流之前添加Execute SQL Task,并在那里构建动态 sql 查询并将其保存到变量中。然后,您可以使用该变量为 Oracle Source SQL 查询定义表达式。
然后选择您的数据流任务并查看“属性”窗口。在“其他”下,您应该会看到 [Oracle Source].[SqlCommand] 的一行。您可以在此处进入表达式编辑器并将您的变量设置为 SqlCommand。
为此,您可以使用一种技术,将源中的哈希值与目标中的哈希值进行比较,以确定行是否已更改。
您需要做的第一件事是导入所有数据,同时包括行数据的哈希。
定义您的 Oracle 源以使用 SQL 命令作为数据访问模式。这是我的表的示例:
SELECT
CAST("Data Source Code" AS VARCHAR2(3)) AS "DataSourceCode"
,"Matrix Id" AS "MatrixId"
,CAST("Primary Matrix Type" AS VARCHAR2(11)) AS "PrimaryMatrixType"
,CAST("Branch Number" AS VARCHAR2(4)) AS "BranchId"
,"Effective Date" AS "EffectiveDate"
,"Expiration Date" AS "ExpirationDate"
,"Spa Flag" AS "SpaFlag"
,CAST("Default Contract Number" AS VARCHAR2(50)) AS "DefaultContractNumber"
,CAST("Direct Contract Number" AS VARCHAR2(50)) AS "DirectContractNumber"
,"Refresh Date" AS "RefreshDate"
,CAST(UPPER(RAWTOHEX(SYS.DBMS_OBFUSCATION_TOOLKIT.MD5(input_string =>
CAST("Data Source Code" AS VARCHAR2(3)) || '|' ||
"Matrix Id" || '|' ||
CAST("Primary Matrix Type" AS VARCHAR2(11)) || '|' ||
CAST("Branch Number" AS VARCHAR2(4)) || '|' ||
CAST("Effective Date" AS VARCHAR2(30)) || '|' ||
CAST("Expiration Date" AS VARCHAR2(30)) || '|'||
"Spa Flag" || '|' ||
CAST("Default Contract Number" AS VARCHAR2(50)) || '|' ||
CAST("Direct Contract Number" AS VARCHAR2(50))
))) AS VARCHAR2(32)) AS "HashVal"
FROM DWDIGITAL.CONTRACT_TABLE
WHERE "Effective Date" >= TO_DATE('2018/01/01', 'yyyy/mm/dd')
我在这里使用SYS.DBMS_OBFUSCATION_TOOLKIT 生成MD5 哈希值,使用所有行列数据的串联字符串(确保将所有列转换为哈希字符串)。我使用SYS.DBMS_OBFUSCATION_TOOLKIT 而不是ORA_HASH,因为我在Oracle 服务器上的权限有限,而SYS.DBMS_OBFUSCATION_TOOLKIT 不需要像ORA_HASH 这样的升级权限。我这里也选择了MD5,因为如果我需要在SQL端生成一个哈希值,事实上,我仍然可以生成相同的哈希值,因为SQL Server也可以使用MD5算法。如果您有权访问ORA_HASH,则可以使用其中一种 SHA* 算法。另外,请注意我在哈希计算的每一列之间添加了|。这样"My"+"text" 和"Myt"+"ext" 将生成不同的哈希值并防止误报,因为My|text 和Myt|ext 是不同的。
现在您的目标表已经加载了数据和数据的哈希值。要创建迭代加载,您首先需要从目标创建键和哈希值的“缓存”。添加一个数据流任务,并创建一个指向目标表的源连接,并将该流直接通过管道传输到Cache Transform。
缓存变换将用于在下一个 DFT 中执行查找变换。您需要配置缓存文件和要缓存的列。
我的主键设置为索引位置 1。
此处的源连接将使用您在上述初始加载期间使用的相同查询。然后创建一个查找转换,并将缓存的 HashVal 添加为新列。
这里应该有两个输出。 “不匹配”输出是来自源的行,其中键在目标中不存在。这些是要插入的新行。然后获取“匹配”输出并将其指向“条件拆分”。条件拆分将比较 HashVals。匹配的 HashVals 表示该行没有变化。不匹配的 HashVals 表示记录已更改。我将这些记录加载到临时表中,并使用存储的 proc 调用来执行 UPDATE 操作。
【讨论】: