PanWeiDB2.0异构数据库访问测试
PanWeiDB2.0异构数据库访问测试
异构数据库访问兼容性测试一览表
No | 访问路径 | 多维度结果 | 备注 |
---|---|---|---|
1 | PanWeiDB(集中式)—访问—PanWeiDB(集中式) | √ | 支持复杂SQL |
2 | PanWeiDB(集中式)—访问—Oracle | √ | 支持 |
3 | Oracle—访问—PanWeiDB(集中式) | √ | 受Oracle默认大写影响,dblink涉及磐维的对象及字段,需要用双引号""括起来。不支持求平均值,偶发性出现链接错误,重新登录正常 |
4 | PanWeiDB(集中式)—访问—PanWeiDB(分布式) | × | 基础select不支持,缺少get_typmod_with_unit 系统基础函数 |
5 | PanWeiDB(分布式)—访问—PanWeiDB(集中式) | × | 不支持database link语法,厂商反馈:不支持database link访问磐维集中式 |
6 | PanWeiDB(集中式)—访问—GoldenDB(分布式) | √ | 支持简单SQL,需注意与GoldenDB数据交互或者修改时,外部表定义的数据类型可能会出现转换异常的情况 |
7 | PanWeiDB(集中式)—访问—AntDB(集中式) | × | 认证交互错误:DETAIL: expected authentication request from server, but received v |
8 | AntDB(集中式)—访问—PanWeiDB(集中式) | × | 外部表映射错误,ERROR: user mapping not found for “antdb” |
测试过程
1、PanWeiDB访问PanWeiDB
测试结果
序号 | 复杂度 | 具体操作 | 结果 |
---|---|---|---|
1 | 基本SQL操作 | 查询远程数据(SELECT) | 验证通过 |
2 | 插入数据到本地表(INSERT) | 验证通过 | |
3 | 更新本地表数据(UPDATE) | 验证通过 | |
4 | 删除数据(DELETE) | 验证通过 | |
5 | 复杂SQL操作 | 多表关联(4表JOIN) | 验证通过 |
6 | 笛卡尔积与过滤条件 | 验证通过 | |
7 | 嵌套循环(NESTED LOOP) | 验证通过 | |
8 | 哈希连接(HASH JOIN) | 验证通过 | |
9 | 聚合函数与GROUP BY | 验证通过 | |
10 | 子查询与EXISTS | 验证通过 | |
11 | 窗口函数与RANK | 验证通过 | |
12 | 复杂条件与函数 | 验证通过 |
测试账户
create user testuser1 with sysadmin password '3GahEH271';
create database testdb1 owner testuser1;
\q
gsql -r -p 17700 -d testdb1 -U testuser1 -W 3GahEH271
1.1 创建dblink
grant all on database testdb1 to testuser1;
GRANT ALL PRIVILEGES ON DATABASE testdb1 TO testuser1;
create extension postgres_fdw;
grant usage on foreign data wrapper postgres_fdw to testuser1;
# 创建到oracle的映射,执行此语句需预先使用 gs_guc generate 命令生成 datasource 文件,此处以如下命令为例:
gs_guc generate -S 'Gs@123456' -D $GAUSSHOME/bin -o usermapping
create database link dblink_pwcrm149 connect to testuser1 identified by '3GahEH271' using postgres_fdw(host '10.183.162.149',port '17700',dbname 'testdb1');
2.1 基本SQL操作
3. 复杂SQL示例
3.1 多表关联(4表JOIN)
3.2 笛卡尔积与过滤条件
3.3 嵌套循环(NESTED LOOP)
3.4 哈希连接(HASH JOIN)
3.5 聚合函数与GROUP BY
3.6 子查询与EXISTS
3.7 窗口函数与RANK
3.8 复杂条件与函数
2、PanWeiDB访问Oracle
PanWeiDB(PanWeiDB版本升级测试库),访问,Oracle(运维库)
create extension oracle_fdw;
create user cboss_ora password 'cboss_ora@123';
grant usage on foreign data wrapper oracle_fdw to cboss_ora ;
\c - cboss_ora
create server ora_fdw_server foreign data wrapper oracle_fdw
options(dbserver '10.176.240.129:1521/cbosslo');
# gs_guc generate -S 'cboss_ora@123' -D $GAUSSHOME/bin -o usermapping
create user mapping for cboss_ora server ora_fdw_server options(user 'OPERUSER_MY',password 'zvMc!P47dK');
create foreign table emp_fdw_ora(empno int,ename varchar(30)) server ora_fdw_server options(schema 'SYSTEM',table 'EMP_FDW');
create foreign table emp_fdw_ora(empno int,ename varchar(30)) server ora_fdw_server options(schema 'OPERUSER_MY',table 'emp_fdw');
select * from emp_fdw_ora;
insert into emp_fdw_ora values(3,'bar3');
测试复杂场景
drop table t1;
create table t1 (id number primary key,update_time timestamp);
INSERT INTO t1 (id, update_time) VALUES (1, TO_TIMESTAMP('2025-01-01 10:00:00', 'YYYY-MM-DD HH24:MI:SS'));
INSERT INTO t1 (id, update_time) VALUES (2, TO_TIMESTAMP('2025-01-02 12:00:00', 'YYYY-MM-DD HH24:MI:SS'));
INSERT INTO t1 (id, update_time) VALUES (3, TO_TIMESTAMP('2025-01-03 14:00:00', 'YYYY-MM-DD HH24:MI:SS'));
commit;
select * from t1;
drop table t2;
create table t2 (
id number,
name varchar2(50),
t1_id number
);
INSERT INTO t2 (id, name, t1_id) VALUES (101, 'Alice', 1);
INSERT INTO t2 (id, name, t1_id) VALUES (102, 'Bob', 2);
INSERT INTO t2 (id, name, t1_id) VALUES (103, 'Charlie', 3);
commit;
select * from t2;
select * from t1_fdw_ora;
SELECT t1.id, t1.update_time, t2.name
FROM t1_fdw_ora as t1
JOIN t2 as t2 ON t1.id = t2.t1_id;
testdb1=> explain analyze SELECT t1.id, t1.update_time, t2.name
testdb1-> FROM t1_fdw_ora as t1
testdb1-> JOIN t2 as t2 ON t1.id = t2.t1_id;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------
Hash Join (cost=100.04..114.88 rows=2 width=158) (actual time=1.364..1.404 rows=3 loops=1)
Hash Cond: (t2.t1_id = t1.id)
-> Seq Scan on t2 (cost=0.00..13.85 rows=385 width=150) (actual time=0.023..0.034 rows=3 loops=1)
-> Hash (cost=100.03..100.03 rows=1 width=40) (actual time=1.215..1.215 rows=3 loops=1)
Buckets: 32768 Batches: 1 Memory Usage: 257kB
-> Foreign Scan on t1_fdw_ora t1 (cost=100.00..100.03 rows=1 width=40) (actual time=0.904..1.165 rows=3 loops=1)
Total runtime: 20.764 ms
(7 rows)
testdb1=>
3、Oracle访问PanWeiDB
Oracle(DBA运维库),访问,PanWeiDB(PanWeiDB版本升级测试库)
3.1 多表关联(4表JOIN)
-- 左连接 + 右连接 + 窗口函数
select
"ee"."emp_name",
d.dept_name,
"pp"."project_name",
pa.role,
"ee"."salary"
from "employees"@pg_link "ee"
left join departments d on "ee"."department" = d.dept_name
right join "projects"@pg_link "pp" on d.dept_id = "pp"."dept_id"
join project_assignments pa on pa.project_id = "pp"."project_id"
where "pp"."start_date" > sysdate - 365
and "ee"."salary" > 6000;
database link涉及磐维对象及字段,需要用双引号""括起来,这受Oracle默认大写影响
不支持求平均值
可以查询
偶发性出现链接错误
3.2 笛卡尔积与过滤条件
-- 笛卡尔积 + CASE判断
SELECT
"ee"."emp_name",
p.project_name,
CASE
WHEN "ee"."salary" > 10000 THEN 'High'
WHEN "ee"."salary" BETWEEN 5000 AND 10000 THEN 'Medium'
ELSE 'Low'
END AS salary_level
FROM "employees"@pg_link "ee", projects p
WHERE p.dept_id = 1
AND "ee"."department" = 'IT';
执行计划
3.3 嵌套循环(NESTED LOOP)
-- 强制使用NESTED LOOP(提示方式)
SELECT /*+ USE_NL(e "dd") */
e.emp_id,
"dd"."dept_name"
FROM employees e
JOIN "departments"@pg_link "dd" ON e.department = "dd"."dept_name"
WHERE "dd"."budget" > 500000;
3.4 哈希连接(HASH JOIN)
-- 强制使用HASH JOIN
SELECT /*+ USE_HASH(pa "pp") */
pa.assignment_id,
"pp"."project_name"
FROM project_assignments pa
JOIN "projects"@pg_link "pp" ON pa.project_id = "pp"."project_id"
WHERE "pp"."end_date" > SYSDATE;
3.5 聚合函数与GROUP BY
-- 聚合函数 + HAVING
SELECT
"dd"."dept_name",
COUNT(e.emp_id) AS total_employees,
SUM(e.salary) AS total_salary
FROM "departments"@pg_link "dd"
LEFT JOIN employees e ON "dd"."dept_name" = e.department
GROUP BY "dd"."dept_name"
HAVING SUM(e.salary) > 100000;
3.6 子查询与EXISTS
-- EXISTS子查询
SELECT
e.emp_name
FROM employees e
WHERE EXISTS (
SELECT 1
FROM "project_assignments"@pg_link "pa"
WHERE "pa"."emp_id" = e.emp_id
AND "pa"."role" = 'Manager'
);
3.7 窗口函数与RANK
-- RANK()窗口函数
SELECT
"emp_name",
"salary",
RANK() OVER (ORDER BY "salary" DESC) AS salary_rank
FROM "employees"@pg_link
WHERE "department" = 'IT';
3.8 复杂条件与函数
-- 字符串函数 + 日期计算
SELECT
"ee"."emp_name",
UPPER(d.dept_name) AS dept_upper,
ADD_MONTHS("ee"."hire_date", 12) AS hire_anniversary
FROM "employees"@pg_link "ee"
JOIN departments d ON "ee"."department" = d.dept_name
WHERE TO_CHAR("ee"."hire_date", 'YYYY') = '2023'
AND LENGTH("ee"."emp_name") > 5;
4、集中式PanWeiDB访问分布式PanWeiDB
PanWeiDB(PanWeiDB版本升级测试库),访问,PanWeiDB分布式(计费系统)
测试结果
序号 | 复杂度 | 具体操作 | 结果 |
---|---|---|---|
1 | 基本SQL操作 | 查询远程数据(SELECT) | 测试未通过 |
测试账户
create user testuser2 with sysadmin password '3GahEH271';
create database testdb1 owner testuser2;
\q
gsql -r -p 17700 -d testdb1 -U testuser2 -W 3GahEH271
1.1 创建dblink
create database link dblink_jfjsxt19098 connect to testuser2 identified by '3GahEH271' using postgres_fdw(host '10.183.190.98',port '17700',dbname 'testdb1');
2.1 基本SQL操作
testdb1=> SELECT * FROM employees@dblink_jfjsxt19098 WHERE department = 'IT';
ERROR: function get_typmod_with_unit(integer, text[]) does not exist
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
CONTEXT: Remote SQL command: SELECT a.attname,
(case pg_catalog.format_type(a.atttypid, get_typmod_with_unit(a.atttypmod, a.attoptions)) when 'oradate' then 'date' else pg_catalog.format_type(a.atttypid, get_typmod_with_unit(a.atttypmod, a.attoptions)) end)
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = (select oid from pg_class where relname='employees' and relnamespace=(select oid from pg_namespace where nspname='testuser2'))
AND a.attnum > 0 AND NOT a.attisdropped AND a.attkvtype != 4 AND a.attname <> 'tableoid' AND a.attname <> 'tablebucketid'
ORDER BY a.attnum;
referenced column: format_type
testdb1=>
磐维集中式数据库-SQL执行正常
磐维分布式数据库-SQL无法执行
磐维分布式数据库缺少函数“get_typmod_with_unit”,导致集中式数据库访问分布式数据库时,无法执行查询:
查询 pg_attribute
系统表,检索有关表 employees
的列信息,以获取列名和数据类型信息,
get_typmod_with_unit
是一个系统函数,用于从类型修饰符中提取单位信息。
它的作用是将类型修饰符转换为更易读的格式
手动创建函数get_typmod_with_unit
CREATE OR REPLACE FUNCTION get_typmod_with_unit(typmod integer, options text[])
RETURNS integer
AS $$
DECLARE
unit integer;
BEGIN
-- 从类型修饰符中提取单位信息
-- 这里是一个示例逻辑,实际逻辑可能需要根据你的数据库系统进行调整
unit := typmod % 1000; -- 假设单位信息存储在 typmod 的低三位
-- 返回提取的单位信息
RETURN unit;
END;
$$ LANGUAGE plpgsql;
磐维集中式dblink访问
查询报错,依然缺少函数“get_typmod_with_unit”函数,暂无方案解决(20250305)。
5、分布式PanWeiDB访问集中式PanWeiDB
PanWeiDB分布式(结算系统(计费系统-计费云详单)),访问,PanWeiDB(PanWeiDB版本升级测试库)
分布式磐维数据库,暂不支持dblink
6、PanWeiDB访问GoldenDB
PanWeiDB(PanWeiDB版本升级测试库),访问,GoldenDB分布式(中台中心)
数据类型略微调整
create extension mysql_fdw;
grant usage on foreign data wrapper mysql_fdw to testuser1;
create server goldendb_fdw_server foreign data wrapper mysql_fdw options(HOST '10.183.200.193',PORT '8880');
create user mapping for testuser1 server goldendb_fdw_server options(username 'testuser1',password '3GahEH271!');
create foreign table employees_fdw_goldendb (
emp_id NUMBER(10) ,
emp_name VARCHAR2(50) NOT NULL,
hire_date DATE,
salary NUMBER(10, 2),
department VARCHAR2(50),
resume CLOB,
photo BLOB
) server goldendb_fdw_server options(DBNAME 'testdb1',table_name 'employees');
create foreign table departments_fdw_goldendb (
dept_id NUMBER(10),
dept_name VARCHAR2(50) ,
manager_id NUMBER(10),
budget NUMBER(15, 2)
) server goldendb_fdw_server options(DBNAME 'testdb1',table_name 'departments');
create foreign table projects_fdw_goldendb (
project_id NUMBER(10),
project_name VARCHAR2(100),
start_date DATE,
end_date DATE,
dept_id NUMBER(10)
) server goldendb_fdw_server options(DBNAME 'testdb1',table_name 'projects');
create foreign table project_assignments_fdw_goldendb (
assignment_id NUMBER(10) ,
emp_id NUMBER(10),
project_id NUMBER(10),
role VARCHAR2(50)
) server goldendb_fdw_server options(DBNAME 'testdb1',table_name 'project_assignments');
基本SQL操作
根据错误信息,问题出在数据类型转换上。具体来说,磐维无法将常量值的数据类型(1399)转换为GoldenDB 的数据类型。这通常发生在使用外部表(FDW,Foreign Data Wrapper)时,数据类型不匹配。
错误分析
数据类型不匹配
- 错误信息
cannot convert constant value to MySQL value
表明,磐维 无法将某个常量值转换为 GoldenDB 的数据类型。 Constant value data type: 1399
表示常量值的数据类型是 1399,这可能是 GoldenDB 中的DECIMAL
类型。
- 错误信息
外部表定义问题
- 外部表
employees_fdw_goldendb
的定义可能与GoldenDB 表的结构不完全匹配。
- 外部表
解决方案
检查外部表定义
- 确保外部表
employees_fdw_goldendb
的定义与GoldenDB 表的结构完全匹配。 - 使用
SHOW CREATE TABLE
或DESCRIBE
命令检查 GoldenDB 表的结构。
- 确保外部表
修改外部表定义
- 如果数据类型不匹配,修改外部表的定义,使其与 GoldenDB 表的结构一致。
- 例如,如果 GoldenDB 表中的
emp_id
是INT
类型,确保外部表中的emp_id
也是INT
类型。
检查常量值的数据类型
- 确保插入或查询时使用的常量值的数据类型与外部表的定义匹配。
- 如果需要,使用显式类型转换。
MySQL_FDW功能描述
外部表,支持select查询、dml操作。
支持创建外部数据封装器mysql_fdw,连接MariaDB或MySQL或者GoldenDB数据库,并能在外部表上进行查询、插入、更新和删除操作。
mysql_fdw插件默认参与编译,用户可直接使用mysql_fdw,无须其他操作。
7、GoldenDB访问PanWeiDB
GoldenDB分布式(中台中心),访问,PanWeiDB(PanWeiDB版本升级测试库)
8、PanWeiDB访问AntDB
PanWeiDB(PanWeiDB版本升级测试库),访问,AntDB(财务系统)
创建扩展
-- 本地数据库创建表
-- 表1: employees (员工表)
CREATE TABLE employees (
emp_id int PRIMARY KEY,
emp_name VARCHAR(50) NOT NULL,
hire_date DATE,
salary int,
department VARCHAR(50),
resume text,
photo text
);
-- 表2: departments (部门表)
CREATE TABLE departments (
dept_id int PRIMARY KEY,
dept_name VARCHAR(50) UNIQUE,
manager_id int,
budget int,
CONSTRAINT fk_manager FOREIGN KEY (manager_id) REFERENCES employees(emp_id)
);
-- 表3: projects (项目表)
CREATE TABLE projects (
project_id int PRIMARY KEY,
project_name VARCHAR(100),
start_date DATE,
end_date DATE,
dept_id int,
CONSTRAINT fk_dept FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
);
-- 表4: project_assignments (项目分配表)
CREATE TABLE project_assignments (
assignment_id int PRIMARY KEY,
emp_id int,
project_id int,
role VARCHAR(50),
CONSTRAINT fk_emp FOREIGN KEY (emp_id) REFERENCES employees(emp_id),
CONSTRAINT fk_project FOREIGN KEY (project_id) REFERENCES projects(project_id)
);
-- 创建索引
CREATE INDEX idx_emp_dept ON employees(department);
CREATE INDEX idx_proj_dept ON projects(dept_id);
CREATE INDEX idx_assign_role ON project_assignments(role);
插入数据
-- 插入员工数据
DO $$
BEGIN
FOR i IN 1..1000 LOOP
INSERT INTO employees VALUES (
i,
'Employee' || i,
CURRENT_DATE - MOD(i, 365),
5000 + MOD(i, 10000),
CASE MOD(i, 4)
WHEN 0 THEN 'IT'
WHEN 1 THEN 'HR'
WHEN 2 THEN 'Finance'
ELSE 'Sales'
END,
'aaaaaaaaaa',
'bbbbbbbbbb'
);
END LOOP;
END;
$$;
-- 插入部门数据
INSERT INTO departments VALUES (1, 'IT', 100, 1000000);
INSERT INTO departments VALUES (2, 'HR', 200, 500000);
-- 插入项目数据
INSERT INTO projects VALUES (101, 'ERP System', CURRENT_DATE-100, CURRENT_DATE+200, 1);
INSERT INTO projects VALUES (102, 'HR Portal', CURRENT_DATE-50, CURRENT_DATE+100, 2);
-- 插入项目分配数据
DO $$
BEGIN
FOR i IN 1..500 LOOP
INSERT INTO project_assignments VALUES (
i,
MOD(i, 1000) + 1,
CASE MOD(i, 2) WHEN 0 THEN 101 ELSE 102 END,
CASE MOD(i, 3) WHEN 0 THEN 'Developer' WHEN 1 THEN 'Tester' ELSE 'Manager' END
);
END LOOP;
END;
$$;
不支持使用dblink直接访问
testdb1=> SELECT * FROM employees@dblink_antdb WHERE department = 'IT';
ERROR: could not connect to server "dblink_antdb"
DETAIL: expected authentication request from server, but received v
testdb1=>
认证错误
使用外部表的方式访问
create extension postgres_fdw;
grant usage on foreign data wrapper postgres_fdw to testuser1;
create server antdb_fdw_server foreign data wrapper postgres_fdw options(HOST '10.183.103.130',PORT '5432');
create user mapping for testuser1 server antdb_fdw_server options(user 'testuser1',password '3GahEH271!');
create foreign table employees_fdw_antdb (
emp_id NUMBER(10) ,
emp_name VARCHAR2(50) NOT NULL,
hire_date DATE,
salary NUMBER(10, 2),
department VARCHAR2(50),
resume CLOB,
photo BLOB
) server antdb_fdw_server options(schema_name 'public',table_name 'employees');
create foreign table departments_fdw_antdb (
dept_id NUMBER(10),
dept_name VARCHAR2(50) ,
manager_id NUMBER(10),
budget NUMBER(15, 2)
) server antdb_fdw_server options(schema_name 'public',table_name 'departments');
create foreign table projects_fdw_antdb (
project_id NUMBER(10),
project_name VARCHAR2(100),
start_date DATE,
end_date DATE,
dept_id NUMBER(10)
) server antdb_fdw_server options(schema_name 'public',table_name 'projects');
create foreign table project_assignments_fdw_antdb (
assignment_id NUMBER(10) ,
emp_id NUMBER(10),
project_id NUMBER(10),
role VARCHAR2(50)
) server antdb_fdw_server options(schema_name 'public',table_name 'project_assignments');
依然无法访问。
9、AntDB访问PanWeiDB
AntDB(财务系统、全面预算系统),访问,PanWeiDB(PanWeiDB版本升级测试库)
create extension postgres_fdw;
grant usage on foreign data wrapper postgres_fdw to testuser1;
create server panweidb_fdw_server foreign data wrapper postgres_fdw options(HOST '10.183.162.150',PORT '17700',dbname 'testdb1');
create user mapping for testuser1 server panweidb_fdw_server options(user 'testuser1',password '3GahEH271');
create foreign table employees_fdw_panweidb (
emp_id int ,
emp_name VARCHAR(50) NOT NULL,
hire_date DATE,
salary int,
department VARCHAR(50),
resume text,
photo text
) server panweidb_fdw_server options(schema_name 'public',table_name 'employees');
不支持number、varchar2、clob、blob
无法访问外部表
测试用例
以下是一个基于Oracle数据库使用DBLink的详细案例,包含测试用例、完整SQL语句及复杂查询示例:
1. 测试用例设计
1.1 创建测试表及约束
-- 本地数据库创建表
-- 表1: employees (员工表)
CREATE TABLE employees (
emp_id NUMBER(10) PRIMARY KEY,
emp_name VARCHAR2(50) NOT NULL,
hire_date DATE,
salary NUMBER(10, 2),
department VARCHAR2(50),
resume CLOB,
photo BLOB
);
-- 表2: departments (部门表)
CREATE TABLE departments (
dept_id NUMBER(10) PRIMARY KEY,
dept_name VARCHAR2(50) UNIQUE,
manager_id NUMBER(10),
budget NUMBER(15, 2),
CONSTRAINT fk_manager FOREIGN KEY (manager_id) REFERENCES employees(emp_id)
);
-- 表3: projects (项目表)
CREATE TABLE projects (
project_id NUMBER(10) PRIMARY KEY,
project_name VARCHAR2(100),
start_date DATE,
end_date DATE,
dept_id NUMBER(10),
CONSTRAINT fk_dept FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
);
-- 表4: project_assignments (项目分配表)
CREATE TABLE project_assignments (
assignment_id NUMBER(10) PRIMARY KEY,
emp_id NUMBER(10),
project_id NUMBER(10),
role VARCHAR2(50),
CONSTRAINT fk_emp FOREIGN KEY (emp_id) REFERENCES employees(emp_id),
CONSTRAINT fk_project FOREIGN KEY (project_id) REFERENCES projects(project_id)
);
-- 创建索引
CREATE INDEX idx_emp_dept ON employees(department);
CREATE INDEX idx_proj_dept ON projects(dept_id);
CREATE INDEX idx_assign_role ON project_assignments(role);
1.2 插入测试数据(通过PL/SQL循环)
-- 插入员工数据
BEGIN
FOR i IN 1..1000 LOOP
INSERT INTO employees VALUES (
i,
'Employee' || i,
SYSDATE - MOD(i, 365),
5000 + MOD(i, 10000),
CASE MOD(i, 4) WHEN 0 THEN 'IT' WHEN 1 THEN 'HR' WHEN 2 THEN 'Finance' ELSE 'Sales' END,
EMPTY_CLOB(),
EMPTY_BLOB()
);
END LOOP;
END;
/
-- 插入部门数据
INSERT INTO departments VALUES (1, 'IT', 100, 1000000);
INSERT INTO departments VALUES (2, 'HR', 200, 500000);
-- 插入项目数据
INSERT INTO projects VALUES (101, 'ERP System', SYSDATE-100, SYSDATE+200, 1);
INSERT INTO projects VALUES (102, 'HR Portal', SYSDATE-50, SYSDATE+100, 2);
-- 插入项目分配数据
BEGIN
FOR i IN 1..500 LOOP
INSERT INTO project_assignments VALUES (
i,
MOD(i, 1000) + 1,
CASE MOD(i, 2) WHEN 0 THEN 101 ELSE 102 END,
CASE MOD(i, 3) WHEN 0 THEN 'Developer' WHEN 1 THEN 'Tester' ELSE 'Manager' END
);
END LOOP;
END;
/
2. DBLink配置与基本SQL
2.1 创建DBLink
-- 创建到远程数据库的DBLink(假设远程数据库名为remote_db)
-- CREATE DATABASE LINK remote_db_link
-- CONNECT TO remote_user IDENTIFIED BY remote_password
-- USING 'remote_db';
grant all on database testdb1 to testuser1;
create extension postgres_fdw;
grant usage on foreign data wrapper postgres_fdw to testuser1;
# 创建到oracle的映射,执行此语句需预先使用 gs_guc generate 命令生成 datasource 文件,此处以如下命令为例:
gs_guc generate -S 'Gs@123456' -D $GAUSSHOME/bin -o usermapping
create database link dblink_pwcrm149 connect to testuser1 identified by '3GahEH271' using postgres_fdw(host '10.183.162.149',port '17700',dbname 'testdb1');
2.2 基本SQL操作
-- 查询远程数据(SELECT)
SELECT * FROM employees@dblink_pwcrm149 WHERE department = 'IT';
-- 插入数据到本地表(INSERT)
INSERT INTO employees
SELECT * FROM employees@dblink_pwcrm149 WHERE emp_id > 500;
-- 更新本地表数据(UPDATE)
UPDATE employees e
SET e.salary = e.salary * 1.1
WHERE EXISTS (
SELECT dept_id FROM departments@dblink_pwcrm149 d
WHERE d.dept_name = e.department AND d.dept_name = 'IT'
);
-- 删除数据(DELETE)
DELETE FROM project_assignments
WHERE project_id IN (
SELECT project_id FROM projects@dblink_pwcrm149 WHERE dept_id = 1
);
3. 复杂SQL示例
3.1 多表关联(4表JOIN)
-- 左连接 + 右连接 + 窗口函数
SELECT
e.emp_name,
d.dept_name,
p.project_name,
pa.role,
AVG(e.salary) OVER (PARTITION BY d.dept_id) AS avg_dept_salary
FROM employees@dblink_pwcrm149 e
LEFT JOIN departments d ON e.department = d.dept_name
RIGHT JOIN projects@dblink_pwcrm149 p ON d.dept_id = p.dept_id
JOIN project_assignments pa ON pa.project_id = p.project_id
WHERE p.start_date > SYSDATE - 365
AND e.salary > 6000;
3.2 笛卡尔积与过滤条件
-- 笛卡尔积 + CASE判断
SELECT
e.emp_name,
p.project_name,
CASE
WHEN e.salary > 10000 THEN 'High'
WHEN e.salary BETWEEN 5000 AND 10000 THEN 'Medium'
ELSE 'Low'
END AS salary_level
FROM employees@dblink_pwcrm149 e, projects p
WHERE p.dept_id = 1
AND e.department = 'IT';
3.3 嵌套循环(NESTED LOOP)
-- 强制使用NESTED LOOP(提示方式)
SELECT /*+ USE_NL(e d) */
e.emp_id,
d.dept_name
FROM employees e
JOIN departments@dblink_pwcrm149 d ON e.department = d.dept_name
WHERE d.budget > 500000;
3.4 哈希连接(HASH JOIN)
-- 强制使用HASH JOIN
SELECT /*+ USE_HASH(pa p) */
pa.assignment_id,
p.project_name
FROM project_assignments pa
JOIN projects@dblink_pwcrm149 p ON pa.project_id = p.project_id
WHERE p.end_date > SYSDATE;
3.5 聚合函数与GROUP BY
-- 聚合函数 + HAVING
SELECT
d.dept_name,
COUNT(e.emp_id) AS total_employees,
SUM(e.salary) AS total_salary
FROM departments@dblink_pwcrm149 d
LEFT JOIN employees e ON d.dept_name = e.department
GROUP BY d.dept_name
HAVING SUM(e.salary) > 100000;
3.6 子查询与EXISTS
-- EXISTS子查询
SELECT
e.emp_name
FROM employees e
WHERE EXISTS (
SELECT 1
FROM project_assignments@dblink_pwcrm149 pa
WHERE pa.emp_id = e.emp_id
AND pa.role = 'Manager'
);
3.7 窗口函数与RANK
-- RANK()窗口函数
SELECT
emp_name,
salary,
RANK() OVER (ORDER BY salary DESC) AS salary_rank
FROM employees@dblink_pwcrm149
WHERE department = 'IT';
3.8 复杂条件与函数
-- 字符串函数 + 日期计算
SELECT
e.emp_name,
UPPER(d.dept_name) AS dept_upper,
ADD_MONTHS(e.hire_date, 12) AS hire_anniversary
FROM employees@dblink_pwcrm149 e
JOIN departments d ON e.department = d.dept_name
WHERE TO_CHAR(e.hire_date, 'YYYY') = '2023'
AND LENGTH(e.emp_name) > 5;
总结
- 测试用例:覆盖了多表结构、索引、约束及循环插入数据。
- DBLink操作:实现了跨数据库的增删改查。
- 复杂SQL:包含多表关联、窗口函数、不同连接算法及优化提示。
通过以上案例,可以从多个维度测试不同数据库DBLink的功能性和性能,同时满足复杂业务场景需求。
PanWeiDB2.0异构数据库访问测试的更多相关文章
- OracleGateway11gR2访问异构数据库(MSSQL)配置文档(转)
1.前提条件 1. 准备工作 软件名称 操作系统 IP地址 端口 用户 密码 版本 状态 Oracle数据库 Windows localhost 1521 scott scott win32 Orac ...
- .net单元测试——常用测试方式(异常模拟、返回值测试、参数测试、数据库访问代码测试)
最近在看.net单元测试艺术,我也喜欢单元测试,今天介绍一下如何测试异常.如何测试返回值.如何测试模拟对象的参数传递.如何测试数据库访问代码.单元测试框架使用的是NUnit,模拟框架使用的是:Rhin ...
- 我的基于asp.net mvc5 +mysql+dapper+easyui 的Web开发框架(1)数据库访问(0)
一.数据库访问 概述 1. 数据库使用mysql,orm采用dapper框架.dapper框架应用简单,只是需要自己手写sql语句,但是对于像我这样写了多年sql语句的人来说,这应该不算问题,个人还是 ...
- 异构数据库迁移 db2---oracle
异构数据库迁移 其他数据库迁移到oracle,以移植db2数据库对象到Oracle的操作说明为例,其他数据库迁移到oracle类似. 移植之平台和相关工具 OS:linux DBMS:db2 Ora ...
- 在数据库访问项目中使用微软企业库Enterprise Library,实现多种数据库的支持
在我们开发很多项目中,数据访问都是必不可少的,有的需要访问Oracle.SQLServer.Mysql这些常规的数据库,也有可能访问SQLite.Access,或者一些我们可能不常用的PostgreS ...
- [开源].NET数据库访问框架Chloe.ORM
扯淡 13年毕业之际,进入第一家公司实习,接触了 EntityFramework,当时就觉得这东西太牛了,访问数据库都可以做得这么轻松.优雅!毕竟那时还年轻,没见过世面.工作之前为了拿个实习机会混个工 ...
- 数据库访问性能优化 Oracle
特别说明: 1. 本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识: 2. 本文许多示例及概念是基于Oracle数据库描述,对于其它关系型数据库也 ...
- java提高数据库访问效率代码优化
package com.jb.jubmis.comm; import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQL ...
- 数据访问层DAL(数据库访问抽象类DataProvider)
晒晒数据访问层DAL,看看你的项目数据访问层使用的是什么形式,数据访问性能比较 采用什么样的数据访问形式是软件编码很重要的一个环节,良好的数据访问形式不仅能够提搞代码的执行效率,协作能力,更重要的是对 ...
- Oracle GoldenGate配置异构数据库数据传输(oracle到sqlserer)的dml操作(带pump进程)
实验环境:os01:Red Hat Enterprise Linux Server release 5.1 (32位)db01:oracle 10.2.0.1.0 os02:Windows 7 (32 ...
随机推荐
- Qt开发经验小技巧276-280
对MDI窗体区域设置背景颜色透明,会发现 QMdiArea{background:transparent;} 无效,哪怕是指定颜色 QMdiArea{background:#ff0000;} 或者 Q ...
- Qt编写视频监控系统70-OSD标签和图形信息(支持写入到文件)
一.前言 作为一个完整的视频监控系统,用户还需要自定义一些OSD标签信息显示在对应通道上面,而且不止一个OSD标签信息,位置可以在四个角或者指定坐标显示.最开始本系统设计的时候,由于本人擅长的是pai ...
- Qt编写的项目作品22-自定义委托全家桶
一.功能特点 可设置多种委托类型,例如复选框/文本框/下拉框/日期框/微调框/进度条等. 可设置是否密文显示,一般用于文本框. 可设置是否允许编辑,一般用于下拉框. 可设置是否禁用,一般用来禁用某列. ...
- IM跨平台技术学习(十):快速对比跨平台框架Electron、Flutter、Tauri、React Native等
本文由21CTO万能的大雄分享,本文有修订和改动. 1.引言 在当今快速发展的技术环境中,对跨平台桌面应用程序的需求正在不断激增. 开发人员面临着选择正确框架之挑战,以便可以高效构建可在 Window ...
- 即时通讯技术文集(第13期):Web端即时通讯技术精华合集 [共15篇]
为了更好地分类阅读52im.net 总计1000多篇精编文章,我将在每周三推送新的一期技术文集,本次是第13 期. [- 1 -] 新手入门贴:史上最全Web端即时通讯技术原理详解 [链接] http ...
- Go基于观察者模式实现的订阅/发布
面UCloud的时候问到了这题,下来看了一下是基于观察者模式实现的,仅作记录 /** * @Author: lzw5399 * @Date: 2021/5/20 20:38 * @Desc: 基于观察 ...
- 解决 raw.githubusercontent.com 无法访问的问题
解决 raw.githubusercontent.com 无法访问的问题 电信默认 DNS 直接遮蔽 github DNS 1: 61.139.2.69 DNS 2: 218.6.200.139 C: ...
- 基于STC8G1K08的CH549单键进入USB下载模式实验
一.实验原因 CH552或CH549进入USB下载,通常需要两个按键,一个控制电源的通断,一个通过串联电阻(一头接VCC或V33)冷启动时抬高UDP电平.时序上是这样的:断电--按下接UDP的轻触开关 ...
- SSH 框架的搭建
Structs1+spring+Hibernate Structs 相当于mvc设计模式中V.C,即jsp页面和Servlet: spring 管理业务逻辑,即Service: Hibernate ...
- 项目PMP之二项目运行环境
一.项目运行环境因素 项目内部:组织过程资产(OPA):用于治理和执行项目,可为正式与非正式 过程.政策和程序:由非项目内职能部门制定的,如PMO 组织知识库:项目进行中累计的信息文档,如经验.设计. ...