暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle、MySQL、达梦数据库保留字问题对比

IT小Chen 2023-12-07
1460

达梦数据库版本:

    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.

                疑问:

                  一.达梦保留字转义方法有哪些?
                  二.达梦数据库自带的系统表保留字查询时也需要特殊处理吗?
                  .OracleMySQL数据库是否有类似情况?

                  一.达梦保留字转义方法有哪些?

                  参考链接:

                    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数据库是否有类似情况

                                Oracle:11.2.0.4.0

                                Oracle可以正常查询

                                但并不是Oracle数据库自带的系统表保留字查询时不需要特殊处理,而是因为INTERVAL不是Oracle的保留字。

                                INTERVAL不属于保留字

                                  SQL> col interval for a30
                                  SQL> select INTERVAL from dba_jobs where rownum<=2;
                                  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###

                                                        文章转载自IT小Chen,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                                        评论