
前言


1、高度兼容MySQL语法:
基础SQL语法(DML/DDL/DCL)
常用数据类型(包括BLOB/TEXT等)
事务隔离级别和锁机制
字符集和排序规则
常用系统函数和运算符
存储引擎特性(部分兼容InnoDB特性)

开启体验之旅


插件uuid-ossp加载方式
create extension uuid-ossp;uuid-ossp 是金仓数据库(KingbaseES)中用于生成UUID(通用唯一标识符)的扩展模块,基于PostgreSQL的uuid-ossp扩展实现。--查看扩展信息SELECT * FROM sys_available_extensions WHERE name = ‘uuid-ossp’;

uuid_generate_v1() 基于时间戳和MAC地址生成UUID
示例:SELECT uuid_generate_v1();

示例:SELECT uuid_generate_v3(uuid_ns_url(), ‘example.com’);



关于语句:
COMMENT ON TABLE employees IS ‘公司员工信息表’;
原因 :直接通过SQL 在字段后添加 COMMENT 的方式,在KingbaseMysql中是被禁止的
其他基础数据不做过多展示,接下来我们继续体验:
4、使用 @ 指定变量名
在金仓数据库(KingbaseES)中,使用 @ 符号指定变量名是PL/SQL和SQL语句中的常见做法。以下是详细使用方法:
测试原因:因为之前内部测试使用,在KESV8版本该方式使用会报错
但是下边是在KingbaseES V009R003C011(Mysql兼容版中执行)
测试1.在SQL查询中使用变量


测试2.在SQL查询中使用变量– 声明变量DECLARE@user_count INT;@max_salary DECIMAL(10,2);BEGINSELECT COUNT(*) INTO @user_count FROM users;SELECT MAX(salary) INTO @max_salary FROM employees;PRINT '用户总数: ’ || @user_count;PRINT '最高薪资: ’ || @max_salary;END;

DO $$DECLAREuser_count INT;max_salary DECIMAL(10,2);BEGINSELECT COUNT(*) INTO user_count FROM users;SELECT MAX(salary) INTO max_salary FROM employees;RAISE NOTICE ‘用户总数: %’, user_count;RAISE NOTICE ‘最高薪资: %’, max_salary;END $$;

测试3. 在存储过程中使用变量
CREATE OR REPLACE PROCEDURE update_employee_salary(@emp_id INT, @increase_percent DECIMAL(5,2))
AS
BEGIN
UPDATE employees
SET salary = salary * (1 + @increase_percent/100)
WHERE id = @emp_id;
PRINT '员工ID ’ || @emp_id || ’ 的薪资已更新,涨幅 ’ || @increase_percent || ‘%’;
END;

改写脚本:
CREATE OR REPLACE PROCEDURE update_employee_salary(
p_emp_id VARCHAR(36),
p_increase_percent DECIMAL(5,2)
)
LANGUAGE plpgsql
AS $$
BEGIN
– 更新员工薪资
UPDATE employees
SET salary = salary * (1 + p_increase_percent/100)
WHERE id = p_emp_id;
-- 输出消息(金仓数据库使用RAISE NOTICE替代PRINT)
RAISE NOTICE '员工ID % 的薪资已更新,涨幅 %%%', p_emp_id, p_increase_percent;
END$$;
– 调用存储过程
CALL update_employee_salary(‘6a3a8b40-9c3a-11ed-a8fc-0242ac120002’, 10.0);

1.变量声明:
不使用@符号前缀
基本格式:变量名 数据类型;
2.代码块结构:
使用DO $$ … $$包装匿名代码块
或使用CREATE FUNCTION/PROCEDURE创建命名程序
3.输出信息:
使用RAISE NOTICE替代PRINT
格式:RAISE NOTICE ‘消息模板’, 变量;
4.变量赋值:
INTO子句用于将查询结果赋给变量
也可以使用:=直接赋值:user_count := 100;
5、关于INSERT IGNORE体验使用
– 使用IGNORE忽略重复键错误
INSERT IGNORE INTO public.employees (id, emp_code, emp_name, gender, department_id, hire_date)
VALUES (uuid()::uuid, ‘EMP001’, ‘张三’, ‘M’, 1, ‘2023-01-15’);

– 使用LIMIT限制更新行数
UPDATE employees SET salary = salary * 1.1 WHERE department_id = 1 LIMIT 5;
6、关于INSERT ON DUPLICATE KEY UPDATE体验使用
INSERT INTO employees (id, emp_code, emp_name, gender, department_id, hire_date)
VALUES (uuid_generate_v4(), ‘EMP001’, ‘张三’, ‘M’, 1, ‘2023-01-15’)
ON DUPLICATE KEY UPDATE emp_name = VALUES(emp_name), department_id = VALUES(department_id);

7、DML error logging体验使用
– 创建错误日志表
CREATE TABLE err_employees (
id VARCHAR(36),
emp_code VARCHAR(20),
emp_name VARCHAR(50),
err_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
err_msg VARCHAR(2000)
);
– 带错误日志记录的INSERT
INSERT INTO employees (id, emp_code, emp_name, gender, department_id, hire_date)
VALUES (‘invalid-uuid’, ‘EMP002’, ‘李四’, ‘M’, 2, ‘2023-02-20’)
LOG ERRORS INTO err_employees REJECT LIMIT 10;
改写语法:
DO $$
BEGIN
– 尝试插入数据
INSERT INTO employees (id, emp_code, emp_name, gender, department_id, hire_date)
VALUES (‘invalid-uuid’, ‘EMP002’, ‘李四’, ‘M’, 2, ‘2023-02-20’);
EXCEPTION WHEN OTHERS THEN
– 发生错误时记录到错误表
INSERT INTO err_employees (id, emp_code, emp_name, err_msg)
VALUES (‘invalid-uuid’, ‘EMP002’, ‘李四’, SQLERRM);
RAISE NOTICE '插入失败,错误已记录: %', SQLERRM;
END $$;
PS:LOG ERRORS错误日志机制不支持,需采用BEGIN/EXCEPTION块或存储过程实现类似功能
8、REPLACE INTO语句体验使用
– 替换已存在员工记录(基于主键或唯一约束)
REPLACE INTO employees (id, emp_code, emp_name, gender, department_id, hire_date)
VALUES (‘6a3a8b40-9c3a-11ed-a8fc-0242ac120002’, ‘EMP003’, ‘王五’, ‘F’, 3, ‘2023-03-10’);

9、LOAD DATA INFILE体验使用
准备测试数据:
CREATE TABLE IF NOT EXISTS products (
id INT PRIMARY KEY,
product_name VARCHAR(100) NOT NULL,
category VARCHAR(50),
price DECIMAL(10,2),
stock INT,
created_at TIMESTAMP
);
data.csv
“id”,“product_name”,“category”,“price”,“stock”,“created_at”
1,“笔记本电脑”,“电子产品”,5999.99,50,“2023-01-15 10:30:00”
2,“智能手机”,“电子产品”,3999.00,100,“2023-01-16 11:15:00”
3,“无线耳机”,“电子产品”,299.90,200,“2023-01-17 09:45:00”
4,“办公椅”,“家具”,899.00,30,“2023-01-18 14:20:00”
5,“台灯”,“家居用品”,159.50,80,“2023-01-19 16:10:00”
6,“咖啡机”,“厨房电器”,1299.00,25,“2023-01-20 13:25:00”
7,“运动鞋”,“服装鞋帽”,459.00,60,“2023-01-21 10:50:00”
测试:
##使用COPY命令导入数据:
COPY products (id, product_name, category, price, stock, created_at)
FROM ‘/data/soft/data.csv’
WITH (
FORMAT csv,
HEADER true, – 跳过标题行(等价于MySQL的IGNORE 1 ROWS)
DELIMITER ‘,’,
QUOTE ‘"’,
NULL ‘’
);

PS:
LOAD DATA INFILE不完全兼容,需改用COPY命令,必须使用PostgreSQL风格的COPY命令替代MySQL的LOAD DATA INFILE,文件路径权限管理更为严格,缺少IGNORE ROWS语法,改用HEADER true跳过标题行。
PS:更新,LOAD使用如下方法:
test=# CREATE TABLE products_new (LIKE products INCLUDING ALL);
CREATE TABLE
test=# select * from products_new;
id | product_name | category | price | stock | created_at
----±-------------±---------±------±------±-----------
(0 rows)
test=# LOAD DATA INFILE ‘/data/soft/tst.csv’
test-# INTO TABLE products_new
test-# FIELDS TERMINATED BY ‘,’
test-# ENCLOSED BY ‘"’
test-# LINES TERMINATED BY ‘\n’
test-# IGNORE 1 LINES;
ERROR: syntax error at or near “IGNORE”
LINE 6: IGNORE 1 LINES;
^
test=# LOAD DATA INFILE ‘/data/soft/tst.csv’
test-# INTO TABLE products_new
test-# FIELDS TERMINATED BY ‘,’
test-# ENCLOSED BY ‘"’
test-# LINES TERMINATED BY ‘\n’;
COPY 7
原因:不支持使用IGNORE

10、GROUP BY WITH ROLLUP体验使用
– 按部门和性别统计员工数量和平均薪资
SELECT
COALESCE(department_id, ‘所有部门’) AS department,
COALESCE(gender, ‘合计’) AS gender,
COUNT(*) AS employee_count,
AVG(salary) AS avg_salary
FROM employees
WHERE leave_date IS NULL
GROUP BY department_id, gender WITH ROLLUP;

总结

金仓数据库Mysql兼容模式基础语法支持良好:大多数基础DML语句(INSERT/UPDATE/DELETE/SELECT)与MySQL高度兼容,常见数据类型和基础函数能够正常工作,提供了非常好的兼容性,大大降低了从Mysql迁移至金仓数据库的技术门槛。期待金仓对Mysql的兼容性将进一步提升,为数据库国产化替代提供更加平滑的迁移路径。




