ORACLE判别字段是否包含中文(P1)或中文包含非中文(P2)

Part.1 ORACLE判别字段是否包含中文


在ORACLE数据库中如何查找那些字段里面包含中文的数据记录呢,有时候就是有这样的特殊需求,下面整理了一些判别字段中包含中文记录的几个方法

 

1:使用ASCIISTR函数判别

 

ASCIISTR函数说明:

ASCIISTR返回字符的ASCII形式的字符串。非ASCII的字符被转化为\xxxx的形式。

使用ASCIISTR函数也是根据非ASCII字符会被转化这个特性来判别中文字符,只要里面包含中文字符,则必定会有\xxx这样的字符。且简体汉字的编码范围是B0A1 - F7FE.如下例子所示

CREATE TABLE TEST
(
    NAME_ONE   CHAR(24)
   ,NAME_TWO   VARCHAR2(24)
   ,NAME_THR   NCHAR(24)
   ,NAME_FOR   NVARCHAR2(24)
)
 
INSERT INTO TEST
SELECT 'abc10', 'abc20', 'abc30', 'abc40'         FROM DUAL UNION ALL
SELECT 'abc11', 'abc21', 'abc31', 'abc41'         FROM DUAL UNION ALL
SELECT 'abc12', 'abc22', 'abc32', 'abc42'         FROM DUAL UNION ALL
SELECT 'abc1!', 'abc2!', 'abc3!', 'abc4!'         FROM DUAL UNION ALL
SELECT 'abc1#', 'abc2#', 'abc3#', 'abc4#'         FROM DUAL UNION ALL
SELECT 'abc1$', 'abc2$', 'abc3$', 'abc4$'         FROM DUAL UNION ALL
SELECT 'ab测试1', 'ab测试2', 'ab测试3', 'ab测试4' FROM DUAL;

clip_image001

使用 ASCIISTR(NAME_ONE) LIKE '%\%' 就能判别那些有中文的记录。如下所示:

SELECT NAME_ONE FROM TEST WHERE ASCIISTR(NAME_ONE) LIKE '%\%' 

但是如果字段里面的非ASCII字符不仅仅有中文,例如还有日文之类,那么这个方法就不能准确判别了,如下所示,我插入一条包含日文的记录.

INSERT INTO TEST
 
SELECT 'abこんにちは1', 'abこんにちは2', 'abこんにちは3', 'abこんにちは4' FROM DUAL;
 
COMMIT;
 
 
SQL> SELECT NAME_ONE FROM TEST WHERE ASCIISTR(NAME_ONE) LIKE '%\%';
 
NAME_ONE
------------------------
ab测试1
abこんにちは1

 

2:使用CONVERT函数判别(比较有用)

CONVERT函数说明:

CONVERT(inputstring,dest_charset,source_charset)

   inputstring:要转换的字符串

     dest_charset:目标字符集

     source_charset:原字符集

SQL> SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';
 
PARAMETER                      VALUE
------------------------------ ----------------------------------------
NLS_CHARACTERSET               UTF8
 
SQL> SELECT NAME_ONE, NAME_TWO FROM TEST WHERE  NAME_ONE <> CONVERT(NAME_ONE, 'ZHS16GBK', 'UTF8');
 
NAME_ONE                 NAME_TWO                
------------------------ ------------------------ 
ab测试1                  ab测试2                
abこんにちは1            abこんにちは2     

clip_image002

 

3:使用函数length和lengthb来判别

  

    使用函数length与lengthb来判别,是基于中文字符占用2~4个字节,而ASCII字符占用一个字节,那么对比LENGTH与LENGTHB就会不一样。这样就能判别字段中是否包含中文字符,但是跟ASCIISTR一样,如果里面的非ASCI字符包含非中文,它一样不能判别。依然有取巧嫌疑。

SELECT NAME_ONE FROM TEST WHERE LENGTH(NAME_ONE) != LENGTHB(NAME_ONE);

clip_image003

 

关于三者的性能,基本上都差不多,并没有那个性能要快一点。当然我没有详细、大量测试过,只是就某个案例的执行计划分析而已。

 

参考资料:

http://www.bitscn.com/pdb/oracle/201407/240540.html

http://blog.csdn.net/yzsind/article/details/6106050

http://blog.itpub.net/9399028/viewspace-687789

作者: 潇湘隐者

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.

Part.2 

oralce查询字段中包含非中文字符的记录?

0
  悬赏园豆:5 [已解决问题]  浏览: 565次

如题 , 比如只有一个name列的表t1,数据如下:

  name  

  张三2

  李四

  王五*

要查出‘张三2’,‘王五*’两条记录,他们都包含非中文字符。

yanwushu的主页 yanwushu  |  菜鸟二级  | 园豆: 204
提问于:2015-01-24 16:02

问题补充:

更新

-----------------------------------------------------------------

尝试过使用正则表达式:

  select customername from transactionrecord where regexp_like(customername , '[^\u4e00-\u9fa5]')

  但是在oralce中测试无效。可能是由于字符集不同导致的不能工作?


收获园豆: 5
dudu  |  高人七级  |园豆:35631  | 2015-01-24 16:13

感谢你的回答!

这篇文章已经参考过,但是没有找到解决方案,这篇文章是说,判断是否包含【中文字符】,而不是是否包含【非中文】字符。

yanwushu  | 园豆:204  (菜鸟二级)  | 2015-01-24 16:25

@yanwushu: Oracle的SQL中的正则表达式不支持\u,要用unistr,参考Searching Unicode characters in Oracle table

dudu  | 园豆:35631  (高人七级)  | 2015-01-24 16:39

@yanwushu: 也就是:

select customername 
from transactionrecord 
where regexp_like(customername , '[^' || unistr('\4e00') || '-' || unistr('\9fa5') || ']')
dudu  | 园豆:35631  (高人七级)  | 2015-01-24 16:44

@dudu: 感谢你的回答!

问题已经解决,sql如下:

select customername from transactionrecord 
where regexp_like(customername , '[^' ||unistr('\4e00')|| '-' ||unistr('\9fa5')||']');

yanwushu  | 园豆:204  (菜鸟二级)  | 2015-01-24 16:49

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值