DATASTAGE实用指南 下载本文

DATESTAGE 使用实用指南

DS的竞争对手:

Informatica的PowerCenter Group 1的Stagent Data Flow BO的DI

ASCL的Data Stage

1.DataStage官方文档学习笔记

1.1通过右键添加link

鼠标右键点击起始stage,按住右键移动鼠标到目标stage。还有一种方法就是把鼠标放在起始stage的边缘等到变为一个小圆圈里面有一个叉的时候拖动鼠标到目标stage。

1.2DataStage中默认和隐式类型转换时注意的问题

当从源向目标映射数据时,如果类型不一致,对于有些类型我们需要在modify或transfomer stage中通过函数进行转换,对于有些系统会自动完成类型转换,在类型转换过程中,注意以下几点:

1 在变长到固定长度字符串的默认转换中,parallel jobs用null(ASCII 0)字符来填充剩余长度。联系到前面做的一个parallel job,当目标是变长时(当时源也是变长,但是好像源的精度要小些),但是字符串实际的长度没有指定的变长那么长的话,系统会自动用空格(ASCII 20)来填充(具体在哪个stage填充的不知),而且环境变量APT_STRING_PADCHAR的默认值也是空格(ASCII 20)。 2 通过环境变量APT_STRING_PADCHAR可以改变默认的填充字符null(ASCII 0)。

注:联系上面两点,感觉文档讲的与实际不符,难道我们项目的administrator改变了该环境变量的默认值?

3 有个PadString 函数可以用来用指定的字符来填充一个变长的字符串到指定的长度。这个函数的参数不能使固定长度字符串,如果是固定长度的先转化为变长。

1.3Copy Stage作为占位符

在job开发中,当你暂时不知道该使用哪个stage时,可以使用copy stage作为占位符,注意不要把Force属性设为True,在不把Force设为True时,复制将在运行时进行优化。

使用Schema file来指定meta data

1 可以通过列定义和schema file两种方式来指定meta data,值得注意的一点是Note that, if you use a schema file, you should ensure that runtime column propagation is turned on. Otherwise the column definitions specified in the stage editor will always override any schema file.即,如果想通过schema file来指定meta data,必须勾上runtime column propagation,否则总是使用列定义来作为meta data。

2 If you are using a schema file on an NLS system, the schema file needs to be in UTF-8 format.如果你的datastage使用了NLS system,那么schema file必须是UTF-8格式的。文档中说可以使用Sequential stage来完成转码。

通过Server Shared Container在Parallel Job中添加Server Job Stage

You create a new shared container in the DataStage Designer, add Server job stages as required, and then add the Server Shared Container to your Parallel job and connect it to the Parallel stages.在Designer中创建一个server shared container,添加需要的Server job stage,再把server shared container添加到parallel job并连接到其他parallel stage。

几个环境变量的具体路径

%SERVERENGINE% – DataStage engine account directory(normally C:\\Ascential\\DataStage\\Engine on Windows and

\\Ascential\\DataStage\\DSEngine on UNIX). %PROJECT% – Current project directory.

%SYSTEM% – System directory on Windows NT or /usr/lib on UNIX.

一句不太懂的话,先做记录

If NLS is enabled, avoid using the built-in Iconv and Oconv functions to map data unless you fully understand the consequences of your actions.在使用了NLS时,尽量避免使用Iconv and Oconv来映射日期,因为可能产生一些意想不到的结果。

1.4Datastage的使用心得及unix应用

Datastage是Ascential公司出品的著名第三方ETL工具。它的主要特点有: 1.可视化操作截面,避免了大量的手工code 2.第三方工具,善于处理复杂的数据源

3.可监控性好,能够快速发现ETL中的问题并解决

对于Datastage的初学者来说,通过学习官方培训资料(网上到处都有的当了),可以快速的入门,毕竟Datastage是一个可视化的工具,没有太深涩难懂的内容。但在真正运用中,就可能碰到各种各样的问题。

下面就说一说我在使用中曾经困惑过的一些问题: 1.Job的粒度。

一套ETL过程中,含有多个步骤,在设计过程中,到底是粗化一些,用少而复杂的job实现,还是细化一些,用多而简单的job实现更好呢?我个人认为,比较细的粒度更有利于程序的开发。在开发初期,表面看来细化的job比较繁琐,但在项目后期的测试阶段,细化的job可以更准确的定位错误并易于修改。

2.并行和串行。

当到了开发后期,我们准备把多个job连接起来,我们就会发现,能否将多个job并行成为ETL效率的关键,而这个因素在设计初期往往被忽略。ETL中可能会涉及多个数据源的多个表,而多个job也可能会形成对某个数据源以及其中的某个表的争用。当数据源争用时,会影响ETL的执行效率。当表争用无法解决的时候,就只能使用串行。而一个好的结构流程设计,可以极大的减少这种争用,从而提高ETL的效率。

3.要将Datastage与外部code相结合。

Datastage并不是独立运行的开发工具,它需要外部控制程序为载体,才可以进行良好的客户操作。而

Datastage也不是万能的,简单的说,它只是sql语言的一个可视化载体。因此,有一些功能,并不一定要在Datastage中实现,而应该放到外部程序中,以sql code的形式完成,以保证整个程序的稳定性,安全性。

上面是一些大方向的问题,在实际中会有很多烦琐的小问题,我也尽量的列举一些:

1.字符集:output和input中的字符集都设置为none,是一个不错的选择。至少可以保证程序运行不会因为乱码abort。

2.文本中的列分隔符无法设置为三位,从理论上讲,只有三位分割符才可以保证程序不会将乱码辨认为分隔符,这是Datastage的一个缺陷。

3.在使用自定义sql前,需要使用非自定义形式手工配置好所需要的表,然后再切回自定义格式,如果直接写自定义sql,将导致Datastage无法辨别表名,从而导致错误,这应该是一个bug。

4.保持配置一个input或output,就view data一下的习惯,不要等到run时再回头找error. 5.Input中尽量不要使用insert or update之类的选项,它和insert only的差别是巨大的。使用insert or update等选项,相当于使用游标,逐条进行对比,每insert一条,都要先做一次全表扫描,其速度是可想而知的。如果必须要实现这种功能,应使用其他方法,如先delete目标表中所有与源表重复的记录,然后再从源表中insert数据.

6.Date型数据是比较麻烦的,因为Datastage中的日期格式为timestamp,当然你也可以把它的日期格式更改为date型,但经常会出现错误。对于oracle数据库源表和目标表,不需要对date型数据做任何转换,直接使用默认即可,但对于informix等一些数据库,则需要使用oconv,iconv函数进行转换,并在output中相应的修改output sql中的日期格式。具体用法可以去网上或查datastage帮助。 7.只要你保证input和output时数据类型和长度不会有问题,在两者之间的这一段过程中,Datastage中的数据类型和长度是可以随意更改的,也可以随意增加自定义列。

8.字符串中的半角空格需要用trimb,而不是trim函数,但这点往往被忽略。其他的情况还可能有半角中文等,所以字符串,长度,字符集,这几者之间经常会导致Datastage产生错误,所以应尽量保证insert前的字符串长度要小于insert后的字符串长度,而你看到的insert前的字符串长度并不一定就是它在Datastage中真正的长度,所以使用trimb函数在input sql中做一下限制,才是最稳妥的方法。

2.实用技术介绍

2.1JOB的分类与作用

1、Server JOB:

最为常用的Job类型,Job可以组合使用,Server Job是Job的最小单位。 原文档:If you have the Web Services pack installed an additional check box, Web Service Enabled, appears. Select it to indicate the job can be made available as a web service. 2、Parallel JOB:

3、Mainframe JOB:运行于大型机的JOB。

4、JOB Sequences:Job Sequence主要用于Job间的协作工作控制,如各Job的实行流程,出错处理,文件监控等。

2.2jobstatus的用法

jobstatus

-jobstatus waits for the job to complete, then returns an exit code derived from the job status.

命令格式为:

dsjob –run

[ –mode [ NORMAL | RESET | VALIDATE ] ] [ –param name=value ] [ –warn n ] [ –rows n ] [ –wait ] [ –stop ] [ –jobstatus] [–userstatus] [-local] project job

2.3判断NULL值

实例

STAGE :JOIN STAGE 设置: LEFT JOIN

左输入语句:SELECT * FROM PMP_Insured_Amount 右输入语句:SELECT COL_ID,TAB_NAME,WORK_DATE,

REF_COLUMN1 AS UNIQUE_ID_IN_SRC_SYS, REF_COLUMN2,ROW_ID, HASHCODE AS B_HASHCODE, ANCHOR_ID,PARTITION_KEY, IS_DUPLICATED,

'A' AS MARK --用以判断结果集右边是否为空 FROM ETL_FOR_INC_TMP2 SQL语句:

SELECT A.*,B.*

FROM PMP_Insured_Amount A

LEFT JOIN ETL_FRO_INC_TMP2 B

ON A.UNIQUE_ID_IN_SRC_SYS = B.UNIQUE_ID_IN_SRC_SYS

功能:判断来自A表的所有记录,哪些能够B表关联,哪些不能与B表关联。说明:由于在构造右输入语句时增加了一个B表中没有的常量字段MARK,所以如果A表能够与B表关联的记录,该常量字段就不为空值(此处设了该常量值为 A);如果A表与B表关联不上的记录,该常量字段就为空值(NULL)。如此只需用一条判断语句判断常量字段是否为空,从而分出两种记录来。

记录分离所使用的STAGE是Transform stage。一开始时,使用Condition设置了字段MARK = 'A'与字段MARK <> 'A' 来分离记录,运行后发现只有MARK = 'A' 的一支有数据通过,而MARK <> 'A' 的一支没有数据通过,后来把 MARK <> 'A' 的一支的条件(condition)改为 ISNULL(MARK) 后,数据正常输出。

总结:从理论上说,任何与NULL值作比较运算(=、>、<、<>)结果都为NULL,而 MARK <> 'A' 属于比较运算,当MARK为NULL时,结果就为NULL,所以就会没有数据输出。实际上,在MSSQL SERVER2000中,如果使用 WHERE MARK <> 'A' 作筛选条件,是可以把为 NULL 值的字段输出的。这是DATASTAGE与MSSQL SERVER在处理 NULL 值运算的不同,MSSQL SERVER是允许一定违反规范规则的情况存在。

2.4关于对多表进行关联操作的STAGE对不同表的同名字段的处理

这些STAGE有:JOIN、LOOKUP、MERGE等。 DATASTAGE的处理原则:保留前者,抛弃后者。 例子:

源表:A(a,b,c,d),关联表:B(b,c,e,f)。

取值规则:第一次关联条件A.b = B.b,取B.e;第二次关联条件A.c = B.c,取B.e。

说明:关联的有前后之分的。第一次关联时,在结果集中已经存在的名字为e的字段,第二次关联是在第一次关联的结果集的基础上进行的,第二次所取的字段名与 第一次所取的相同。在此就出现种问题,从数据库常识来说,同一张表是不允许有同名字段出现的,如何能够正确取值呢?

在T-SQL里面,可以使用JOIN语句对表进行关联,两张表的同名字段e因为被加了表名作前缀,所以即使字段名相同,也可以正确输出。以下则为使用T-SQL完成上述取值规则的语句: SELECT A.a,A.b,A.c,A.d,B.e FROM A LEFT JOIN

(SELECT A.a,A.b,A.c,A.d,B.e,AB.e

FROM A LEFT JOIN B ON A.b = B.b) AS AB ON A.c = AB.c 很容易就能看出,最终的结果将会(假设结果表名为C):C( A.a,A.b,A.c,A.d,B.e,AB.e),结果正确,所以在T-SQL里,在做多表关联时,可以不必关心不同表的同名字段的取值问题。

但在DATASTAGE里就不能不关心了。由于DATASTAGE里的所有STAGE的输出,默认下是对该STAGE的输入进行复制,即表结构的复制。输 入的是什么名字的字段,输出的也是这个名字的字段。那么多表关联时,如果不同的表有相同名字的字段,那么输出时也会出现有同名字段了,而数据表是不允许有 同名字段的,所以就会发生同名冲突。DATASTAGE对于这中其矿,处理方式是把最先输入的字段保留下来,之后如果有同字段再添加进来时,就会把要添加 进来的字段抛弃掉。这种情况,即使在JOB运行时也不会报错的,因为语法是没有错误的,不过会出现一个WARNING,告知用户这个STAGE将会出现字 段知丢失。所以碰到上面上述情况,解决的方法是在第二次关联时,在输出时把这个同名字段的名字手工更改一下。如上,把字段名e改为字段名e_2,赋值也是 赋e过去,这样既保留了e的值,有不会给抛弃,只是更改了一下字段的名字,到最后输出时再统一把结果表名定制一下就行。