免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4911 | 回复: 8
打印 上一主题 下一主题

请问:如何在RPGLE中实现中文的模糊查询? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-02-18 15:29 |只看该作者 |倒序浏览
找了一下,以前有人发起过同样的提问,但没看到具体的可行方法。(也可能是我过于愚钝,没看明白
(引用以前的那个帖子的问题是这样的:
例如公司名字段为xxcomp,其中数据有
1.中国劲量电池科技有限公司
2.中国旺盛电子有限公司
3.和仁旺盛电测仪器厂
搜索条件输入“中国”,确定后,则显示1,2条记录
搜索条件输入“旺盛”,确定后,则显示2,3条记录
搜索条件输入“电”,确定后,则显示1,2,3条记录)

我想问两个问题:
1.使用SQLRPGLE实现的话,例如SELECT * FROM pf WHERE xxcomp LIKE '%'||'中国'||'%'
因为搜索条件“中国”是不确定的,是随便输入的两个汉字,那应该占6个字符长,那如何在SQLRPGLE中去掉0E0F,准确的实现这个SQL语句?
2.如果使用SCAN实现,也是同样的问题,如何去掉0E0F?另外,SCAN操作一般只针对单字节,这种情况可行吗?

请各位高手指点迷津,如果哪位高人做过类似的功能,请详细的说一下,谢谢!

论坛徽章:
0
2 [报告]
发表于 2010-02-18 18:20 |只看该作者
对第一个问题,可以做个动态的sql,把SELECT....放在一个文本中,类似“中国”的查询条件可以组合到这个select语句中,然后在程序中执行select。

对第二个问题,在400下,scan对单双字节都有效。如果scan操作,如果是查找的key要输入“中国”,无论是系统输入还是外部带入的值,系统都会用0E0F把“中国”框起来,对显示是“中国”;对运算是16进制的代码。另一方面,系统会自动根据查找的信息key的16进制代码值查找搜索字段,遇到0E时,系统就会根据pf的ccsid转换0E后的16进制的代码,直到0F。接着搜索key的“中国”的16进制代码scan被检索的字段内容。

论坛徽章:
0
3 [报告]
发表于 2010-02-18 22:30 |只看该作者
对第一个问题,可以做个动态的sql,把SELECT....放在一个文本中,类似“中国”的查询条件可以组合到这个sel ...
passthru 发表于 2010-02-18 18:20


可能是我能力不够,您的回答我都没理解.
第一个问题,我问的不是如何制作动态sqlrpgle程序,我问的是如何将六位字节长的变量,改为像sql 语句中的那种4位字节长的"中国"
第二个问题,您的意思是说可以直接使用scan吗?能用具体语句说的具体点吗?因为之前我试过,不可行.

谢谢指教!

论坛徽章:
0
4 [报告]
发表于 2010-02-19 13:03 |只看该作者
在400下,如果用的双字节字符,IBM都按语种归类于一个‘字符集’用ccsid标识。‘中国’放在400内执行,就必须用0E0F来框定。如果sql语句从前端应用进入,400 OS下的转换接口就会根据ccsid标识,自动用0E0F对双字节的内容,进行框定和转换成这个字符集中对应的16进制代码。4字节的“中国”在400中是不存在的。

论坛徽章:
0
5 [报告]
发表于 2010-02-19 13:33 |只看该作者
本帖最后由 JmLei 于 2010-02-19 13:36 编辑

回复 1# SAXONBABY


1) SQL
  1. /free                                                                    
  2.    xxDES = %subst('%'+(%trim(X1DES) +                                    
  3.             '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'):1:52) ;
  4. /end-free

  5. SELECT * FROM pf WHERE xxcomp LIKE :xxDES
复制代码
2) Scan

http://blog.csdn.net/jmlei/archive/2009/02/05/3863606.aspx

论坛徽章:
0
6 [报告]
发表于 2010-02-20 15:05 |只看该作者
可能是我能力不够,您的回答我都没理解.
第一个问题,我问的不是如何制作动态sqlrpgle程序,我问的是如何 ...
SAXONBABY 发表于 2010-02-18 22:30



    对于第二个问题,要将“中国”两边的0E0F去掉再scan

论坛徽章:
0
7 [报告]
发表于 2010-02-20 16:16 |只看该作者
对于第二个问题,要将“中国”两边的0E0F去掉再scan
wrgpmf 发表于 2010-02-20 15:05



    概念都错了。

   用scan之前,os会对0eof框起来的“中国”根据jobd的ccsid到字符集中找出对应的16进制代码,再进行操作。

  如果把“中国”两个字,先转换为4个16进制代码,再scan是可以。0e0f在操作码中的作用,是OS根据jobd的ccsid,转换内容对应的16进制代码。

论坛徽章:
0
8 [报告]
发表于 2010-02-20 22:12 |只看该作者
本帖最后由 passthru 于 2010-02-20 22:20 编辑

《如何在RPGLE中实现中文的模糊查询?》是个较复杂的问题。400/DB2有两个引擎,RPG下使用的是CQE引擎。SQL语句,如select,是使用SQE引擎。我们都知道在rpg下对pf进行快速检索定位需用到这个PF下的LF。如果key字段是LF的键值,就能快速定位;如果key字段不是LF的键值,只能遍历PF操作。或者,定位之前创建一个queryfile,或程序描述文件。SQL操作也是这样,如果where的字段在index的范围内,就能快速定位,否则只能遍历from的文件。

《如何在RPGLE中实现中文的模糊查询?》如果key值不在LF的键值范围内,只能用Q类的API进行操作,RPGLE代码比较复杂,是可行的。但是比遍历PF快速。

前一段时间,我们做过一个测试,一个外部java的SQL对400/db2的pf进行查询操作,对百万级记录的pf进行稍微复杂的操作,需6分钟。转化为RPGLE,即CQE对400/DB2的操作,只需230毫秒,即0.23秒。性能相差如此之大。

论坛徽章:
0
9 [报告]
发表于 2010-02-23 15:34 |只看该作者
在5.2版本中如果使用SQL建表并制定字段属性为CCSID 65535,是可以使用中文的模糊查询的但如果使用DDS建表,利用field level keyword来制定字段属性为CCSID
(65535),则无法使用中文的模糊查询,原因是0E/0F控制码也被当作普通字符使用。

例如
R TEST
--NAME --A(20)-- CCSID(65535)

建立PF文件QGPL/TEST

INSERT INTO QGPL/TEST VALUES('中华人民共和国')

使用QUERY进行模糊查询
SELECT * FROM QGPL/TEST WHERE NAME LIKE '中%‘
系统返回0行纪录

如果要实现对65535字段的模糊查询,必须修改QUERY的写法:
SELECT * FROM QGPL/TEST WHERE HEX(NAME) LIKE SUBST(HEX('中'),1,3)||'%'
返回的结果为
--------中华人民共和国
返回结果正确。

这里充分考虑了在单字节环境下对简体中文的处理过程,即把一个双字节字符(加上0E/0F控制码)当作4个字节来处理,而这些字节包含的数据是无法在单字节环境下正确解析的。所以,必须使用16进制的方式来处理。

如果用户要检索的是“中华“,则检索的条件必须写成:
SELECT * FROM QGPL/TEST WHERE HEX(NAME) LIKE SUBST(HEX('中'),1,5)||'%'

因为0E/0F只出现在双字节字符串的开头和结尾,所以两个汉字需要检索的字符个数是5个。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP