一.场景描述

数据库为ASCII编码单字节存储,在查询中文时可能会出现错误结果。例如查询like“房”字,会查询出不含“房”,含“朔科”的结果。

select * from Tablename01 where name like '%房%';

二.原因分析

一个汉字为2个字符,“朔”的第二个字节与“科”的第一个字节,正好与“房”的两个字节相同。查看十六进制,如下:

select  char2hexint('房');  --00B7 00BF
select char2hexint('朔科'); --00CB 00B7 00BF 00C6

三.解决方案

1.安装部署自定义函数chs_instr

chs_instr(参数1,参数2)是一个C编写的自定义函数,它的功能是在参数1中查找参数2,按照参数2的字节数去查找,如果查询不到则返回0,查询到则返回大于0的值。

经查在Teradata库中,使用此UDF函数与like比较,IO数基本不变,CPUTime突增近100倍。所以,遇到此类问题时,优先考虑从设计层面规避like中文。

2.语句【name like ‘%房%’】替换成【chs_instr(name,'房')>0】

四.UDF安装部署

Teradata支持C语言的自定义函数。具体部署方法如下:

1、如下UDF存储到文件中,文件名称为chs_instr.udf

/*
database syslib;
replace FUNCTION chs_instr(srcStr VARCHAR(1024), childStr VARCHAR(64))
RETURNS INTEGER
LANGUAGE C
NO SQL
PARAMETER STYLE TD_GENERAL
EXTERNAL NAME chs_instr;
sel chs_instr('弢1234|', '|');
sel index('弢1234|', '|');
*/

2、如下为UDF定义中引用的C函数,文件名称为chs_instr.c

#define SQL_TEXT Latin_Text
#include <sqltypes_td.h>
#include <string.h>
/* Result is 0, if search_str does not apper in source_string */
/* index, a pos(start at 1) to the firt occurrence of search_str of source_string */
void chs_instr(VARCHAR_LATIN *source_string,VARCHAR_LATIN *search_str,
int *result,
char sqlstate[])
{
unsigned char *src = source_string, *sub = search_str, c;
int sublen = strlen(sub);
int slen = strlen(src);
int spos = ;
*result = ;
while ( spos <= slen-sublen ) {
if (memcmp(src+spos, sub, sublen) == ) {
*result = spos+;
break;
}
c = src[spos++];
if (c > ) spos++;
}
return;
}

3、使用bteq登录数据库(dbc用户),指定UDF默认存储数据库为syslib。

bteq "logon citic/dbc,dbc" < chs_instr.udf

附录:memcmp函数是按字节比较的。

s1,s2为字符串时候memcmp(s1,s2,1)就是比较s1和s2的第一个字节的ascII码值;
memcmp(s1,s2,n)就是比较s1和s2的前n个字节的ascII码值;
如:char *s1="abc";
char *s2="acd";
int r=memcmp(s1,s2,3);
就是比较s1和s2的前3个字节,第一个字节相等,第二个字节比较中大小已经确定,不必继续比较第三字节了。所以r=-1.

【Teradata UDF】中文按字符查找chs_instr的更多相关文章

  1. js 中文长字符截短&关键字符隐藏 自定义过滤器

    两个非常简单的过滤器:隐藏关键字符和字符截短.同样也可以迁移到ng和原生js直接使用(去掉avalon.filters声明即可).后期还有不错的过滤器,还往这里面加 keyword:avalon,js ...

  2. SQL Server判断某个字段是否包含中文/英文字符/数字

    原文:SQL Server判断某个字段是否包含中文/英文字符/数字 因最近在清理系统中的脏数据,需要查询某个字段是否包含中文/英文字符/数字的数据, 比较简单,仅以此篇博客做一个简单总结,方便以后查阅 ...

  3. python对不同类型文件(doc,txt,pdf)的字符查找

    python对不同类型文件的字符查找 TXT文件: def txt_handler(self, f_name, find_str): """ 处理txt文件 :param ...

  4. Oracle instr() 字符查找函数

    instr()函数的格式  (俗称:字符查找函数) 格式一:instr( string1, string2 )    /   instr(源字符串, 目标字符串) 格式二:instr( string1 ...

  5. 【Teradata UDF】MD5加密

    使用参考:Teradata自定义函数UDF(chs_instr) 源码下载:百度网盘链接

  6. 【mysql】利用全文索引实现中文的快速查找

    现在我们数据库表中的记录大约在17万,每一条记录都有name字段,根据name做模糊匹配,效率非常低下. 表结构如下: create table T ( id int, name ) ); 总数据量如 ...

  7. 如何在windows的DOS窗口中正常显示中文(UTF-8字符)

    打开CMD.exe命令行窗口,通过 chcp命令改变代码页 UTF-8的代码页为65001,ANSI/OEM - 简体中文 GBK为936,window default OEM - 美国为437 如果 ...

  8. python利用utf-8编码判断中文英文字符(转)

    下面这个小工具包含了判断unicode是否是汉字.数字.英文或者其他字符,全角符号转半角符号,unicode字符串归一化等工作. #!/usr/bin/env python # -*- coding: ...

  9. python(40):利用utf-8编码判断中文英文字符

    #!/usr/bin/env Python # -*- coding:GBK -*- """汉字处理的工具: 判断unicode是否是汉字,数字,英文,或者其他字符. 全 ...

随机推荐

  1. JDK1.8 ConcurrentHashMap源码阅读

    1.  带着问题去阅读 为什么说ConcurrentHashMap是线程安全的?或者说 ConcurrentHashMap是如何防止并发的? 2.  字段和常量 首先,来看一下ConcurrentHa ...

  2. C#版 - Leetcode 191. Number of 1 Bits-题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  3. Solr 11 - Solr集群模式的部署(基于Solr 4.10.4搭建SolrCloud)

    目录 1 SolrCloud结构说明 2 环境的安装 2.1 环境说明 2.2 部署并启动ZooKeeper集群 2.3 部署Solr单机服务 2.4 添加Solr的索引库 3 部署Solr集群服务( ...

  4. 写在最前面 - 《看懂每一行代码 - kubernetes》

    我要写什么 <看懂每一行代码 - kubernetes>会包含k8s整个项目的源码解析,考虑到门槛问题,在开始分析k8s之前我会通过一些更低难度的golang开源项目讲解来帮助大家提升go ...

  5. 适配器模式 adapter 结构型 设计模式(九)

    现实世界中的适配器模型   先来看下来几个图片,截图自淘宝 上图为港版的插头与港版的插座   上图为插座适配器卖家的描述图   上图为适配后的结果 现实世界中适配器模式 角色分类 这就是适配器模式在电 ...

  6. 只需要4步就可以将asp.net mvc变成SPA(单页面)应用,实现无刷新页面切换!

    SENNA.js Senna.js是一个超快速的单页面应用程序引擎,轻松构建基于Web的现代应用程序,只有大约8KB的JavaScript而没有任何依赖性.还提供非常酷炫的动画效果.想要详细了解的朋友 ...

  7. 初识TensorFlow

    在前边几期的文章中,笔者已经用TensorFlow进行的一些基础性的探索工作,想必大家对TensorFlow框架也是非常的好奇,本着发扬雷锋精神,笔者将详细的阐述TensorFlow框架的基本用法,并 ...

  8. 解读经典《C#高级编程》第七版 Page94-100.继承.Chapter4

    前言 今天,我们开始进入第四章的解读.本章讲的是继承.要做稍微复杂一些的开发,便不可避免的会使用到继承.本篇文章我们主要解读"实现继承". 另外,从本文开始,我开始使用Markdo ...

  9. VisualStudio移动开发(C#、VB.NET)Smobiler开发平台——VoiceRecorder控件的使用方式.Net移动开发

    一.          样式一 我们要实现上图中的效果,需要如下的操作: 从工具栏上的“Smobiler Components”拖动一个VoiceRecorder控件和一个ImageButton控件到 ...

  10. 第1章 背景 - Identity Server 4 中文文档(v1.0.0)

    大多数现代应用程序或多或少看起来像这样: 最常见的互动是: 浏览器与Web应用程序通信 Web应用程序与Web API进行通信(Web应用程序自身 或 代表用户 与 Web API 通信) 基于浏览器 ...