背景
- 数据库版本------ 3.1.0
- 模式-------------- A
问题
客户反馈,使用 DBeaver 工具连接磐维进行SQL查询时,列名或列别名的结果集大小写处理规则如下:
-
无双引号 别名:自动转为全大写
如 SELECT col AS my_alias 显示为 MY_ALIAS。 -
有双引号 全小写别名:转为全大写
如 SELECT col AS “myalias” 显示为 MYALIAS,与 oracle 行为不一致。 -
有双引号 全大写/大小写混合别名:保留双引号内形式
如 SELECT col AS “MyAlias” 显示为 MyAlias。
定位
- 更换成最新版驱动没有问题;
- 后来发现实际是 更换驱动的测试用例 连接串参数不同,加上 db_compatibility=oracle 后,问题复现。
相关参数
详见文档。
jdbc 参数
- db_compatibility
可选值:postgresql(默认)、oracle、mysql
作用:设置返回的对象名大小写,以及一些兼容特性。
文档中已说明加双引号的全小写别名会转为全大写。
- resultCaseMode
可选值:lower(默认)、upper
作用:设置当前连接的result_case_mode
内核参数
内核参数
-
result_case_mode(仅a模式支持)
可选值:lower(默认)、upper
作用:设置返回字段名的大小写,仅支持在会话中配置。
-
uppercase_attribute_name
可选值:off(默认)、on
作用:设置列名是否以大写形式返回。
-
enable_ignore_ident_case
可选值:off(默认)、on
作用:设置双引号内标识符的大小写解析逻辑。
-
lower_case_column_names(仅b模式支持)
测试
测试用例
CREATE TABLE test_0305(
name varchar(10)
);
insert into test_0305 values ('a');
复制
--set result_case_mode="upper";
--set uppercase_attribute_name=on;
--set enable_ignore_ident_case=on;
select
name,
Name,
NAME,
name as name,
name as Name,
name as NAME,
name as name_1,
name as "name",
name as "Name",
name as "NAME",
name as "name_1"
from test_0305;
复制
show result_case_mode;
show uppercase_attribute_name;
show enable_ignore_ident_case;
set result_case_mode="lower";
set uppercase_attribute_name=off;
set enable_ignore_ident_case=off;
复制
Oracle 测试
使用 sql plus 测试:
- 无双引号 别名:转为大写;
- 有双引号 别名:保持引号内形式。
NAME NAME NAME
---------- ---------- ----------
a a a
NAME NAME NAME NAME_1
---------- ---------- ---------- ----------
a a a a
name Name NAME name_1
---------- ---------- ---------- ----------
a a a a
复制
Panwei 测试
- 数据库版本:PanWeiDB_V2.0-S3.0.1_B01 A模式
- 驱动版本:PanWeiDB-V2.0-JDBC-3.1.0_B01.tar.gz
0. 初始环境
内核参数设置
- result_case_mode: lower
- uppercase_attribute_name: off
- enable_ignore_ident_case: off
不加参数测试
- 无双引号 别名:转为全小写;
- 有双引号 别名:保持引号内形式。
name|name|name| name|name|name|name_1| name|Name|NAME|name_1| ----+----+----+ ----+----+----+------+ ----+----+----+------+ a |a |a | a |a |a |a | a |a |a |a |
复制
1. JDBC 参数测试
1.1 加上 jdbc 参数 db_compatibility=oracle
- 无双引号 别名:转为全大写;
- 有双引号 全小写别名:转为全大写;
- 有双引号 全大写/大小写混合别名:保持引号内形式。
NAME|NAME|NAME| NAME|NAME|NAME|NAME_1| NAME|Name|NAME|NAME_1| ----+----+----+ ----+----+----+------+ ----+----+----+------+ a |a |a | a |a |a |a | a |a |a |a |
复制
1.2 加上 jdbc 参数 resultCaseMode=upper
- 无双引号 别名:转为大全写;
- 有双引号 别名:保持引号内形式;
- 和 Oracle 行为一致。
NAME|NAME|NAME| NAME|NAME|NAME|NAME_1| name|Name|NAME|name_1| ----+----+----+ ----+----+----+------+ ----+----+----+------+ a |a |a | a |a |a |a | a |a |a |a |
复制
1.3 加上 jdbc 参数 db_compatibility=oracle 和 resultCaseMode=upper
- 无双引号 别名:转为全大写;
- 有双引号 全小写别名:转为全大写(说明 db_compatibility=oracle 优先级更高);
- 有双引号 全大写/大小写混合别名:保持引号内形式。
NAME|NAME|NAME| NAME|NAME|NAME|NAME_1| NAME|Name|NAME|NAME_1| ----+----+----+ ----+----+----+------+ ----+----+----+------+ a |a |a | a |a |a |a | a |a |a |a |
复制
2. 内核参数测试
不带任何 JDBC 参数。
2.1 加上内核参数 result_case_mode=upper
- 无双引号 别名:转为全大写;
- 有双引号 别名:保持引号内形式;
- 效果和 jdbc 参数 resultCaseMode=upper 一样,符合预期。
NAME|NAME|NAME| NAME|NAME|NAME|NAME_1| name|Name|NAME|name_1| ----+----+----+ ----+----+----+------+ ----+----+----+------+ a |a |a | a |a |a |a | a |a |a |a |
复制
2.2 加上内核参数 uppercase_attribute_name=on
- 无双引号 别名:转为全大写;
- 有双引号 全小写别名:转为全大写;
- 有双引号 全大写/大小写混合别名:保持引号内形式。
NAME|NAME|NAME| NAME|NAME|NAME|NAME_1| NAME|Name|NAME|NAME_1| ----+----+----+ ----+----+----+------+ ----+----+----+------+ a |a |a | a |a |a |a | a |a |a |a |
复制
2.3 加上内核参数 enable_ignore_ident_case=on
- 无双引号 别名:转为全小写(该参数不干预不加引号时,别名的处理逻辑);
- 有双引号 别名:转为全小写(原因是在解析阶段,引号内的别名被转为了小写)。
name|name|name| name|name|name|name_1| name|name|name|name_1| ----+----+----+ ----+----+----+------+ ----+----+----+------+ a |a |a | a |a |a |a | a |a |a |a |
复制
2.4 加上内核参数 result_case_mode=upper 和 enable_ignore_ident_case=on
- 无双引号 别名:转为全大写;
- 有双引号 别名:转为全小写(说明 enable_ignore_ident_case=on 优先级更高)。
NAME|NAME|NAME| NAME|NAME|NAME|NAME_1| name|name|name|name_1| ----+----+----+ ----+----+----+------+ ----+----+----+------+ a |a |a | a |a |a |a | a |a |a |a |
复制
2.5 加上内核参数 result_case_mode=upper 和 uppercase_attribute_name=on
- 无双引号 别名:转为全大写;
- 有双引号 全小写别名:转为全大写(说明 uppercase_attribute_name=on 优先级更高);
- 有双引号 全大写/大小写混合别名:保持引号内形式。
NAME|NAME|NAME| NAME|NAME|NAME|NAME_1| NAME|Name|NAME|NAME_1| ----+----+----+ ----+----+----+------+ ----+----+----+------+ a |a |a | a |a |a |a | a |a |a |a |
复制
测试结论
在设置内核参数 uppercase_attribute_name: off、enable_ignore_ident_case: off 的情况下,设置 JDBC 参数 resultCaseMode=upper 或内核参数 result_case_mode=upper,可以在使用别名的情况下,使结果集中列名大小写的处理和 Oracle 保持一致。
解决
JDBC 连接串去掉参数 db_compatibility=oracle,加上 resultCaseMode=upper,问题解决。