一种ETL任务中指标变更的检测方法和装置与流程

文档序号:17880553发布日期:2019-06-13 10:32阅读:119来源:国知局
本申请涉及数据仓库
技术领域
:,具体涉及一种ETL任务中指标变更的检测方法和装置。
背景技术
::ETL(Extract-Transform-Load,数据抽取、转换、装载的过程)作为BI/DW(BusinessIntelligence/DataWarehouse,商业智能/数据仓库)的核心和灵魂,能够按照统一的规则集成并提高数据的价值,是负责完成数据从数据源向目标数据仓库转化的过程,是实施数据仓库的重要步骤。在数据仓库的整个项目中最难部分是用户需求分析和模型设计,而ETL规则设计和实施则是工作量最大的,约占整个项目的60%~80%。数据仓库ETL过程中,当ETL代码变更时,ETL开发人员需要查明指标变更原因,以便于为后续的ETL工作提供有价值的参考。一种常用的ETL指标变更的检测方法是通过记录目标表数据初始状态和结束状态,直接监控这两个状态下目标表指标数据的变化情况,从而查明指标变更的原因。该方法既没有通过某种方式保证ETL代码固定,也没有通过某种方式保证源数据固定。在这种情况下,被检测出发生指标变更的目标表数据,导致其发生指标变更的原因包括两种:既可能是因为源数据随着互联网实际行为变化真的发生了变更导致的,也可能是开发人员修改了ETL数据处理代码导致的。因此,即使发现目标表发生指标变更,开发人员仍无法判断指标变更的具体原因。综上所述,现有技术存在无法准确判断ETL指标变更原因是ETL代码变更还是源数据变更的问题。技术实现要素:本申请提供一种ETL任务中指标变更的检测方法和装置,以解决现有技术存在无法准确判断ETL指标变更原因是ETL代码变更还是源数据变更的问题。本申请提供一种ETL任务中指标变更的检测方法,包括:获取变更前的ETL任务和变更后的ETL任务;解析所述变更前的ETL任务和变更后的ETL任务,生成变更前目标表集合和变更后目标表集合,以及变更前后的所有源表集合,并根据其各自的建表指令进行建表;针对每个源表,按照事先备份好的数据进行初始化;以上述初始化后的源表为数据来源,分别执行所述变更前的ETL任务的数据操作指令和变更后的ETL任务的数据操作指令,在变更前目标表集合和变更后目标表集合中,分别获得相应的数据;比较所述变更前目标表集合和变更后目标表集合的共有目标表下同名指标的数据,判断数据是否发生变化,若是,则判断指标发生变更并作出指标变更标识。可选的,所述判断数据是否发生变化,具体是:判断相同目标表中同名指标下的数据量是否发生变化,若是,则对该同名指标作出“数据量发生变化”的标识。可选的,所述判断相同目标表中同名指标下的数据量是否发生变化的步骤中,若判断结果为否,则:以所述相同目标表中的变化前目标表为主表,选择一个具有主键性质的公共指标作为关联字段;通过所述关联字段,将所述变化前目标表与相同目标表中的变化后目标表相关联,比较所述同名指标下的数据值是否发生变化;若是,则对所述同名指标作出“数据值发生变化”的标识。可选的,若所述比较所述同名指标下的数据值是否发生变化的步骤中,判断结果为是,则找出主键指标的至少一个数据值,并在所述变化前目标表中找出对应所述数据值的所述同名指标的数据值作为变化前数据值,以及在所述变化后目标表中找出对应所述数据值的所述同名指标的数据值作为变化后数据值;将所述共有指标标识为:在所述主键指标为所述数据值时,所述共有指标的值从所述变化前数据值变成所述变化后数据值。可选的,还包括:比较所述变更前目标表集合和所述变更后目标表集合的共有目标表;找出变更前共有目标表中包含而变更后共有目标表不包含的指标集合,这些指标为被下线指标集合。可选的,还包括:根据预先存储的指标依赖关系,获取对发生变更的指标有直接或间接依赖关系的指标。可选的,在所述获取ETL任务在变更前和变更后分别包括的数据操作指令之前,还包括:初始化所述指标依赖关系。可选的,所述初始化所述指标依赖关系包括:针对ETL过程中的每一个ETL任务,获取所述ETL任务包括的数据操作指令;解析所述数据操作指令,获取各个指标生成语句;根据所述指标生成语句,获取所述指标生成语句中的目标指标和源指标,并将所述目标指标和源指标之间的关系作为所述指标依赖关系;所述目标指标直接依赖于源指标。相应的,本申请还提供一种ETL任务中指标变更的检测装置,包括:获取单元,用于获取变更前的ETL任务和变更后的ETL任务;解析单元,用于解析所述变更前的ETL任务和变更后的ETL任务,生成变更前目标表集合和变更后目标表集合,以及变更前后的所有源表集合,并根据其各自的建表指令进行建表;初始化数据单元,用于针对每个源表,按照事先备份好的数据进行初始化;执行单元,用于以上述初始化后的源表为数据来源,分别执行所述变更前的ETL任务的数据操作指令和变更后的ETL任务的数据操作指令,在变更前目标表集合和变更后目标表集合中,分别获得相应的数据;第一比较单元,用于比较所述变更前目标表集合和变更后目标表集合的共有目标表下同名指标的数据,判断数据是否发生变化,若是,则判断指标发生变更并作出指标变更标识。可选的,所述判断数据是否发生变化,具体是:判断相同目标表中同名指标下的数据量是否发生变化,若是,则对该同名指标作出“数据量发生变化”的标识。可选的,所述判断相同目标表中同名指标下的数据量是否发生变化的步骤中,若判断结果为否,则:以所述相同目标表中的变化前目标表为主表,选择一个具有主键性质的公共指标作为关联字段;通过所述关联字段,将所述变化前目标表与相同目标表中的变化后目标表相关联,比较所述同名指标下的数据值是否发生变化;若是,则对所述同名指标作出“数据值发生变化”的标识。可选的,若所述比较所述同名指标下的数据值是否发生变化的步骤中,判断结果为是,则找出主键指标的至少一个数据值,并在所述变化前目标表中找出对应所述数据值的所述同名指标的数据值作为变化前数据值,以及在所述变化后目标表中找出对应所述数据值的所述同名指标的数据值作为变化后数据值;将所述共有指标标识为:在所述主键指标为所述数据值时,所述共有指标的值从所述变化前数据值变成所述变化后数据值。可选的,还包括:第二比较单元,用于比较所述变更前目标表集合和所述变更后目标表集合的共有目标表;标识下线单元,用于找出变更前共有目标表中包含而变更后共有目标表不包含的指标集合,这些指标为被下线指标集合。可选的,还包括:获取依赖单元,用于根据预先存储的指标依赖关系,获取对发生变更的指标有直接或间接依赖关系的指标。可选的,还包括:初始化关系单元,用于初始化所述指标依赖关系。可选的,所述初始化关系单元包括:获取子单元,用于针对ETL过程中的每一个ETL任务,获取所述ETL任务包括的数据操作指令;解析子单元,用于解析所述数据操作指令,获取各个指标生成语句;生成子单元,用于根据所述指标生成语句,获取所述指标生成语句中的目标指标和源指标,并将所述目标指标和源指标之间的关系作为所述指标依赖关系;所述目标指标直接依赖于源指标。与现有技术相比,本发明具有以下优点:本申请提供的ETL任务中指标变更的检测方法和装置,基于ETL代码变更触发对目标表指标变更的检测,通过使用事先备份好的数据初始化ETL任务的源表数据,执行变更前的ETL任务和变更后的ETL任务,获取变更前目标表集合和变更后目标表集合相应的数据;并比较变更前目标表集合和变更后目标表集合的共有目标表下同名指标的数据,发现目标表的指标变更以及具体的变更详情,使得当检测到目标表指标变更时,开发人员若想进一步排查指标变更原因,可以不用考虑源数据不一致的问题,直接就可以判断是ETL代码变更导致的。附图说明图1是本申请的ETL任务中指标变更的检测方法实施例A的流程图;图2是本申请的ETL任务中指标变更的检测方法实施例脚本文件的示意图;图3是本申请的ETL任务中指标变更的检测方法实施例B的具体流程图;图4是本申请的ETL任务中指标变更的检测方法实施例B步骤S300的具体流程图;图5是本申请的ETL任务中指标变更的检测装置实施例的示意图。具体实施方式在下面的描述中阐述了很多具体细节以便于充分理解本发明。但是本发明能够以很多不同于在此描述的其它方式来实施,本领域技术人员可以在不违背本发明内涵的情况下做类似推广,因此本发明不受下面公开的具体实施的限制。在本申请中,提供了一种ETL任务中指标变更的检测方法和装置。在下面的实施例中逐一进行详细说明。请参考图1,其为本申请的ETL任务中指标变更的检测方法实施例的流程图。所述方法包括如下步骤:步骤S101:获取变更前的ETL任务和变更后的ETL任务。本申请提供的ETL任务中指标变更的检测方法,是针对ETL的每一个任务的检测方法。在实际应用中,既可以在ETL任务发生变化后,实时执行检测方法,也可以在执行服务器上部署一个总调脚本,并定时执行该总调脚本,遍历ETL过程中的各个任务,然后针对每个任务,执行本申请提供的ETL任务中指标变更的检测方法。本申请所述的ETL任务是指ETL过程中开发人员预先设计的任务,也称为ETL模块,在其内部封装的是数据操作指令(即:SQL指令),因此其实质是一段ETL代码。一个ETL任务的工作过程包括:从若干源表中取数据、处理数据以及生成目标表数据。在数据仓库的ETL过程中,根据具体的应用需求,ETL开发人员可能会随时变更ETL代码。可选的,ETL任务存储在数据库存储过程中或脚本文件中。本申请实施例所述的ETL任务可以存储在脚本文件中。当任务存储在脚本文件时,总调脚本负责遍历脚本服务器上的脚本目录,得到该目录下每个脚本文件的绝对路径,然后执行以下操作:连接数据库,并调用数据库服务器上的主存储过程,入参为脚本文件的绝对路径。该存储过程实际执行每个任务的指标变更检测。此外,任务也可以不存储在脚本文件中,例如:计算平台是ORACLE,那么任务相关的数据操作指令存储在数据库存储过程中;如果计算平台是ODPS,那么开发可能不用脚本封装ETL过程,而是单个的SQL语句封装,而且任务相关的表结构也不一定一致。上述存储任务的这些不同的方式,都只是具体实施方式的变更,都不偏离本申请的核心,因此都在本申请的保护范围之内。可选的,所述脚本文件采用的编写语言包括:PERL脚本语言、SHELL脚本语言、PYTHON脚本语言。在本实施例中,所述任务存储在脚本文件中,编写脚本文件的语言是PERL脚本语言。请参考图2,其为本申请的ETL任务中指标变更的检测方法实施例脚本文件的示意图。在实际应用中,为使数据库开发管理人员能够更加容易、清楚地理解任务的内容,通常在任务中会使用不规范的指令表达方式。为此,在执行本步骤S102之前,需要对任务相关的数据操作指令进行预处理操作。在本实施例中,在所述获取变更前的ETL任务和变更后的ETL任务之前,还包括:步骤S100:与所述数据库建立连接。步骤S102:解析所述变更前的ETL任务和变更后的ETL任务,生成变更前目标表集合和变更后目标表集合,以及变更前后的所有源表集合,并根据其各自的建表指令进行建表。本申请实施例提供的ETL任务中指标变更的检测方法,解析变更前的ETL任务和变更后的ETL任务,根据分别包括的数据操作指令,生成源表集合包括如下步骤:读取数据操作指令;解析数据操作指令,获取数据操作指令中from子句后的所有表名和join子句后的所有表名;删除所有表名中重复的表名,形成所有非冗余的表名;解析数据操作指令,获取数据操作指令中insertoverwritetable子句后的所有临时表表名;将所有所述临时表表名从所有非冗余的表名中删除,形成源表集合。本申请实施例提供的ETL任务中指标变更的检测方法,解析变更前的ETL任务和变更后的ETL任务,根据分别包括的数据操作指令,生成目标表集合包括如下步骤:读取数据操作指令;解析数据操作指令,获取数据操作指令中insertoverwritetable字句后的所有非临时表表名,形成目标表集合。在本实施例中,通过解析任务的数据操作指令,得到图2所示的脚本文件中的源表有dataware_example_source1、dataware_example_source2和dataware_example_source3,目标表有dataware_example_target_table。在具体实施过程中,由于一个数据库中不能存在同名的两张表,因此,如果变更前的ETL任务和变更后的ETL任务中有相同的目标表,在建表的时候应该在表名上加以区分。例如:ETL任务的目标表为target1,则可以将变更前ETL任务的目标表的表名改为target1_old,而将变更后ETL任务的目标表的表名改为target1_new。步骤S103:针对每个源表,按照事先备份好的数据进行初始化。本申请实施例提供的ETL任务中指标变更的检测方法可以保证在同样的源表数据下,只关注ETL代码变更导致的指标变更。实际应用中,数据仓库的数据会随着日期的推移不断更新,但是由于源表数据有备份,因此在执行本申请的技术方案时,可以使用备份的源表数据初始化与ETL任务相关的源表。步骤S104:以上述初始化后的源表为数据来源,分别执行所述变更前的ETL任务的数据操作指令和变更后的ETL任务的数据操作指令,在变更前目标表集合和变更后目标表集合中,分别获得相应的数据。步骤S105:比较所述变更前目标表集合和变更后目标表集合的共有目标表下同名指标的数据,判断数据是否发生变化,若是,则判断指标发生变更并作出指标变更标识。本申请提供的ETL任务中指标变更的检测方法是将变更前ETL任务和变更后ETL任务生成的相同的目标表的指标进行比对,从而获取该目标表中发生变化的指标。数据仓库ETL过程中,一个ETL任务生成的目标表数量与ETL代码的组织方式相关,通过开发的ETL任务,最终会生成一张或多张目标表。因此,在执行本申请的技术方案时,仅需针对变更前ETL任务和变更后ETL任务生成的共有目标表进行指标比对。在本实施例中,所述判断数据是否发生变化,具体是:判断相同目标表中同名指标下的数据量是否发生变化,若是,则对该同名指标作出“数据量发生变化”的标识。例如:以上述初始化后的源表为数据来源,先后执行变更前和变更后的ETL代码,在变更前的目标表target_table_old和变更后的目标表target_table_new中生成两份数据,对表target_table_old、表target_table_new中都存在的任一同名指标index_I,执行判断数据量是否发生变化的操作,如果target_table_old、target_table_new两表数据量不等,那么指标index_I被标识为“表target_table_old中指标index_I值的数据量发生变化”。本申请实施例提供的ETL任务中指标变更的检测方法,所述判断相同目标表中同名指标下的数据量是否发生变化的步骤中,若判断结果为否,则:以所述相同目标表中的变化前目标表为主表,选择一个具有主键性质的公共指标作为关联字段;通过所述关联字段,将所述变化前目标表与相同目标表中的变化后目标表相关联,比较所述同名指标下的数据值是否发生变化;若是,则对所述同名指标作出“数据值发生变化”的标识。在本实施例中,若所述比较所述同名指标下的数据值是否发生变化的步骤中,判断结果为是,则找出主键指标的至少一个数据值,并在所述变化前目标表中找出对应所述数据值的所述同名指标的数据值作为变化前数据值,以及在所述变化后目标表中找出对应所述数据值的所述同名指标的数据值作为变化后数据值;将所述共有指标标识为:在所述主键指标为所述数据值时,所述共有指标的值从所述变化前数据值变成所述变化后数据值。例如:如果target_table_old、target_table_new两表数据量相等,那么以target_table_old为主表,选择一个具有主键性质的公共指标index_K做关联字段,通过与target_table_new表关联,比较同名指标index_I的值:如果在关联字段index_K为某个值X时,指标index_I的值从value1_index_I变成了value2_index_I,那么index_I被标识为“在指标index_K为某个值X时,指标index_I的值从value1_index_I变成了value2_index_I”。在本实施例中,还包括:步骤S106:比较所述变更前目标表集合和所述变更后目标表集合的共有目标表。步骤S107:找出变更前共有目标表中包含而变更后共有目标表不包含的指标集合,这些指标为被下线指标集合。例如:通过target_table_old和target_table_new的表结构进行比较,对表target_table_old中存在而target_table_new中不存在的指标index_C,标识为“表target_table_old中指标index_C被下线”。对于target_table_new中新增的指标,由于原来并不存在,故不涉及指标变更的问题,所以无需检测。数据仓库ETL过程中,通过开发的ETL任务,最终会生成一张或多张目标表,每一张目标表中有多个指标,这些指标可能会直接或者间接参与到其他指标的ETL计算过程中。一个ETL任务生成的目标表,可能做为其他ETL任务中的源表使用。如果某个ETL任务生成目标表的过程中用到了某张源表,那么该ETL任务就依赖于生成这张源表的那个ETL任务。同理,如果在生成某个目标表字段的时候用到了某个源表中的某个字段,那么该目标表字段就依赖于该源表字段,故字段和字段之间就形成了血缘关系,即:形成指标到指标的直接或者间接依赖关系。每一次ETL代码变更,都有可能导致其输出的目标表中的特定指标发生变化,而由于指标之间的依赖关系,这些指标的变化可能会进一步导致其他指标变更。现有技术中,常用的ETL指标变更的检测方法仅查明一个ETL任务中指标变更的原因,而没有利用指标依赖关系进一步查找发生变化的指标,因此现有技术只能发现当前ETL任务的目标表指标变更,而无法通过指标依赖关系查找检测到其影响到的其他指标的变更。请参考图3,其为本申请的ETL中指标变更的检测方法实施例B的具体流程图,实施例B是实施例A的一个优选实施例。在本实施例中,还包括:步骤S301:根据预先存储的指标依赖关系,获取对发生变更的指标有直接或间接依赖关系的指标。本申请所述的指标依赖关系包括整个ETL过程中的各个任务之间的指标依赖关系,如表1所示:父指标子指标B.index_BA.index_A1B.index_BA.index_A2B.index_BA.index_A3……表1、指标依赖关系从表1可以得出:表B中的指标index_B在ETL计算生成的过程中直接或者间接的用到了表A中的index_A1、index_A2、index_A3,即index_B是由指标index_A1、index_A2、index_A3直接或者间接通过SQL指令运算生成的。同理,当指标index_A1、index_A2、index_A3变更了,就有可能会影响到指标index_B。在本实施例中,在步骤S101之前,还包括:步骤S300:初始化所述指标依赖关系。在实际应用中,如果关键指标量不大,可以手工初始化并定期维护指标依赖关系;如果量比较大,可以通过程序解析ETL代码的方式初始化和维护指标依赖关系。请参考图4,其为本申请的ETL中指标变更的检测方法实施例B步骤S300的具体流程图。在本实施例中,所述初始化所述指标依赖关系包括:步骤S3001:针对ETL过程中的每一个ETL任务,获取所述ETL任务包括的数据操作指令。步骤S3002:解析所述数据操作指令,获取各个指标生成语句。步骤S3003:根据所述指标生成语句,获取所述指标生成语句中的目标指标和源指标,并将所述目标指标和源指标之间的关系作为所述指标依赖关系;所述目标指标直接依赖于源指标。在本实施例中,所有定时执行的任务调度或者文件操作等使用LINUX基本命令,脚本方面用到了SHELL、PYTHON等脚本语言,同时还用到了ORACLE的存储过程解析任务脚本,这些都是基于后续实现成本相对较低而选择的。实际应用中,脚本解析部分也可用其他主流的计算机语言或者脚本语言,如:JAVA、PERL等,而数据库也可用其他常见数据库,例如:GREENPLUM、MYSQL等实现数据存储。本申请提供的ETL任务中指标变更的检测方法和装置,基于ETL代码变更触发对目标表指标变更的检测,通过使用事先备份好的数据初始化ETL任务的源表数据,执行变更前的ETL任务和变更后的ETL任务,获取变更前目标表集合和变更后目标表集合相应的数据;并比较变更前目标表集合和变更后目标表集合的共有目标表下同名指标的数据,发现目标表的指标变更以及具体的变更详情,使得当检测到目标表指标变更时,开发人员若想进一步排查指标变更原因,可以不用考虑源数据不一致的问题,直接就可以判断是ETL代码变更导致的。在上述的实施例中,提供了一种ETL任务中指标变更的检测方法,与之相对应的,本申请还提供一种ETL任务中指标变更的检测装置。请参看图5,其为本申请的ETL任务中指标变更的检测装置实施例的示意图。由于装置实施例基本相似于方法实施例,所以描述得比较简单,相关之处参见方法实施例的部分说明即可。下述描述的装置实施例仅仅是示意性的。本实施例的一种ETL任务中指标变更的检测装置,包括:获取单元101,用于获取变更前的ETL任务和变更后的ETL任务;解析单元102,用于解析所述变更前的ETL任务和变更后的ETL任务,生成变更前目标表集合和变更后目标表集合,以及变更前后的所有源表集合,并根据其各自的建表指令进行建表;初始化数据单元103,用于针对每个源表,按照事先备份好的数据进行初始化;执行单元104,用于以上述初始化后的源表为数据来源,分别执行所述变更前的ETL任务的数据操作指令和变更后的ETL任务的数据操作指令,在变更前目标表集合和变更后目标表集合中,分别获得相应的数据;第一比较单元105,用于比较所述变更前目标表集合和变更后目标表集合的共有目标表下同名指标的数据,判断数据是否发生变化,若是,则判断指标发生变更并作出指标变更标识。可选的,所述判断数据是否发生变化,具体是:判断相同目标表中同名指标下的数据量是否发生变化,若是,则对该同名指标作出“数据量发生变化”的标识。可选的,所述判断相同目标表中同名指标下的数据量是否发生变化的步骤中,若判断结果为否,则:以所述相同目标表中的变化前目标表为主表,选择一个具有主键性质的公共指标作为关联字段;通过所述关联字段,将所述变化前目标表与相同目标表中的变化后目标表相关联,比较所述同名指标下的数据值是否发生变化;若是,则对所述同名指标作出“数据值发生变化”的标识。可选的,若所述比较所述同名指标下的数据值是否发生变化的步骤中,判断结果为是,则找出主键指标的至少一个数据值,并在所述变化前目标表中找出对应所述数据值的所述同名指标的数据值作为变化前数据值,以及在所述变化后目标表中找出对应所述数据值的所述同名指标的数据值作为变化后数据值;将所述共有指标标识为:在所述主键指标为所述数据值时,所述共有指标的值从所述变化前数据值变成所述变化后数据值。可选的,还包括:第二比较单元,用于比较所述变更前目标表集合和所述变更后目标表集合的共有目标表;标识下线单元,用于找出变更前共有目标表中包含而变更后共有目标表不包含的指标集合,这些指标为被下线指标集合。可选的,其特征在于,还包括:获取依赖单元,用于根据预先存储的指标依赖关系,获取对发生变更的指标有直接或间接依赖关系的指标。可选的,还包括:初始化关系单元,用于初始化所述指标依赖关系。可选的,所述初始化关系单元包括:获取子单元,用于针对ETL过程中的每一个ETL任务,获取所述ETL任务包括的数据操作指令;解析子单元,用于解析所述数据操作指令,获取各个指标生成语句;生成子单元,用于根据所述指标生成语句,获取所述指标生成语句中的目标指标和源指标,并将所述目标指标和源指标之间的关系作为所述指标依赖关系;所述目标指标直接依赖于源指标。本发明虽然以较佳实施例公开如上,但其并不是用来限定本发明,任何本领域技术人员在不脱离本发明的精神和范围内,都可以做出可能的变动和修改,因此本发明的保护范围应当以本发明权利要求所界定的范围为准。在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flashRAM)。内存是计算机可读介质的示例。1、计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括非暂存电脑可读媒体(transitorymedia),如调制的数据信号和载波。2、本领域技术人员应明白,本申请的实施例可提供为方法、系统或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例或结合软件和硬件方面的实施例的形式。而且,本申请可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。当前第1页1 2 3 当前第1页1 2 3 
当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1