【人大金仓】人大金仓数据库V9函数 sys.concat()不存在的问题解决方案

博主介绍:✌全网粉丝24W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌

技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。

感兴趣的可以先关注收藏起来,在工作中、生活上等遇到相关问题都可以给我留言咨询,希望帮助更多的人。
技术扩展 :最近发现了一个特别好用的人工智能学习网站,通俗易懂,风趣幽默,忍不住想分享一下给大家,进入传送门:https://www.captainbed.cn/no8g/

人大金仓数据库V9函数 sys.concat不存在的问题解决方案

  • 一、现象描述
  • 二、问题原因
    • [2.1 人大金仓 9 对`concat`函数参数类型校验更严格](#2.1 人大金仓 9 对concat函数参数类型校验更严格)
    • [2.2 原生 `concat` 仅支持两个入参](#2.2 原生 concat 仅支持两个入参)
    • [2.3 数据库模式为兼容oracle数据库](#2.3 数据库模式为兼容oracle数据库)
  • 三、解决方案
    • [3.1 方案一:使用 `||` 字符串拼接符(金仓 / PostgreSQL 原生推荐)](#3.1 方案一:使用 || 字符串拼接符(金仓 / PostgreSQL 原生推荐))
    • [3.2 方案二:全局兼容(自定义 concat 函数,不推荐临时查询用)](#3.2 方案二:全局兼容(自定义 concat 函数,不推荐临时查询用))
  • 四、补充说明

首先确定的一点是人大金仓V9版本中是有 concat() 函数的。只不过是金仓 9 的 concat() 不支持多参数拼接 (仅支持 2 个参数),这是根源,单纯转类型没用。

一、现象描述

开发环境部署的是人大金仓V8版本数据库,测试环境是人大金仓V9版本的数据库。在执行以下 SQL 时开发环境的V8数据库能正常执行,而到了测试环境的V9版本的数据库时居然报错。

sql 复制代码
SELECT
  fa.*,
  traintypedic.dict_label AS train_type_name,
  hi.thread_slug,
  faultHandledic.dict_label AS fault_state_name,
  bdi.driver_name AS driver_name,
  fard.*,
  concat ( train_type_name, '-', fa.train_no, '-', fa.train_port ) AS train_no_ext,
  concat ( train_type_name, '-', fa.train_no, '-', fa.train_port ) AS vr_name,
  concat ( train_type_name, '-', fa.train_no, '-', fa.train_port ) AS model_name 
FROM
  faultalarm fa
  LEFT JOIN faultalarm_rundetail fard ON fa.ID = fard.alarm_id
  LEFT JOIN base_driverinfo bdi ON fa.driver_code = bdi.driver_code
  LEFT JOIN sys_dict_data traintypedic ON traintypedic.dict_value = fa.train_type 
  AND traintypedic.dict_type = 'train_type'
  LEFT JOIN sys_dict_data faultHandledic ON faultHandledic.dict_value = fa.fault_state 
  AND faultHandledic.dict_type = 'fault_handle_state'
  LEFT JOIN handinfo hi ON hi.ID = fa.handinfo_id 

ORDER BY
  fa.fault_time DESC

报错详情如下:

bash 复制代码
11:37:56.748 [http-nio-28088-exec-21] ERROR c.l.f.w.e.GlobalExceptionHandler - [handleRuntimeException,119] - 请求地址'/fh/handinfo/realTimeDataByTrainNum/E',发生未知异常.
org.springframework.jdbc.BadSqlGrammarException: 
### Error querying database.  Cause: com.kingbase8.util.KSQLException: ERROR: 函数 sys.concat(varchar, unknown, varchar, unknown, varchar) 不存在
  Hint: 没有匹配指定名称和参数类型的函数. 您也许需要增加明确的类型转换.
  Position: 578 At Line: 7, Line Position: 16
### The error may exist in URL [jar:nested:/home/leg/leg-server/lib/leg-admin-V1.0.0.2.jar/!BOOT-INF/lib/leg-service-1.0.0.jar!/mapper/FhFaultalarmMapper.xml]
### The error may involve com.leg.service.mapper.FhFaultalarmMapper.selectFhFaultalarmList-Inline
### The error occurred while setting parameters
### SQL: select fa.id, fa.fault_code, fa.fault_content, fa.fault_time, fa.train_type, fa.train_no, fa.train_port,                fa.train_num, fa.train_id, fa.driver_code, fa.fault_state, fa.create_time, fa.handinfo_id,                traintypedic.dict_label as train_type_name, hi.thread_slug,                faultHandledic.dict_label as fault_state_name, bdi.driver_name as driver_name,                fard.train_speed, fard.run_route, fard.run_line, fard.run_dir, fard.run_mileage, fard.ahead_signal,                fard.ahead_station, fard.ahead_phasesplit_distance,                concat(train_type_name, '-', fa.train_no, '-', fa.train_port) as train_no_ext,                concat(train_type_name, '-', fa.train_no, '-', fa.train_port) as vr_name,                concat(train_type_name, '-', fa.train_no, '-', fa.train_port) as model_name         from fh_faultalarm fa         left join fh_faultalarm_rundetail fard on fa.id = fard.alarm_id         left join base_driverinfo bdi on fa.driver_code = bdi.driver_code         left join sys_dict_data traintypedic on traintypedic.dict_value=fa.train_type and traintypedic.dict_type='train_type'         left join sys_dict_data faultHandledic on faultHandledic.dict_value=fa.fault_state and faultHandledic.dict_type='fault_handle_state'         left join fh_handinfo hi on hi.id = fa.handinfo_id                WHERE  fa.fault_time >= ?                                           AND fa.fault_time <= ?          order by fa.fault_time desc
### Cause: com.kingbase8.util.KSQLException: ERROR: 函数 sys.concat(varchar, unknown, varchar, unknown, varchar) 不存在
  Hint: 没有匹配指定名称和参数类型的函数. 您也许需要增加明确的类型转换.
  Position: 578 At Line: 7, Line Position: 16
; bad SQL grammar []
        at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:112)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:107)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:116)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:116)
        at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:92)
        at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439)
        at jdk.proxy2/jdk.proxy2.$Proxy94.selectList(Unknown Source)

二、问题原因

2.1 人大金仓 9 对concat函数参数类型校验更严格

人大金仓 9 对concat函数参数类型校验更严格'-'字面量被识别为unknown类型,和字段varchar类型混用时,无法匹配内置concat函数,金仓 8 兼容宽松所以正常执行。

2.2 原生 concat 仅支持两个入参

人大金仓 9 内核限制:原生 concat 仅支持两个入参,不支持多参数,所以 5 个参数直接报错。

2.3 数据库模式为兼容oracle数据库

sql 复制代码
# 可以查看数据库的兼容模式,使用以下 sql 语句
SHOW database_mode;
# 此处应该会显示 oracle,兼容oracle模式下也会导致上面报错。

人大金仓V9版本想安装成适配pg 版本的,结果安装后使用 show database_mode 语句查询出来的是 oracle,怎么办呢?别担心,安装完成后发现模式不对,这个问题完全可以解决,而且不用重装整个软件。如果想变更模式,可以参考我写的另一篇文章。

我将数据库模式从 oracle 修改为 pg 之后就不再报上面的错误了。

三、解决方案

3.1 方案一:使用 || 字符串拼接符(金仓 / PostgreSQL 原生推荐)

金仓完全兼容 || 拼接,无需类型转换,语法更简洁:

sql 复制代码
train_type_name || '-' || fa.train_no || '-' || fa.train_port AS train_no_ext,
train_type_name || '-' || fa.train_no || '-' || fa.train_port AS vr_name,
train_type_name || '-' || fa.train_no || '-' || fa.train_port AS model_name

完整 SQL 替换对应行即可。

即完整的SQL如下:

sql 复制代码
SELECT
  fa.*,
  traintypedic.dict_label AS train_type_name,
  hi.thread_slug,
  faultHandledic.dict_label AS fault_state_name,
  bdi.driver_name AS driver_name,
  fard.train_speed,
  fard.run_route,
  fard.run_line,
  fard.run_dir,
  fard.run_mileage,
  fard.ahead_signal,
  fard.ahead_station,
  fard.ahead_phasesplit_distance,
  train_type_name || '-' || fa.train_no || '-' || fa.train_port AS train_no_ext,
  train_type_name || '-' || fa.train_no || '-' || fa.train_port AS vr_name,
  train_type_name || '-' || fa.train_no || '-' || fa.train_port AS model_name
FROM
  faultalarm fa
  LEFT JOIN faultalarm_rundetail fard ON fa.ID = fard.alarm_id
  LEFT JOIN base_driverinfo bdi ON fa.driver_code = bdi.driver_code
  LEFT JOIN sys_dict_data traintypedic ON traintypedic.dict_value = fa.train_type 
  AND traintypedic.dict_type = 'train_type'
  LEFT JOIN sys_dict_data faultHandledic ON faultHandledic.dict_value = fa.fault_state 
  AND faultHandledic.dict_type = 'fault_handle_state'
  LEFT JOIN handinfo hi ON hi.ID = fa.handinfo_id 

ORDER BY
  fa.fault_time DESC;

3.2 方案二:全局兼容(自定义 concat 函数,不推荐临时查询用)

如果大量老 SQL 都有该问题,可创建兼容函数(仅执行一次):

sql 复制代码
CREATE OR REPLACE FUNCTION sys.concat(VARIADIC args anyarray)
RETURNS text AS $$
BEGIN
  RETURN array_to_string(args, '');
END;
$$ LANGUAGE plpgsql IMMUTABLE;

注意:该方案影响全库,优先用方案 1

四、补充说明

  1. 人大金仓 9 基于 PostgreSQL 高版本内核,类型推断更严谨,这是和 V8 的核心差异;
  2. 业务 SQL 优先使用 || 做字符串拼接,是 PG 系数据库标准写法,跨版本最稳定;
  3. 三条拼接内容完全一致,也可以用子查询 / CTE 只计算一次,优化性能。

好了,今天分享到这里。希望你喜欢这次的探索之旅!不要忘记 "点赞" 和 "关注" 哦,我们下次见!🎈

本文完结!

祝各位大佬和小伙伴身体健康,万事如意,发财暴富,扫下方二维码与我一起交流!!!

相关推荐
丷丩1 天前
Postgresql基础实践教程(十一)各种Join
数据库·postgresql·join
星夜夏空991 天前
FreeRTOS学习(4)——内存映射
数据库·学习·mongodb
TheRouter1 天前
AI Agent 记忆体系建设实战:短期、长期与工作记忆的工程实现
数据库·人工智能·oracle
Omics Pro1 天前
首个!外源天然产物综合性代谢图谱
数据库·人工智能·算法·机器学习·r语言
JAVA面经实录9171 天前
Hibernate面试题库
数据库·oracle·hibernate
迷枫7121 天前
DM8 目录结构与常用排查入口梳理
服务器·数据库
Mr.Daozhi1 天前
RAG 进阶实战:跑通 Demo 后我连续翻了 6 次车,逐一修复才真正可用(含 Gradio Web 版)
前端·数据库·langchain·大模型·gradio·rag·科研工具
小程故事多_801 天前
Claude Code自定义workflow skills用法
数据库·人工智能·智能体
大鹏说大话1 天前
SQL 排序与分组实战:解决“分组后取最新数据“
android·java·数据库
夏贰四1 天前
数据建模工具如何筑牢数据根基?数据建模工具怎样落实标准体系?
数据库·数学建模·数据建模工具