Posted by zengchengjie on Monday, January 1, 0001

达梦数据库 改造

问题:

达梦 ### The error occurred while executing a query SQL: SELECT LISTAGG(name, ‘,') WITHIN GROUP (ORDER BY name) AS names FROM inm_db.app_management WHERE INSTR(’,' || ? || ‘,’, ‘,’ || id || ‘,') > 0 Cause: dm.jdbc.driver.DMException: 第3 行附近出现错误: 无效的模式名[inm_db]

在将 SQL 语句从 MySQL 切换到达梦数据库(DM Database)时,需要注意达梦数据库对某些函数和语法的支持情况。根据你提供的 SQL 语句,达梦数据库不支持 WM_CONCATFIND_IN_SET 函数。以下是具体的分析和解决方法:

1. 分析问题

1.1 WM_CONCAT 函数

  • MySQLWM_CONCAT 是 MySQL 的一个非标准函数,用于将多行数据连接成一个字符串。
  • 达梦数据库:达梦数据库不支持 WM_CONCAT 函数。可以使用 LISTAGG 函数来实现相同的功能。

1.2 FIND_IN_SET 函数

  • MySQLFIND_IN_SET 函数用于检查一个字符串是否在以逗号分隔的字符串列表中。
  • 达梦数据库:达梦数据库不支持 FIND_IN_SET 函数。可以使用 INSTR 函数来实现相同的功能。

2. 修改 SQL 语句

2.1 替换 WM_CONCATLISTAGG

达梦数据库提供了 LISTAGG 函数来实现字符串连接的功能。

LISTAGG(name, ',') WITHIN GROUP (ORDER BY name) AS names

2.2 替换 FIND_IN_SETINSTR

达梦数据库可以使用 INSTR 函数来检查一个字符串是否在另一个字符串中。

INSTR(',' || #{appId} || ',', ',' || id || ',') > 0

3. 修改后的 SQL 语句

以下是修改后的 RequirementMapper.xml 中的 SQL 语句:

<select id="selectNamesByAppIds" resultType="String">
    SELECT LISTAGG(name, ',') WITHIN GROUP (ORDER BY name) AS names
    FROM inm_db.app_management
    WHERE INSTR(',' || #{appId} || ',', ',' || id || ',') > 0
</select>

4. 完整示例

以下是完整的 RequirementMapper.xml 示例:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ctsi.ssdc.mapper.RequirementMapper">

    <select id="selectNamesByAppIds" resultType="String">
        SELECT LISTAGG(name, ',') WITHIN GROUP (ORDER BY name) AS names
        FROM inm_db.app_management
        WHERE INSTR(',' || #{appId} || ',', ',' || id || ',') > 0
    </select>

    <!-- 其他 SQL 语句 -->

</mapper>

5. 解释修改

5.1 LISTAGG 函数

LISTAGG 函数用于将多行数据连接成一个字符串,并支持指定分隔符和排序。

LISTAGG(name, ',') WITHIN GROUP (ORDER BY name) AS names

5.2 INSTR 函数

INSTR 函数用于检查一个字符串是否在另一个字符串中。通过在 #{appId}id 周围添加逗号,可以确保精确匹配。

WHERE INSTR(',' || #{appId} || ',', ',' || id || ',') > 0

6. 测试 SQL 语句

在达梦数据库中直接执行修改后的 SQL 语句,确保语法正确且能够返回预期的结果。

示例

SELECT LISTAGG(name, ',') WITHIN GROUP (ORDER BY name) AS names
FROM inm_db.app_management
WHERE INSTR(',1,2,3,', ',' || id || ',') > 0;

7. 检查日志和错误信息

确保日志级别设置为 debugtrace,以便获取详细的日志信息,帮助排查问题。

logging:
   level:
      ROOT: debug
      com.ctsi: debug

8. 参考达梦数据库文档

参考达梦数据库的官方文档,确保所有 SQL 语句和配置都符合达梦数据库的要求。文档通常会提供详细的语法和配置示例。

总结

通过以上步骤,你可以解决 RequirementMapper.xml 中的达梦数据库语法错误。确保使用达梦数据库支持的函数和语法,并在达梦数据库中直接测试 SQL 语句,确保语法正确且能够返回预期的结果。如果问题仍然存在,请提供具体的错误信息和日志,以便进一步排查。

以下是完整的修改后的 RequirementMapper.xml 部分:

<select id="selectNamesByAppIds" resultType="String">
    SELECT LISTAGG(name, ',') WITHIN GROUP (ORDER BY name) AS names
    FROM inm_db.app_management
    WHERE INSTR(',' || #{appId} || ',', ',' || id || ',') > 0
</select>

确保这些修改已经应用到你的项目中,并重新启动应用程序进行测试。