重置自增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:在数据导入中已有解决办法