一、PGSQL空间数据表迁移达梦
最近在做国产化改造项目,mysql、pgsql迁移到达梦,起初进展一切顺利,我们都是通过sqlark工具去迁移的,mysql完全没问题,因为没有涉及空间数据,但是在pgsql中会有一些小问题,比如下图:
(这个问题只需要把"public".“geometry"修改成st_geometry即可创建表成功)

(但是在迁移数据的时候明明已经改了"public”."geometry"修改成st_geometry还是报错,没得到解决,最终我们打算手动些脚本去插入数据)

pg的geometry类型需要适配达梦的st_geometry才能建表成功,此外在inser插入数据的时候还需要包裹一下pg原有的wkb,所以sqlark无法迁移,我们手动的对几个表进行了处理。
1、先去pg数据库中把表数据ddl拷贝出来

2、通过java脚本修改sql脚本,把wkb包裹适配达梦insert语句
package com.yutu.icp.wisdomwater.utils;
import java.io.*;
import java.util.*;
import java.util.regex.*;
public class MyDMOut {
public static void main(String[] args) {
String inputFile = "C:\\Users\\Admin\\Desktop\\address.sql"; //原sql文件
String outputFile = "C:\\Users\\Admin\\Desktop\\address_out.sql"; //修改后输出sql文件
int targetPosition = 3; //从values开始数,wkb在第几列(从1数)
try {
convertSqlFile(inputFile, outputFile, targetPosition);
System.out.println("转换完成,结果已保存到: " + outputFile);
} catch (IOException e) {
System.err.println("处理文件时出错: " + e.getMessage());
}
}
public static void convertSqlFile(String inputFile, String outputFile, int targetPosition)
throws IOException {
// 匹配INSERT语句的正则表达式
Pattern insertPattern = Pattern.compile(
"(INSERT INTO \\\".+?\\\"\\(.*?\\)\\s*VALUES\\s*\\()(.*?)(\\)\\s*;)",
Pattern.CASE_INSENSITIVE
);
try (BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {
String line;
while ((line = reader.readLine()) != null) {
Matcher matcher = insertPattern.matcher(line);
if (matcher.find()) {
// 分割VALUES部分
String valuesPart = matcher.group(2);
List<String> values = splitValues(valuesPart);
// 检查目标位置是否有效
if (values.size() > targetPosition - 1) {
String targetValue = values.get(targetPosition - 1).trim();
// 添加DMGEO函数包装
values.set(targetPosition - 1, "DMGEO.ST_GEOMFROMWKB(" + targetValue + ",4326)");
// 重组SQL语句
String newValuesPart = String.join(",", values);
String newLine = matcher.group(1) + newValuesPart + matcher.group(3);
writer.write(newLine);
} else {
writer.write(line);
}
} else {
writer.write(line);
}
writer.newLine(); // 保持原样换行
}
}
}
// 处理包含逗号的复杂VALUES分割
private static List<String> splitValues(String valuesPart) {
List<String> values = new ArrayList<>();
boolean inQuotes = false;
int start = 0;
for (int i = 0; i < valuesPart.length(); i++) {
char c = valuesPart.charAt(i);
if (c == '\'') {
inQuotes = !inQuotes;
} else if (c == ',' && !inQuotes) {
values.add(valuesPart.substring(start, i).trim());
start = i + 1;
}
}
// 添加最后一个值
values.add(valuesPart.substring(start).trim());
return values;
}
}
你将会得到以下内容(原address.sql、修改后address_out.sql)


3、在达梦中执行sql脚本文件,我这里用的sqlark工具连的达梦,执行完后会得到这样的数据

并且可以使用dmgeo的函数进行wkb转wkt

起初以为一切进展都顺利的,但是突然发现有些表是通过超图导入的,这东西导入出现了一些问题。。。
二、超图导入数据到达梦
1、在超图中连接数据源
(如果你的DMPlus是灰色的,需要安装DM驱动放到bin目录下)
通过网盘分享的文件:超图达梦依赖.zip
链接: https://pan.baidu.com/s/1ZfQzAVN7X5Swfy5yCFlKyw?pwd=9nss 提取码: 9nss


注意了,在超图中必须选择新建数据库型数据源!!而不是打开数据库型数据源,不然会报没有系统表,且非扩展打开!!
当我们新建数据源的时候超图会自动在达梦的这个数据库中生成一堆相关的表(依赖),如果你的数据库已经有这些表了那么就可以选择打开数据库型数据源。

这些表的解释你可以看这个 https://blog.51cto.com/u_16099350/11427089 都有介绍
2、导入shp文件(测试使用,一般都是使用gdb)

导入之后会同步到达梦数据库中

但是问题又来了,使用超图导入到达梦,会发现超图生成保存空间数据的字段SmGeometry是image类型?如下图

你会发现这个类型我们无法使用dmgeo的函数进行转换

出现这个问题,是因为在超图中选择错数据源了!!!注意,不要选择DMPlus,要选择DMSpatial!!!不然就会出现类型不对。。
三、解决超图导入数据到达梦空间数据类型不对的问题(Image类型->SmGeometry)
下面给大家写个超图导入数据到超图的步骤
1、先在DM中创建模式、用户、表空间、分配角色

2、到超图中使用DMSpatial连接,一定要使用DMSpatial连!!

3、导入数据

4、在达梦中查看

你会发现,居然成功了。。。。。。历经好几天的排查,搜百度,终于发现了。。。
另外配一张我用户分配的权限仅供参考!

建议先使用sqlark迁移业务表(也就是没有空间数据的表,注意sm开头的表以及postgis生成的表都不要导过来,删除也行),然后再使用超图创建连接达梦进行导入空间数据表
四、超图SHP文件数据集同步到达梦数据库时表名超过17长度被截取丢失问题,但是同步到PG是正常的
问题截图
超图软件

达梦数据库

少量表名超17字符的解决方案
手动修改注册表
查询表名不对问题的数据:
SELECT SmDatasetName, SmTableName FROM SmRegister WHERE SmDatasetName LIKE 't_run_possess_greenland';

更新注册表表名:
UPDATE SmRegister SET SmTableName = 'T_RUN_POSSESS_GREENLAND' WHERE SmDatasetName = 't_run_possess_greenland';

修改新表名:
ALTER TABLE T_RUN_POSSESS_GRE RENAME TO T_RUN_POSSESS_GREENLAND;

超图软件中重新加载
1. 一定要先关闭当前连接

2. 重新连接

3. 修改成功
服务正常加载,表数据正常加载

五、字段名被截取以及字段丢失
1. 字段名被截取
这个问题一般是使用了shp格式导出、导入
解决办法就是直接在导出和导入的时候使用gdb格式就好了


2. 字段名丢失
这个问题一般是数据类型引起的,看超图中的控制台输出报错信息,数据精度超出范围,导致字段创建失败

问题原因以及解决办法直接看我的文章:https://blog.youkuaiyun.com/weixin_44912902/article/details/153315449
六、dmgeo.st_astext(wkb)括号前空格问题

解决:直接匹配替换
空格替换 以及 MULTIPOLYGON多个点的时候逗号后面也会出现空格,也替换掉!!!
SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(dmgeo.st_astext(SmGeometry), 'POINT (', 'POINT('), 'LINESTRING (', 'LINESTRING('), 'POLYGON ((', 'POLYGON(('), 'MULTIPOLYGON (((', 'MULTIPOLYGON((('), ', ', ','), * FROM address;


七、超图yhld表增加字段start_curing_time varchrt(255)类型,达梦中ID自增失效,需要重新手动勾选ID自增

1185

被折叠的 条评论
为什么被折叠?



