kingbase V8(人大金仓数据库) 与 mysql 的 sql 差异对比 与 数据迁移

重置自增id
清空表后无法重置自增id 需要手动重置

alter sequence casecheck.address_abc_id_seq restart with 1;

其中 casecheck.address_abc_id_seq 是表中自增函数的参数值
示例:


空字符串与null
kingbase默认会将空格字符串当做null处理 mysql就不会,为了达到兼容按照顺序执行以下语句
kingbase 设置null与空字符串分别处理:

show ora_input_emptystr_isnull;   --查看空字符串的处理方式  如果为 on 则  空字符串与会当做null处理
alter database casecheck_new set ora_input_emptystr_isnull to 'off';  -- 将此设置关闭
select sys_reload_conf(); --重新载入配置

执行以上语句后重新启动数据库管理工具


substring_index
在kingbase中没有substring_index函数,直接创建

create or replace function public.substring_index(varchar, varchar, int)
returns varchar
as
begin
    if $3 = 0 then return '';
    elsif $3 > 0 then return left($1, instrb($1, $2, 1, $3) - 1);
    else return right($1, instrb($1, $2, -1, abs($3)) - 1);
    end if;
end ;

聚合函数
kingbase使用的是sql3(1999) 在oracle与servicesql 中使用 max,sum,avg 等函时(group by)会出现报错,无法确定未使用聚合函数字段的值
可以在kingbase的配置文件中增加 sql_mode = '' 解决此问题
操作示例:
在服务器寻找 kingbase.conf 配置文件
cd /
find . -name kingbase.conf
vim 目录/kingbase.conf
加入以下配置
sql_mode = ''
然后重启kingbase数据库
重启例子:
重启时需先切换到kingbase的管理账户
us 账户名
找到安装目录下的Server/bin文件夹 在此文件夹下执行一下命令
./sys_ctl -D 目录/data restart
此处的目录是kingbase.conf的位置
例如:kingbase.conf 在以下目录
/opt/Kingbase/ES/V8/data/kingbase.conf
则重启命令为:
./sys_ctl -D /opt/Kingbase/ES/V8/data restart


insert
插入语句必须使用values关键字 没有value关键字

//正确
insert into account(name,age) values('king',32)
//错误
insert into account(name,age) value('king',32)

last_insert_id
kingbase没有last_insert_id 可以在插入语句末尾加入returning [字段名]关键字获取

insert into account(name,age) values('king',33) returning id;

插入成功后返回的结果集中会包含id字段

反引号与双引号

kingbase不支持mysql中的 反引号 与其相对应的是 双引号

mysql中的语法:`name`
kingbase中的语法:"name"

正则表达式
kingbase 正则表达式 与mysql中 的语法不同 :

-- mysql 中的语法:
`name` regexp '^b.*'
-- kingbase 中的语法:
regexp_like("name",'^b.*','i')

字符串包裹
kingbase 与 mysql 字符串差别 mysql中可以使用单引号与双引号包裹 字符串 kingbase只能使用 单引号包裹

-- mysql 中的语法:
insert into `users`(`name`,`context`) values('name',"context")
-- kingbase 中的语法:
insert into "users"("name","context") values('name','context')

类型转换:
-- kingbase不支持类型的隐式转换不通类型中必须手动转换
-- mysql 支持类型的隐式转换
例子:

select casecheck.sm4(casecheck.sm4('123456','123456',0),'123456',1)::varchar

GROUP_CONCAT:
kingbase 使用 group_concat 需要执行以下函数开启扩展

create extension kdb_utils_function;

replace into:

mysql 中 replace into 是根据 唯一约束 进行查找 如果有数据 删除并且插入新数据,没有则直接插入数据。
kingbase 中没有 replace into 需要使用 merge into 替换。 其语句执行结果是: 根据输入的字段作为条件如果含有则修改,没有则插入

具体替换件如下sql:

单字段条件:

merge into "account" a using (select 'acco0004' as account_code) b on (a.account_code = b.account_code)
when matched then update set "name" = 'hello world'
when not matched then insert ("account_code","name") values ('acco0004','hello')

解释:
1."account" 为源表名(要被修改数据的表)
2.(select 'acco0004' as account_code) b 判断重复的虚拟表 其中 'acco0004' 为判断依据(根据实际状况替换) account_code 为自定义字段名 可根据实际状况修改
3.on (a.account_code = b.account_code) 过滤条件 如果 account 表中含有 虚拟表b中 acco0004 的值则进行修改操作 account_code 可根据实际状况修改 可使用and连接多个字段 但字段必须 有唯一约束
4.update set "name" = 'hello world' 如果有则需改 这里只修改了 name 可根据增加替换
5.insert ("account_code","name") values ('acco0004','hello') 如果没有则进行插入

多字段条件:

merge into "account" a using (select 'acco0001' as account_code ,'keyc0001' as key_code) b 
on (a.account_code = b.account_code and a.key_code = b.key_code)
when matched then update set "name" = 'hello world'
when not matched then insert ("account_code","name","key_code") values ('acco0001','hello','keyc0001')

insert ignore into:

mysql 的 insert ignore into 没有数据则插入,有则忽略。

kingbase 没有 insert ignore into 可替换为以下sql:

语句跟replace into差不多 只是缺少了修改:

merge into "account" a using (select 'acco0002' as account_code) b on (a.account_code = b.account_code)
when not matched then insert ("account_code","name") values ('acco0002','hello')

DATE_FORMAT :

kingbase 中的to_char函数与mysql中date_format对应,但第二位的参数有所不同

FIELD:

kingbase中没有 field 函数 要实现此形式提供以下示例参考:

mysql 语句:

SELECT * FROM account ORDER BY FIELD(`name`,'suyoupeng','liushaopeng','huxue','hongjinbao','malong')

kingbase 语句:

SELECT * FROM account ORDER BY case when name = 'suyoupeng' then '0' when name = 'liushaopeng' then '1' when name = 'huxue' then '2' when name = 'hongjinbao' then '3' when name = 'malong' then '4' else name end ,name

Tips:其中 then 后面的值 需要根据 字段 name 的类型进行调整, kingbase 不支持隐式数据转换

concat:

由于kingbase的双引号代表包含字段 如果想让concat以单引号包含字符可以使用以下语法 也兼容mysql

SELECT CONCAT('''','bailong','''')

group by:

kingbase 使用SQL3以前的标准所以在 group by 与mysql的语法相同:

mysql 中group by 用法:

SELECT id,`name`,age,birthday FROM account WHERE age BETWEEN 20 AND 50 GROUP BY `name` ORDER BY birthday

如果在kingbase中也达到同样的结果 请转换为以下的sql

select id,name,age,birthday from casecheck.account where id in (select max(id) from casecheck.account where age between 20 and 50 group by name ) order by birthday desc

解释:

在kingbase使用group by 必须将显示的字段多键入到group by中。这样的话就导致了数据的不准确

在上面的sql语句中 select max(id) from casecheck.account where age between 20 and 50 group by name 如果 id 不使用聚合函数 max 包裹将会报错,

可能的原因是 group by name字段以后 一个name 对应多个id 此时sql引擎不知道应该显示哪个,使用max聚合函数后 sql 就取最大的id的name了。

得到所有符合条件的id后,再以此做为条件 重新检索数据表。

INET_ATON:

mysql 使用例子:

SELECT INET_ATON('192.168.1.90') AS ip

kingbase 不支持 INET_ATON函数 用以下sql替换

select 
    to_number(regexp_replace(ip, '([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})', '\1')) * 16777216 +
    to_number(regexp_replace(ip, '([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})', '\2')) * 65536 +
    to_number(regexp_replace(ip, '([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})', '\3')) * 256 +
    to_number(regexp_replace(ip, '([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})', '\4'))  as ip_number
from
    (SELECT '192.168.1.90' AS ip)

INET_NTOA:
mysql例子:

SELECT INET_NTOA('3232235866') AS ip

kingbase 不支持 INET_NTOA函数 用以下sql替换

SELECT
    trunc(ip/16777216)||'.'|| trunc( MOD(ip, 16777216)/65536) ||'.'|| trunc(MOD(ip,65536)/256)||'.'|| trunc(MOD(ip,256)) AS ip_address
FROM
    (SELECT 3232235866 AS ip);

YEARWEEK:
mysql 获得输入日期是 第几周

SELECT YEARWEEK('2022-01-03',7)

在kingbase中没有yearweek函数使用to_char替换

select to_char(to_date('2022-01-03'),'yyyyww')

aes_encrypt 与 aes_decrypt 函数
kingbase中没有 aes_encrypt 和 aes_decrypt 可以新建函数达到与mysql同样的效果 使用的是 sm4 加密函数
先新建 sm4 函数

-- 新建sm4 函数
create or replace function public.sm4(
    bytea,
    bytea,
    integer
) returns bytea language c immutable parallel SAFE strict as '$libdir/kbcrypto',
$function$sm4$function$;
-- 新建aes_encrypt 函数
create or replace function "public".aes_encrypt(
        varchar ,
        varchar
    ) returns blob as
    declare l_txt blob ;
begin
    select casecheck.sm4($1,$2,0) into l_txt;
    return l_txt;
end ;
-- 新建aes_decrypt函数
create or replace function "public".aes_decrypt(
        blob ,
        varchar
    ) returns blob as
    declare l_txt blob ;
begin
    select casecheck.sm4($1,$2,1) into l_txt;
    return l_txt;
end ;

mysql导入kingbase:

应该分为两步操作

首先导入表结构后 在导入数据 同时导入可能索引创建不成功

导入表结果如下图:

加入json类型映射:

结构导入完毕再执行数据导入 (如下图):

报错问题定位:

导入数据报错合集:

  • ERROR: invalid byte sequence for encoding "UTF8": 0x00

tips:含有中文的数据都有可能出现此错误

解决方式如下:

在源数据库表中找到报错数据

SELECT * FROM `law_item` WHERE `text` LIKE CONCAT("%",CHAR(0),"%");

重新以对应的编码输入文字即可。

  • 没有找到数据类型:json请增加数据类型映射

加入json类型映射即可。

tips:在数据导入中已有解决办法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容