达梦数据库版本:
DM:8.1.3.26
背景:
检查数据库JOBS时,一直提示语法错误:
执行语句:
SELECT JOB,SCHEMA_USER,LAST_DATE,LAST_SEC,NEXT_DATE,FAILURES,INSTANCE,INTERVAL FROM DBA_JOBS;
最终定位到是 INTERVAL 保留字的问题;
SQL> SELECT INTERVAL FROM DBA_JOBS;
SELECT INTERVAL FROM DBA_JOBS;
SELECT INTERVAL FROM DBA_JOBS;
*
第 1 行, 第 16 列[FROM]附近出现错误[-2007]:
语法分析出错.
已用时间: 0.274(毫秒). 执行号:0.
按 * 执行,没有报错,自动转义了;
SELECT * FROM DBA_JOBS;
经测试保留字添加双引号后可以正常执行:
SELECT "INTERVAL" FROM DBA_JOBS;
不能用反引号
SQL> SELECT `INTERVAL` FROM DBA_JOBS;
SELECT `INTERVAL` FROM DBA_JOBS;
SELECT `INTERVAL` FROM DBA_JOBS;
*
第 1 行, 第 7 列[`]附近出现错误[-2007]:
语法分析出错.
已用时间: 0.235(毫秒). 执行号:0.
也不能使用单引号,会当成固定字符串。
SQL> SELECT 'INTERVAL' FROM DBA_JOBS;
行号 'INTERVAL'
---------- ----------
1 INTERVAL
2 INTERVAL
已用时间: 0.456(毫秒). 执行号:5245214.
疑问:
一.达梦保留字转义方法有哪些?
二.达梦数据库自带的系统表保留字查询时也需要特殊处理吗?
三.Oracle、MySQL数据库是否有类似情况?
一.达梦保留字转义方法有哪些?
参考链接:
https://eco.dameng.com/community/article/6ca6b591fecb40d2941e524af5fc25c9
作者:LeeWen
1.添加双引号
经测试关键字添加双引号后可以正常执行:
SELECT "INTERVAL" FROM DBA_JOBS;
2.数据库配置文件dm.ini中EXCLUDE_RESERVED_WORDS参数
EXCLUDE_RESERVED_WORDS:
语法解析时,需要去除的保留字列表,保留字之间以逗号分隔。默认为空,静态参数。
V$RESERVED_WORDS视图中RES_FIXED=N的关键字通过EXCLUDE_RESERVED_WORDS参数设置之后将会失效,V$RESERVED_WORDS视图不会再记录。
或者disql进入数据库实例,执行以下命令:
sp_set_para_string_value(2,'EXCLUDE_RESERVED_WORDS','xxx');
重启数据库服务生效
3.dm_svc.conf配置文件中KEYWORDS配置项
使用时需要注意,在dm_svc.conf文件中配置KEYWORDS时,KEYWORDS应配置在“服务配置区”中,不应直接配置到“全局配置区”。
示例:
KEYWORDS=(xxx,yyy.zzz)
4.客户端连接字符串url屏蔽指定关键字
示例:
jdbc:dm://192.1.1.100:5236/CJC?keywords=(xxx,yyy,zzz)
二.达梦数据库自带的系统表保留字查询时也需要特殊处理吗?
是的,需要转义
SELECT "INTERVAL" FROM DBA_JOBS;
三.Oracle、MySQL数据库是否有类似情况
甲骨文:11.2.0.4.0
Oracle可以正常查询
但并不是Oracle数据库自带的系统表保留字查询时不需要特殊处理,而是因为INTERVAL不是Oracle的保留字。
INTERVAL不属于保留字
for a30 col interval
where rownum<=2; select INTERVAL from dba_jobs
INTERVAL
------------------------------
sysdate + 8/24
sysdate + 10/1440
查看含有INTERVAL列的表
set pagesize 1000
set line 300
col owner for a30
select owner,table_name,column_name from dba_tab_columns where column_name='INTERVAL';
OWNER TABLE_NAME COLUMN_NAME
------------------------------ ------------------------------ ------------------------------
SYS ALL_PART_INDEXES INTERVAL
SYS DEFSCHEDULE INTERVAL
SYS DBA_JOBS INTERVAL
......
37 rows selected.
查看Oracle有哪些保留字
SET PAGESIZE 2000
SELECT ROWNUM,KEYWORD FROM V$RESERVED_WORDS WHERE RESERVED='Y';
......
查询保留字对应的表、列信息
SET LINE 300
SET PAGESIZE 3000
COL OWNER FOR A10
SELECT OWNER,TABLE_NAME,CLOUMN_NAME FROM DBA_TAB_COLUMNS WHERE COLUMN_NAME IN (SELECT KEYWORD FROM V$RESERVED_WORDS WHERE RESERVED='Y');
查询任意一张表
SELECT MODE FROM SYS.V$_DIAG_VHM_RUN where rownum<=1;
ORA-00936:missing expressioin
需要转义,也是双引号
SELECT "MODE" FROM SYS.V$_DIAG_VHM_RUN where rownum<=1;
不支持反引号、单引号转义,和达梦类似;
MySQL版本:8.0.32
查看 INTERVAL 属于MySQL保留字
SELECT RESERVED,WORD FROM INFORMATION_SCHEMA.KEYWORDS WHERE WORD='INTERVAL';
查询保留字信息
mysql> SELECT ROW_NUMBER() OVER(ORDER BY WORD) as ROW_NUM,WORD FROM INFORMATION_SCHEMA.KEYWORDS WHERE RESERVED=1 ORDER BY 2;
......
262 rows in set (0.00 sec)
保留字测试
mysql> alter table t1 add INTERVAL int;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTERVAL int' at line 1
mysql> alter table t1 add `INTERVAL` int;
Query OK, 0 rows affected (0.09 sec)
Records: 0 Duplicates: 0 Warnings: 0
需要使用反引号进行转义
mysql> select `INTERVAL` from t1;
单引号和双引号不能进行转义会被识别为固定字符
mysql> select 'INTERVAL' from t1;
mysql> select "INTERVAL" from t1;
总结:
1.达梦、Oracle、MySQL保留字名称、数量有很大差异;
例如:
INTERVAL 在 达梦和MySQL数据库中属于保留字,在Oracle中不属于保留字,如果涉及Oracle迁移达梦数据库,需要考虑保留字的影响。
2.达梦、Oracle、MySQL保留字转义方式不同;
达梦和Oracle使用双引号进行转义;
MySQL使用反引号进行转义;
3.达梦、Oracle、MySQL数据库系统表中的保留字也需要转义,和普通表无区别。
###chenjuchao 20231206###
如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!
添加我为好友,拉您入交流群!
请使用微信扫一扫!