- 软件版本信息
- 问题1:Cognos多数据源生成SQL分段的问题解决方法
- 问题描述
- 问题原因
- 解决方法
- Cognos Framework Manager创建数据源
- Cognos Reprot Studio创建报表
- 问题2:Cognos Transformer导入基于gbase数据源的iqb文件报错
- 问题描述
- 问题原因
- 解决方法
- 问题3:Framework Manager查询包含中文的模型报错
- 问题描述
- 问题原因
- 解决方法
- 问题4: Report Studio 运行报表出现“数据库不支持排序规范,此运算需要在本地处理数据”错误
- 问题描述
- 问题原因
- 解决方法
- 问题5:Framework Manager查询总行数报语法错误
- 问题描述
- 问题原因
- 解决方法(暂时绕行)
- 问题6:cognos性能问题(不能把条件推到数据库处理)
- 问题描述
- 问题原因
- 解决方法
编写背景
民航项目在使用Cognos基于GBase 8a 集群上开发数据模型、报表模型,因Cognos和GBase 8a没有进行产品兼容,在Cognos使用时遇到了一些问题,本文档总结了问题处理过程,供民航项目组技术人员参考使用。
鉴于对Cognos产品功能了解有限,可能Cognos一些配置并不一定是最优配置,但就本文描述的几个问题都可以通过所提供的方法解决,后续如果有更多案例和方法可以进行补充。
|
产品名称 |
版本号 |
|
GBase 8a集群 |
8.6.1.1 build 16.19 UTF8 |
|
Cognos |
10.2.2 |
|
GBase ODBC |
GBaseODBC_8.3.81.53_build53.16_W32 |
Cognos在GBase数据库上开发报表时,发现两表关联生成的SQL是分段的,预期是两表做inner join,关联后生成的数据有 238,124条,对两张表的关联sql直接放在gbase管理器中执行时1~2s即出数据,而cognos报表中需要约125s才能展现结果。生成的本地SQL如下图1所示:
图 1
对比oracle生成的正常SQL如下如图2所示:
图 2
本文档描述了解决该问题的详细步骤。
Cognos对不同数据源的主题进行查询时,会认为这两个数据源是不同的实例,即使两个数据源是同一个库, Cognos仍然会将它们视为不同的实例。因此cognos在生成SQL时无法将联接推到数据库,也即原生 SQL 是没有连接的,是两个独立选择语句,从数据库检索出结果后,两个独立结果集将在 IBM Cognos BI 服务器上进行本地联接,因此效率上也会表现的与预期有差别。
经过资料分析,配置 Framework Manager可以将处理联接查询推到数据库,提升执行的效率。
Cognos Framework Manager创建项目后,建立两个不同数据源的查询主题,本例中两个数据源分别的gbase_dim、gbase_dws,单击gbase_dim,设置该数据源的属性,查询处理选择“仅限于数据库”,Content Manager数据源属性设置为“gbase_dim”,如下图3所示:
图 3
同样,单击gbase_dws,设置该数据源的属性,查询处理选择“仅限于数据库(也可选择仅本地)”,Content Manager数据源属性设置为“gbase_dim”(此处设置的数据源要与gbase_dim一致),如下图4所示:
图 4
查看每个查询主题的SQL,库名.表名的格式,并单击验证通过,如下图5、图6所示,在测试选项卡中,选择“SQL设置”,此处选择“本地”即可,如图7所示。
图 5
图 6
图 7
在Cognos Framework Manager需要建立两表关联关系,如图8所示:
图 8
关联建好后,单击【关系SQL】标签页,单击“测试”按钮,测试能够出来数据即可,如图9所示。
图 9
以上设置完成后,发布数据包,在数据包上单击右键,创建数据包,按照引导一步步创建即可,如图10所示。
图 10
登录http://localhost:9300/p2pd/servlet/dispatch,选择“启动-->IBM Cognos Administration”,找到刚才发布的数据包,选择数据包后,打开“启动-->Report Studio”菜单,进行报表制作,选择“新建—>列表”,打开报表设计页面,选择查询主题中要展示的列到报表页面,如图10所示。
图 11
完成后,单击菜单栏“工具à显示生成的SQL/MDX”,如图11、12所示,查看生成的SQL即是两表关联查询的SQL。
图 12
图 13
如果想显示展示关联SQL则,设置查询1的属性,SQL联结语法为“显示”,如图13所示,生成的本地SQL如图14所示。
图 14
图 15
处理显示“仅数据库”选项,设置完成后单击生成报表按钮,即可查看生成的报表,如图15、16所示。
图 16
图 17
用cognos的工具Transformer连接gbase出现报错问题。
1)导入基于gbase数据源的iqb文件报错如下:
图 18
图 19
2)以基于gbase的FM包作为transformer的数据源时,导入正常,但生成关系时报错
图 20
日志部分内容如下:
cognos配置问题
1. ~\ibm\cognos\c10\CS7Gateways\bin目录下的cognos配置文件中是否正确的添加了GBase8a数据库的链接串
2.数据源ODBC配置里,高级—>其他 ,需要勾选'不支持事务'
使用cognos framework 打开“运输月统计.cpf”,可以看到用户设计的模型,根据数据源名字建立创建库、表、导入数据、创建ODBC数据源,在cognos创建数据源“计算”标签页,可查看响应的SQL,可以看到有中文查询条件,单击测试标签页,单击“测试表样”,报转换字符集错误,如下图所示:
图 21
字符集配置问题。因GBase 8a 集群版本使用的字符集是UTF8,ODBC数据源配置应选择“UTF8”,且cognos创建数据源时应勾选“Unicode ODBC”。
根据GBase 8a集群字符集,设置ODBC数据源字符集,民航集群版本字符集为utf8,因此ODBC应设置为uft8,如下图所示:
图 22
ODBC字符集设置完毕后,需要设置cognos数据源的字符集,勾选“Unicode ODBC”复选框,本步骤如果不设置,中文会显示乱码,设置步骤如下图所示:
图 23
报表制作完成后,单击运行图标,出现如下图所示的错误:
图 24
Cognos配置问题
方法1:修改Cognos Framework数据源的【查询处理】选项为“仅本地”,如下图所示:
图 25
方法2:在Cognos Report Studio设置查询属性“自动排序”,设置成“无”,如下图所示:
图 26
Framework Manager建好主题后,对主题进行测试时,“选项—>SQL设置使用本地SQL”时,执行“总行数”链接,报语法不支持,如下图所示:
图 27
查看GBase 8a 审计日志audit_log表发现,cognos 下发给GBase 8a集群的SQL如下,主要是congnos工具对GBase 8a数据库的支持不好,目前只能修改公司产品的ODBC接口驱动代码中的关键字,伪装成mysql用于和congnos进行联调,mysql的语法相对宽松,而GBase 8a语法要求严格,因此报错语法不支持的问题。
|
select `CountResultQuery8`.`C_2` as "Count1" from (select count(`aBmtQuerySubject7`.`半年名称`) as "C_1" , count(1) as "C_2" from (select `日期`.`dt_y` as "年" , `日期`.`dt_m` as "月" , `日期`.`dt_d` as "日" , `日期`.`dt_q_s` as "季度" , `日期`.`dt_hy` as "半年" , case when `日期`.`dt_q_s` = N'Q1' then N'一季度' when `日期`.`dt_q_s` = N'Q2' then N'二季度' when `日期`.`dt_q_s` = N'Q3' then N'三季度' when `日期`.`dt_q_s` = N'Q4' then N'四季度' end as "季度名称" , case when `日期`.`dt_hy` = N'Y1' then N'上半年' when `日期`.`dt_hy` = N'Y2' then N'下半年' end as "半年名称" from (Select dt_y, dt_m, dt_d, dt_q_s, dt_hy from dim.etl_date where
dt_m between '200001' and date_format(current_date ,'%Y%m')) `日期`) `aBmtQuerySubject7` having count(*) > 0) `CountResultQuery8` |
需要查看“总行数”时,在“测试à选项àSQL设置”,SQL类型选择为“Pass-Throught”,此时查询总行数可正常执行,查询完毕后,SQL类型修改为“本地”。
图 28
执行报表时发现结果集很少的报表,最终展示都需要等待15S以上,即使报表是空结果集,查询也很慢。
通过开启GBase 8a 的审计日志audit_log,分析cognos发过来SQL,发现SQL是没有报表中选择的过滤条件,cognos根据此SQL拿到的结果集比较大(52万条),cognos拿到结果集后利用cognos内部的过滤机制进行处理,最后展现结果。
通过以上过程可看出问题的原因:cognos并没有直接把最终带过滤条件的SQL发给GBase,因此解决cognos正确发送SQL给GBase,使过滤在数据库执行,即可解决本问题。
查看报表中过滤条件有“单位性质”,而最终报表中没有“单位性质”这列的显示,此时cognos生成SQL时不会添加“单位性质”的过滤条件,如下图29所示:
图 29
通过Report Studio“工具à显示生成的SQL/MDX”可查看生成的SQL,如下所示,标红的条件中并没有“单位性质”的条件,同时在GBase的审计日志audit_log中也可查到本条SQL。
|
select `日期9`.`dt_y`, `航线8`.`hxfl`, `日期9`.`dt_m`, `航线8`.`hx_code`, `航线8`.`hx_name`, `运输月统计基础表10`.`hbl`, `运输月统计基础表10`.`lkysl`, `运输月统计基础表10`.`kgzw`, `运输月统计基础表10`.`lkkgl`, `运输月统计基础表10`.`zdkgl`, `运输月统计基础表10`.`客座率`, `航线8`.`航线分类名称` from ( select `航线`.`hx_code` as "hx_code" , `航线`.`hx_name` as "hx_name" , `航线`.`hxfl` as "hxfl" , case when `航线`.`hxfl` = N'DOM' then N'国内' when `航线`.`hxfl` = N'REG' then N'地区' when `航线`.`hxfl` = N'INT' then N'国际' end as "航线分类名称" from (Select hx_code, hx_name, hxjc, hxfl from dim.route) `航线`) `航线8`, ( select distinct `日期`.`dt_y` as "dt_y" , `日期`.`dt_m` as "dt_m" from (Select dt_y, dt_m, dt_d, dt_q_s, dt_hy from dim.etl_date where dt_m between '200001' and date_format(current_date ,'%Y%m')) `日期`) `日期9`, ( select `运输月统计基础表`.`ft_date` as "ft_date" , `运输月统计基础表`.`hx` as "hx" , `运输月统计基础表`.`hbxz` as "hbxz" , `运输月统计基础表`.`hbl` as "hbl" , `运输月统计基础表`.`kgzw` as "kgzw" , `运输月统计基础表`.`lkysl` as "lkysl" , `运输月统计基础表`.`lkkgl` as "lkkgl" , `运输月统计基础表`.`zdkgl` as "zdkgl" , case when `运输月统计基础表`.`lkkgl` / nullif(`运输月统计基础表`.`zdkgl`, 0) <= 1 then `运输月统计基础表`.`lkkgl` / nullif(`运输月统计基础表`.`zdkgl`, 0) else `运输月统计基础表`.`zdkgl` / nullif(`运输月统计基础表`.`lkkgl`, 0) end as "客座率" from (Select ft_date, dw_ft, dw_code, fxd_ft, hxfl, hx, hbh, hbxz, jx, jh, hdfl, hbl, kgzw, lkysl, lkkgl, zdkgl, hbl_tq, lkysl_tq, lkkgl_tq, zdkgl_tq, kgzw_tq from dws.yy_base_m) `运输月统计基础表`) `运输月统计基础表10`, (Select hbxz_code, hbxz_name from dim.flight_nat) `航班性质` where `航班性质`.`hbxz_code` = `运输月统计基础表10`.`hbxz` and `日期9`.`dt_m` = `运输月统计基础表10`.`ft_date` and `航线8`.`hx_code` = `运输月统计基础表10`.`hx` and `运输月统计基础表10`.`kgzw` <> 0 and `运输月统计基础表10`.`zdkgl` <> 0 and `运输月统计基础表10`.`lkkgl` <> 0 and `航班性质`.`hbxz_code` in (N'W/Z', N'Z/P', N'E/A', N'T/C') |
确认以上问题是由于“单位性质”查询条件没有在列表中显示的问题,把“单位性质”加到列表中,生成的SQL有过滤条件,展示行能在5-8S之间,解决了问题。
但如果最终的报表不需要显示“单位性质”这列,需要通过以下步骤解决。
首先,在Report Studio中找到列表相关的查询,查看该查询检索的数据项是否包含“单位性质”,如图30所示。本例中该查询并没有包含“单位性质”,因此,需要在物理视图中添加“单位性质”到查询1中,如图31所示。
图 30
图 31
其次,在页面设计中选择报表,在左侧的报表属性中找到【属性】项,单击弹出属性列,把刚才的“单位性质”复选框选中,单击确定按钮,如下图所示
图 32
最后,通过Report Studio“工具à显示生成的SQL/MDX”可查看生成的SQL,可以看一下标红的筛选条件,同时在GBase的audit_log进行跟踪,验证cognos发送的SQL正常,同时报表基本在5-8S之间可以出来展示结果(最终结果在2万条左右,数据量增大时间会延长,属于正常情况)。
图 33
|
select `航线10`.`hxfl` as "C0" , `航线10`.`hx_code` as "C1" , `航线10`.`hx_name` as "C2" , `运输月统计基础表11`.`hbh` as "C3" , min({fn CONCAT(`运输月统计基础表11`.`dw_ft`, `运输月统计基础表11`.`hbh`)}) as "C4" , `机型`.`jx_code` as "C5" , sum(`运输月统计基础表11`.`hbl`) as "C6" , sum(`运输月统计基础表11`.`kgzw`) as "C7" , `日期13`.`dt_m` as "C8" , `日期13`.`dt_y` as "C9" , `单位飞行队14`.`单位性质` as "C10" , min(`航线10`.`航线分类名称`) as "C11" , min(`机型`.`jx_name`) as "C12" from (select `航线`.`hx_code` as "hx_code" , `航线`.`hx_name` as "hx_name" , `航线`.`hxfl` as "hxfl" , case when `航线`.`hxfl` = N'DOM' then N'国内' when `航线`.`hxfl` = N'REG' then N'地区' when `航线`.`hxfl` = N'INT' then N'国际' end as "航线分类名称" from (Select hx_code, hx_name, hxjc, hxfl from dim.route) `航线`) `航线10`, (Select ft_date, dw_ft, dw_code, fxd_ft, hxfl, hx, hbh, hbxz, jx, jh, hdfl, hbl, kgzw, lkysl, lkkgl, zdkgl, hbl_tq, lkysl_tq, lkkgl_tq, zdkgl_tq, kgzw_tq from dws.yy_base_m) `运输月统计基础表11`, (Select jx_code, jx_name from dim.air_type) `机型`, (select distinct `日期`.`dt_y` as "dt_y" , `日期`.`dt_m` as "dt_m" from (Select dt_y, dt_m, dt_d, dt_q_s, dt_hy from dim.etl_date where dt_m between '200001' and date_format(current_date ,'%Y%m')) `日期`) `日期13`, (select `单位飞行队`.`fxd_ft` as "fxd_ft" , case when `单位飞行队`.`gxlx` = N'1' then N'报送单位' when `单位飞行队`.`gxlx` = N'2' then N'报表单位' when `单位飞行队`.`gxlx` = N'3' then N'法人单位' when `单位飞行队`.`gxlx` = N'4' then N'年报单位' end as "单位性质" from (Select jt_code, jt_name, dw_code, dw_ft, dw_name, fxd_ft, fxd_name, gxlx from dim.dwfxd_rs where gxlx = ('2')) `单位飞行队`) `单位飞行队14`, (Select hbxz_code, hbxz_name from dim.flight_nat) `航班性质` where `航班性质`.`hbxz_code` in (N'W/Z', N'Z/P', N'E/A', N'T/C') and `日期13`.`dt_m` = N'201601' and `航线10`.`hxfl` = N'REG' and `日期13`.`dt_y` = N'2016' and `航线10`.`hx_code` = `运输月统计基础表11`.`hx` and `日期13`.`dt_m` = `运输月统计基础表11`.`ft_date` and `单位飞行队14`.`fxd_ft` = `运输月统计基础表11`.`fxd_ft` and `航班性质`.`hbxz_code` = `运输月统计基础表11`.`hbxz` and `机型`.`jx_code` = `运输月统计基础表11`.`jx` group by `航线10`.`hxfl`, `航线10`.`hx_code`, `航线10`.`hx_name`, `运输月统计基础表11`.`hbh`, `机型`.`jx_code`, `日期13`.`dt_m`, `日期13`.`dt_y`, `单位飞行队14`.`单位性质` |
对于单表简单查询,可能根据以上方法也无法使查询条件下发至数据库层,可通过对数据项定义if .....else......或case ......when......句型结构的方式,达到表达式下发的目的。




