普通网友 2026-03-10 05:50 采纳率: 98.4%
浏览 5
已采纳

DM是什么数据库?它与Oracle、MySQL有哪些核心区别?

DM(达梦数据库)是国产高性能关系型数据库管理系统,由武汉达梦公司自主研发,具备完全自主知识产权,广泛应用于党政、金融、能源等关键领域。它兼容SQL标准,支持Oracle风格语法(如PL/SQL、同义词、DBLink),也提供MySQL模式适配。与Oracle相比,DM在存储过程语法、数据字典视图、权限模型上高度相似,但缺少RAC集群、ADG实时备库等企业级高可用特性;与MySQL相比,DM采用共享内存+多线程架构(非进程模型),事务默认强一致性(无“可重复读”幻读例外),且原生支持行列混合存储、透明加密、三权分立等安全机制。常见技术问题:**迁移Oracle应用至DM时,为何部分PL/SQL包编译失败?——主因是DM对自治事务、动态SQL(EXECUTE IMMEDIATE)的语法约束更严格,且不支持某些Oracle专有包(如UTL_FILE需替换为DM_FILE)**。
  • 写回答

1条回答 默认 最新

  • 大乘虚怀苦 2026-03-10 09:26
    关注
    ```html

    一、现象层:PL/SQL包编译失败的典型表现

    在Oracle→DM迁移过程中,开发人员常遇到CREATE OR REPLACE PACKAGEBODY语句执行报错,如:ERROR: [DM] PL/SQL: compilation unit analysis terminatedORA-06550: line X, column Y: PLS-00103: Encountered the symbol "..."。这类错误高频集中于含PRAGMA AUTONOMOUS_TRANSACTION、嵌套动态SQL块、UTL_FILE.FOPEN调用、DBMS_OUTPUT.PUT_LINE非标准用法等场景。

    二、语法层:DM对PL/SQL兼容性的“形似神异”特性

    • 自治事务(AUTONOMOUS_TRANSACTION):DM要求PRAGMA AUTONOMOUS_TRANSACTION必须置于过程/函数声明的最顶层(即紧随ASIS之后),且不支持在匿名块中声明;Oracle允许更宽松的位置。
    • EXECUTE IMMEDIATE:DM强制要求动态SQL字符串必须为VARCHAR2类型(不可为CLOB),且绑定变量数量与占位符:var必须严格一一对应,无隐式类型转换容错。
    • 异常处理块:DM不支持WHEN OTHERS THEN RAISE;后接DBMS_UTILITY.FORMAT_ERROR_BACKTRACE——该函数未实现。

    三、生态层:Oracle专有包的DM替代矩阵

    Oracle原生包DM等效方案关键差异说明
    UTL_FILEDM_FILE(需显式GRANT EXECUTE ON DM_FILE TO user文件路径仅支持数据库配置项EXTERNAL_DIRECTORY白名单目录,不继承OS用户权限
    DBMS_LOB原生支持TO_CLOB/DBMS_LOB.SUBSTR,但DBMS_LOB.CREATETEMPORARY需改用EMPTY_CLOB()临时LOB生命周期绑定会话,不支持跨事务持久化
    DBMS_SCHEDULER暂不支持,需替换为操作系统级crontab + disql -c "CALL ..."脚本调用DM 8.4起提供DBMS_JOB基础版,功能远弱于Scheduler

    四、架构层:共享内存+多线程模型引发的隐性约束

    DM采用单实例共享内存架构(非Oracle RAC多实例),其PL/SQL引擎运行于数据库服务进程内核线程中,导致:

    • 全局变量(PACKAGE VARIABLE)在会话内持久,但**不可跨连接共享**(区别于Oracle的SGA共享池变量);
    • 递归调用深度限制为128层(Oracle默认255),超限触发ORA-00600 internal error
    • 动态SQL执行时,EXECUTE IMMEDIATE 'SELECT ... INTO :x FROM DUAL'中的INTO子句必须为单列标量,不支持记录类型(%ROWTYPE)直接赋值。

    五、诊断层:四步定位法(从日志到字节码)

    1. 启用编译追踪:在disql中执行SET SHOW ERROR ON + SHOW ERRORS PACKAGE pkg_name获取精确行号;
    2. 检查数据字典:查询USER_ERRORS视图(与Oracle同名),字段ATTRIBUTE'PLS'前缀错误码;
    3. 比对语法树:使用SELECT DBMS_METADATA.GET_DDL('PACKAGE','PKG_NAME') FROM DUAL导出DDL,在DM管理工具中逐行粘贴验证;
    4. 启用内核日志:修改dm.iniSVR_LOG = 1 + SVR_LOG_NAME = plsql_debug,复现编译操作后分析dm_SVR_LOG_*.log

    六、解决层:迁移加固最佳实践

    graph TD A[源Oracle PL/SQL代码] --> B{静态扫描} B -->|发现UTL_FILE| C[替换为DM_FILE + 目录授权] B -->|含AUTONOMOUS_TRANSACTION| D[重构为独立事务过程 + 显式COMMIT] B -->|动态SQL含CLOB参数| E[强制CAST为VARCHAR2(32767)] B -->|DBMS_OUTPUT调用| F[封装为LOG_TABLE插入 + 定时清理] C --> G[编译验证] D --> G E --> G F --> G G --> H[通过DM性能压测验证事务一致性]

    七、演进层:DM 8.5+对PL/SQL的增强方向

    根据达梦2023技术白皮书,后续版本将重点突破:

    • 支持PRAGMA SERIALLY_REUSABLE(序列可重用包状态);
    • 引入DBMS_SQL完整实现(当前仅支持基础解析/绑定/执行);
    • 增加JSON_OBJECT_T等原生JSON类型操作函数,替代UTL_JSON
    • 计划在V9版本实现DBMS_SCHEDULER核心能力(作业链、窗口调度、邮件通知)。

    八、安全层:“三权分立”机制对PL/SQL部署的影响

    DM强制实施系统管理员(SYSDBA)、安全管理员(SYSSSO)、审计管理员(SYSAUDITOR)三权分立。这意味着:

    • 创建存储过程需同时具备CREATE PROCEDURE权限(由SYSDBA授予)和EXECUTE ANY PROCEDURE(由SYSSSO审批);
    • 涉及DM_FILE的包,必须由SYSSSO执行GRANT DIRECTORY ON ext_dir TO user,否则编译通过但运行时报ORA-29280: invalid directory path
    • 所有PL/SQL对象创建/修改操作均被SYSAUDITOR自动记录至SYSAUDITOR.AUD$审计表,不可绕过。
    ```
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 3月11日
  • 创建了问题 3月10日