news 2026/9/30 12:05:45

达梦数据库SQL实战:从语法兼容到迁移排错,一份能直接用的速查清单

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
达梦数据库SQL实战:从语法兼容到迁移排错,一份能直接用的速查清单

1. 这份达梦SQL清单能帮你解决哪些问题

达梦数据库(DM)在国内信创和央国企项目里出现的频率越来越高,很多原本写惯了Oracle、MySQL的人第一次接触时,最大的感受不是功能不够,而是“看着面熟,写起来处处要小心”。就拿SQL来说,达梦确实兼容了大量标准SQL和Oracle语法,可它又不完全是Oracle:同一个分页写法、同一个日期函数、同一个表名大小写规则,在不同初始化参数下可能表现不一样。没搞清楚这些差异就闷头写,大概率会被“无效的模式名”“列不存在”这种报错折腾一晚上。

我最早接触DM8是在做系统迁移的时候,项目要求把一套Oracle ERP的报表逻辑平移到达梦,业务表几十张,存储过程加上定时任务一堆,时间又紧。那段时间我把常用SQL基本挨个踩了一遍,慢慢沉淀出一套可以直接“抄”的写法。这篇文章不打算讲安装或者性能调优的大道理,就老老实实把日常开发、运维、排障中最常用的达梦SQL整理清楚:查数据怎么写、建表改表怎么写、分页用什么方案、日期和字符串函数怎么用、连不上库该查哪几条SQL、项目里接JDBC又该注意什么。

适合的人群主要有三类:刚接到达梦项目还一脸懵的Java开发;从Oracle或MySQL迁库,需要快速确认语法兼容性的DBA;还有做国产化适配,卡在连接配置和常见报错上的实施人员。读这篇文章之前不需要你有达梦基础,只要熟悉任意一种SQL,就能按目录直接找自己关心的片段。每条SQL我都尽量给到可运行的形式,并标注适用场景和容易踩的坑。

2. 达梦SQL基础:模式与对象定位

2.1 模式名加不加,差别很大

达梦里每个用户会对应一个默认模式(SCHEMA),如果只建了一个用户,登录后直接写表名通常没问题。但一旦项目里有多个用户、多套业务库,或者从Oracle迁移来了一批带用户前缀的SQL,就很容易卡在模式这块。

最常见的报错是“无效的模式名”或者“表或视图不存在”。比如我用SYSDBA登录,想去查另一个用户USER01下的表,直接写:

SELECT * FROM T_USER;

有时候能查到,有时候又报“无效的表名”,原因是当前会话所在的默认模式并不是这个表所属的模式。最稳妥的写法就是把模式名带上:

SELECT * FROM USER01.T_USER;

如果不想每条SQL都加前缀,可以在会话里切换当前模式。达梦兼容Oracle的写法:

ALTER SESSION SET CURRENT_SCHEMA = USER01;

也可以用DISQL命令:

SET SCHEMA USER01;

把当前模式切过去之后,下面不带前缀的SQL就都指向USER01了。开发中我建议MyBatis项目里统一用“模式名.表名”去写SQL,不要依赖会话级设置,因为连接池会把会话复用,切来切去容易出交叉问题。

2.2 查看用户、表和列信息的基础SQL

刚接手一个达梦库,第一件事永远是先摸清楚库里到底有哪些对象。下面这几条是我每次必敲的:

-- 查看所有用户 SELECT USERNAME, ACCOUNT_STATUS FROM ALL_USERS; -- 查看当前用户拥有的表 SELECT TABLE_NAME FROM USER_TABLES ORDER BY TABLE_NAME; -- 查看某个模式下的所有表 SELECT OWNER, TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'USER01' ORDER BY TABLE_NAME; -- 查看表的字段信息 SELECT COLUMN_NAME, DATA_TYPE, DATA_LENGTH, NULLABLE FROM ALL_TAB_COLUMNS WHERE OWNER = 'USER01' AND TABLE_NAME = 'T_USER' ORDER BY COLUMN_ID;

这些视图名和Oracle很像,但注意达梦的一些视图在不同版本里字段会略有差异。如果某条SQL报“视图不存在”或“列不存在”,先执行 DESC 或者 SELECT * FROM 视图名 WHERE ROWNUM <= 1 看下真实字段是什么,别死记硬背。

2.3 简单的查询脚本模板

新手刚开始写达梦SQL,可以先把这套“安全模板”背下来,至少不会出现方向性错误:

SELECT T.ID, T.USER_NAME, T.CREATE_TIME FROM USER01.T_USER T WHERE T.STATUS = 1 ORDER BY T.CREATE_TIME DESC;

这里有个很隐蔽的点,就是USER_NAME这种字段尽量写成下划线格式,不要写 userName 这种驼峰格式。达梦默认会做大小写转换:不带引号的标识符会被转成大写,所以 T.USER_NAME 会被解析成 T.USER_NAME;而你建表时如果没有对列名加双引号,列名实际上也是大写存储在字典里的,两者能对上。可一旦你在建表SQL里写了:

CREATE TABLE T_USER ("userId" VARCHAR(20));

那么这个列名就是大小写敏感的小写 userId,等查询时写 T.USERID 或者 T.USER_ID 都会报列无效。这一点坑了很多人。我的经验是:建表时老老实实全用大写和下划线,查询时不加双引号,最省心。

3. DDL速查:建表、索引、视图与序列

3.1 建表时字段类型怎么选

达梦的字段类型兼容得比较杂,既有Oracle风格的VARCHAR2、NUMBER,也有MySQL风格的INT、DATETIME。我建议直截了当地按照“接近Oracle”的习惯去选,这样迁Oracle项目时改动最小。

CREATE TABLE T_USER ( ID INT NOT NULL, USER_NAME VARCHAR(64) NOT NULL, AGE INT, SALARY NUMBER(10,2), BIRTHDAY DATE, CREATE_TIME DATETIME DEFAULT SYSDATE, REMARK CLOB, PRIMARY KEY (ID) );

这里几个选择我展开讲一下:

  • 主键ID建议用INT,数据量大用BIGINT,不要省这个空间,后续分库分表或者对接BI系统时大主键更稳。
  • VARCHAR和VARCHAR2在达梦里通常是一个含义,但如果初始化时开启了兼容Oracle的VARCHAR2语义,部分版本会按字节还是按字符算长度,需要跟DBA确认一下。一般我们写VARCHAR(64)默认是64个字符,但遇到中文长度问题,就说明库的语义可能偏字节,需要改成VARCHAR2(64 CHAR)。
  • CLOB字段别用VARCHAR去硬扛,达梦里超过行大小限制会直接报错,特别是存JSON或大段文字时。
  • DATETIME DEFAULT SYSDATE这招很实用,插入时就不用手工填时间了。

建表后加注释也是基本操作,不然一个月后没人看得懂:

COMMENT ON TABLE T_USER IS '用户信息表'; COMMENT ON COLUMN T_USER.USER_NAME IS '用户姓名'; COMMENT ON COLUMN T_USER.SALARY IS '月薪,单位元';

3.2 修改表结构的常用写法

业务是迭代的,表结构必然要改。达梦的ALTER TABLE语法大体接近Oracle,但有些写法得注意列关键字:

-- 追加字段 ALTER TABLE T_USER ADD COLUMN EMAIL VARCHAR(128); -- 修改字段类型 ALTER TABLE T_USER MODIFY COLUMN EMAIL VARCHAR(256); -- 修改字段默认值 ALTER TABLE T_USER MODIFY COLUMN STATUS INT DEFAULT 0; -- 删除字段 ALTER TABLE T_USER DROP COLUMN STATUS; -- 表改名 ALTER TABLE T_USER RENAME TO T_USER_NEW; -- 列改名 ALTER TABLE T_USER RENAME COLUMN USER_NAME TO REAL_NAME;

修改字段类型时有个常见坑:如果原字段已经有大量数据,VARCHAR长度从64改成128一般没事,但改成NUMBER或者DATE这种跨类型操作,大概率因为不兼容报错。这时需要新建临时列、拷贝数据、再删旧列,或者干脆用新型别建新表后INSERT INTO SELECT。别和数据库硬刚,业务数据安全才是第一位的。

3.3 索引、视图、序列

索引是SQL优化的关键利器。达梦创建索引的语法和Oracle几乎一样:

-- 普通索引 CREATE INDEX IDX_T_USER_AGE ON T_USER(AGE); -- 唯一索引 CREATE UNIQUE INDEX UK_T_USER_NAME ON T_USER(USER_NAME); -- 组合索引 CREATE INDEX IDX_T_USER_TIME ON T_USER(STATUS, CREATE_TIME DESC);

建立索引时不要一句“给所有查询字段都加索引”完事,索引建多了写入会变慢,还会占空间。我一般在慢SQL出现之后,结合执行计划去加索引,优先给WHERE条件里高频出现的字段和ORDER BY字段建组合索引。组合索引里字段顺序很关键,从左到右匹配,把区分度最高的字段放前面。

视图和序列也是日常开发少不了的:

-- 创建视图 CREATE OR REPLACE VIEW V_USER_SALARY AS SELECT T.USER_NAME, T.SALARY FROM T_USER T WHERE T.SALARY > 5000; -- 创建序列 CREATE SEQUENCE SEQ_USER_ID START WITH 10000 INCREMENT BY 1 CACHE 20; -- 取序列下一个值 SELECT SEQ_USER_ID.NEXTVAL; -- 取序列当前值 SELECT SEQ_USER_ID.CURRVAL;

使用序列时有个细节:CURRVAL只有在当前会话已经调用过NEXTVAL之后才有效,否则会报错。批量插入数据时,序列和分布式系统的高并发ID方案是两回事,别在微服务多节点环境里指望单库序列能全局唯一,除非你确定所有写入都走这个库。

4. DML和事务:查询之外必须掌握的部分

4.1 INSERT、UPDATE、DELETE的实用写法

插入单条记录没什么特别,但需要注意时间字段和序列的配合:

INSERT INTO T_USER(ID, USER_NAME, AGE, CREATE_TIME) VALUES(SEQ_USER_ID.NEXTVAL, '张三', 28, SYSDATE);

批量插入时,我推荐用INSERT ALL或者INSERT INTO SELECT方式,尽量避免在业务代码里逐条拼接INSERT语句,既慢又容易被SQL注入风险盯上:

INSERT INTO T_USER_HIS(ID, USER_NAME, AGE) SELECT ID, USER_NAME, AGE FROM T_USER WHERE STATUS = 0;

UPDATE语句的条件最好显式用主键或唯一索引。很多新手喜欢写:

UPDATE T_USER SET AGE = 30 WHERE USER_NAME = '张三';

万一USER_NAME没有唯一约束,这次更新就可能波及多条记录,得灾后复盘。稳妥做法是:

UPDATE T_USER SET AGE = 30 WHERE ID = 1001;

DELETE同样如此。需要清表时,用TRUNCATE和DELETE要想清楚区别:TRUNCATE快,但不走事务、不能按条件删、大概率无法回滚;DELETE慢,但可以配合WHERE和事务回滚。

4.2 多表关联更新与删除

达梦支持Oracle风格的多表更新语法吗?我经验是尽量用MERGE或子查询,避免一条UPDATE JOIN写出来报语法错误。推荐方案是把关联结果先查出来,再用IN匹配:

UPDATE T_USER T SET T.DEPT_NAME = (SELECT D.DEPT_NAME FROM T_DEPT D WHERE D.DEPT_ID = T.DEPT_ID) WHERE EXISTS (SELECT 1 FROM T_DEPT D WHERE D.DEPT_ID = T.DEPT_ID);

这种写法在Oracle和达梦里都能跑,迁移成本最低。删除关联表数据的场景也一样:

DELETE FROM T_USER WHERE DEPT_ID IN (SELECT DEPT_ID FROM T_DEPT WHERE DEPT_NAME LIKE '%临时%');

4.3 事务隔离与控制

达梦默认的事务行为贴近Oracle,DML语句执行后不会自动提交,需要显式COMMIT。如果你从MySQL过来,第一次跑后台定时任务时没提交事务,数据看似写进去了,另一个连接却看不到,这就很容易造成“数据丢了”的假象。

-- 开启事务(在达梦中 DML 后即自动开启事务) UPDATE T_USER SET SALARY = SALARY * 1.05 WHERE DEPT_ID = 100; -- 提交 COMMIT; -- 回滚 ROLLBACK;

在一个事务里做过多次更新后,如果发现某一步执行错,尽量别把整个事务回滚掉,可以用SAVEPOINT做定点回滚:

SAVEPOINT SP1; UPDATE T_USER SET AGE = 30 WHERE ID = 1001; ROLLBACK TO SP1;

事务越短越好。项目里出现过同事把大量清洗SQL放一个事务里跑,结果跑了半小时,锁表锁到前端系统告警。处理大数据量时,拆成批提交,每批500到1000条,既稳又快。

5. MySQL/Oracle迁移人员最需要的分页和函数写法

5.1 分页别盲目用LIMIT

从MySQL迁过来的团队,第一句通常就是 SELECT ... LIMIT 0,10,结果在达梦里直接报错。虽然达梦部分兼容模式或较新版本能支持LIMIT,但为了稳妥,我推荐直接用Oracle风格的分页,在任何模式下都不会翻车:

-- 第一种:ROWNUM SELECT * FROM ( SELECT T.*, ROWNUM RN FROM T_USER T ORDER BY T.CREATE_TIME DESC ) WHERE RN BETWEEN 1 AND 10;

不过ROWNUM是在结果集生成时分配的,如果先排序再取ROWNUM,内层必须先完成排序。上面这种写法能确保按CREATE_TIME倒序后,再取前10条。如果数据量大,更推荐用ROW_NUMBER()窗口函数:

SELECT * FROM ( SELECT T.*, ROW_NUMBER() OVER (ORDER BY T.CREATE_TIME DESC) RN FROM T_USER T ) WHERE RN BETWEEN 1 AND 10;

第二种写法可控性更强,排序字段还可以随意扩展成多列,后续做复杂分页也不怕。

5.2 日期和字符函数对照

日常取系统时间,达梦里用SYSDATE,MySQL的NOW()并不是不能用,但我吃过兼容模式的亏,后来统一用SYSDATE:

SELECT SYSDATE; SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS NOW_STR; SELECT TO_DATE('2025-06-01 12:00:00', 'YYYY-MM-DD HH24:MI:SS') AS D;

日期加减也很常用:

SELECT SYSDATE + 1 FROM ...; -- 明天同一时刻 SELECT SYSDATE - 7 FROM ...; -- 七天前 SELECT ADD_MONTHS(SYSDATE, 3) FROM ...; -- 三个月后

字符串处理方面,达梦和Oracle的兼容度很高:

-- 字符串拼接 SELECT 'ABC' || 'DEF'; -- 截取 SELECT SUBSTR('ABCDEF', 2, 3); -- 查找位置 SELECT INSTR('ABCDEF', 'CD'); -- 判断是否数字 SELECT CASE WHEN REGEXP_LIKE('12345', '^[0-9]+$') THEN 1 ELSE 0 END;

这里多提一句REGEXP_LIKE,它的正则语法和主流数据库基本一致,处理“判断手机号、身份证、金额格式”这类需求特别方便。

5.3 空值处理和去重

MySQL里 IFNULL,Oracle里 NVL,达梦两者兼容性都有,但建议统一写NVL:

SELECT NVL(AGE, 0) AS AGE_VALUE FROM T_USER; SELECT NVL2(REMARK, '有备注', '无备注') FROM T_USER;

去重时除了DISTINCT,更常用的是ROW_NUMBER()取最新一条,这个场景在报表里极常见。比如每个用户只取最近一条登录记录:

SELECT * FROM ( SELECT T.*, ROW_NUMBER() OVER (PARTITION BY USER_ID ORDER BY LOGIN_TIME DESC) RN FROM T_LOGIN T ) WHERE RN = 1;

这招比GROUP BY再取时间最大值要稳定得多,不但能拿到用户ID,还能把整行登录信息都带出来。

6. 运维排错与性能优化用的达梦SQL

6.1 查询会话、锁和正在执行的SQL

遇到达梦数据库卡顿,第一步不是重启,而是先看会话和锁。以下几条SQL是我平时排查用得最频繁的:

-- 查看当前所有会话 SELECT SESS_ID, USER_NAME, SQL_TEXT, STATE, CREATE_TIME FROM V$SESSIONS; -- 查看当前正在等待锁资源的会话 SELECT * FROM V$LOCK; -- 查看被锁对象 SELECT * FROM V$LOCKED_OBJECT;

如果发现某个会话长时间处于ACTIVE状态,且SQL_TEXT一直不变,可以先拿到SESS_ID,然后和业务方确认是否在跑大事务。确认是阻塞源后,再用系统过程杀掉会话,别在生产环境乱杀。

不同版本的达梦动态视图字段名略有不同,执行前先DESC V$SESSIONS,看一下字段列表。

6.2 慢SQL定位模板

慢SQL优化不是上来就看执行计划,而是先在库里找到“谁在慢”。下面这个模板可以直接复用:

SELECT SQL_TEXT, EXECUTIONS, TOTAL_EXEC_TIME, DISK_READS, BUFFER_GETS FROM V$SQL_AREA WHERE EXECUTIONS > 100 ORDER BY TOTAL_EXEC_TIME DESC;

跑出来的结果里,TOTAL_EXEC_TIME一列基本能让人心里有数。针对单条慢SQL,再单独看执行计划:

EXPLAIN SELECT T.USER_NAME, COUNT(*) FROM T_USER T WHERE T.CREATE_TIME >= TO_DATE('2025-01-01','YYYY-MM-DD') GROUP BY T.USER_NAME;

执行计划里如果看到“全表扫描”且表数据量在百万级以上,大概率要补索引。注意EXPLAIN只是评估计划,不完全代表真实执行开销,必要时可以用实际执行时间对比。

6.3 统计信息和分析命令

达梦的优化器依赖统计信息。建了一堆索引后,查询还是慢,有时候就是统计信息陈旧。可以手动收集:

DBMS_STATS.GATHER_TABLE_STATS('USER01', 'T_USER'); DBMS_STATS.GATHER_INDEX_STATS('USER01', 'IDX_T_USER_AGE');

大表收集统计信息会比较耗时,建议放到业务低峰期执行。也可以开启表的自动统计信息任务,但自动任务的周期和采样方式要谨慎配置,生产环境优先人工控制。

6.4 表空间和数据文件检查

DBA日常巡检至少要看表空间使用率,免得业务跑到一半报表“磁盘空间不足”:

SELECT TABLESPACE_NAME, STATUS, CONTENTS, EXTENT_MANAGEMENT FROM DBA_TABLESPACES; SELECT FILE_ID, TABLESPACE_NAME, BYTES, AUTOEXTENSIBLE FROM DBA_DATA_FILES;

表空间使用率还可以结合FILE_BLOCKS计算,但初级排查用上面两条看容量和是否自动扩展就够。

7. 开发框架和客户端连接达梦的SQL配置与常见报错

7.1 Navicat连接达梦的操作要点

现在较新版本的Navicat Premium已经支持达梦,新建连接时选择达梦数据库,默认端口是5236,用户名一般用SYSDBA,密码是安装时设置的。如果Navicat版本比较老,没有达梦类型,可以通过“自定义JDBC驱动”添加,指向达梦官方JDBC包。

连接串最关键的是驱动类和URL:

jdbc:dm://127.0.0.1:5236

JDBC驱动类名是:

dm.jdbc.driver.DmDriver

一定要用项目对应的JDBC版本,不要拿老版本驱动去连新版本数据库,否则容易出现“不支持的协议”之类的怪问题。

7.2 Spring Boot + MyBatis + Druid集成达梦配置

项目里最常见的技术栈是Spring Boot + MyBatis + Druid。接入达梦时,配置文件和MySQL没有本质区别,就是URL、驱动、方言和最后表名前缀要注意。

spring: datasource: url: jdbc:dm://127.0.0.1:5236?schema=USER01 username: USER01 password: your_password driver-class-name: dm.jdbc.driver.DmDriver type: com.alibaba.druid.pool.DruidDataSource

这里有个容易踩的坑:URL里如果写了schema=USER01,而数据库用户本身也是USER01,通常没问题;但如果你是SYSDBA身份连接,又想访问USER01模式,别光在URL里写schema,还要确认SYSDBA是否有访问USER01对象的权限,否则一查表就报“表或视图不存在”。

MyBatis的Mapper里编写达梦SQL时,尽量使用JDBC预编译的#{}参数,不要用${}直接拼接。比如:

<select id="selectByUserName" resultType="com.demo.User"> SELECT USER_NAME, AGE FROM USER01.T_USER WHERE USER_NAME = #{userName} </select>

这里#{userName}会被预编译成占位符,从源头上减少SQL注入风险。而${}会直接把字符串拼进SQL里,如果业务上必须用,比如动态排序列名,就需要用白名单校验。

7.3 常见报错排查清单

我整理了一份自己常备的排查对照表,遇到问题可以先对号入座:

报错现象大概率原因解决办法
无效的表名或视图名当前模式不对加“模式名.表名”或切换schema
无效的模式名用户名或模式不存在确认用户是否已创建,访问是否授权
列无效列名大小写问题或者字段名打错检查DESC表结构,确认列名
第X行附近出现错误SQL语法兼容性问题把Oracle/MySQL特有写法换掉,比如LIMIT
数据溢出或长度超限字段长度不够修改字段为VARCHAR2或加大长度
驱动无法连接端口或驱动版本不对确认5236端口开放,JDBC版本匹配
无法获取连接MAXCONN不足或连接池配置过高调低Druid最大连接数,适当加大数据库会话数
表或视图不存在但实际存在权限问题授权查表:GRANT SELECT ON USER01.T_USER TO USER02

7.4 达梦DISQL里的几个常用命令

开发时我习惯直接开DISQL,比图形界面轻量。几个高频命令记录一下:

-- 连接数据库 disql USER01/password@localhost:5236 -- 查看当前用户 SELECT USER; -- 显示表结构 DESC T_USER; -- 导入SQL脚本 START /tmp/test.sql; -- 设置每页行数 SET PAGESIZE 200;

脚本导入时如果文件里有大量中文注释,注意文件编码尽量UTF-8,否则DISQL可能把注释里的中文变成乱码,甚至影响执行。这是我踩过的实实在在的坑,导脚本前先用记事本另存为UTF-8无BOM总没错。

8. 几个容易被忽略的达梦SQL细节

8.1 双引号与保留字

达梦有很多保留字,比如LEVEL、TYPE、COMMENT、USER、MATCH等。如果业务表名或字段名不幸起了这种名字,不能直接用,得加双引号,但这会带来大小写敏感的后续问题。我建议遇到保留字就干脆把表名改掉,不要贪图名称简短给自己挖坑。如果改不了,必须加双引号,那建表、查询、JPA映射的每一处都得严格一致。

8.2 数据字典查询的权限

普通业务账号通常只能看到自己有权限的数据字典。比如用非管理账号查ALL_TABLES,返回结果往往不全,这不代表表不存在,而是权限不足。查不到对象时,先看当前账号是否被授予了DICTIONARY访问权限,再让DBA确认授权范围。避免拿一个业务账号去验证另一个业务账号的库表结构,结果误导排查方向。

8.3 批量操作的提交策略

定时任务里如果要清洗千万级数据,不要一把梭提交,最好按主键范围分批处理。比如每次取1万条ID区间,处理完提交一次,既能避免长事务锁定,又能让日志输出进度。实际经验是,一个超过千万行的UPDATE一次性提交,很可能会拖垮整个库,影响在线业务。

SELECT和DML的日常写法虽然看着简单,但在国产数据库上,写“稳”比写“炫”更重要。我今天给出的这些SQL都是经过真实项目和线上环境验证过的,不敢说覆盖所有DM版本,但覆盖常见的调试、开发、迁移场景足够了。最后再分享一个小习惯:我每次写到达梦的疑难SQL,都会先用EXPLAIN看执行计划,再在测试库跑一遍,确认无误后才会拿到生产环境执行,这套习惯帮我避开了不少次“数据库无响应”的险情。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 12:03:36

C语言指针本质:从内存物理结构到工程级实操指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 12:01:37

数据库增删改查实战:从索引优化到事务与安全删除

1. 增删改查的本质与整体设计思路聊数据库&#xff0c;绕不开的永远是这四个字&#xff1a;增删改查。说句实在话&#xff0c;我入行这些年&#xff0c;经手的业务系统少说也有几十个&#xff0c;从早期的单机管理软件&#xff0c;到后来基于微服务架构的中台系统&#xff0c;无…

作者头像 李华
网站建设 2026/9/30 12:01:26

Oracle数据库开源监控方案:oracledb_exporter+Prometheus+Grafana实战

如果你们公司还有Oracle数据库在跑&#xff0c;我猜你对它的监控状态大概率是不满意的。MySQL有现成的mysqld_exporter&#xff0c;PostgreSQL有pg_stat_statements&#xff0c;唯独Oracle在Prometheus生态里像个后妈养的孩子&#xff0c;搜遍全网都是Oracle Enterprise Manage…

作者头像 李华
网站建设 2026/9/30 12:00:50

C++模板元编程:从黑魔法到现代编译期计算的性能进化

很多C开发者听到“模板元编程”这五个字&#xff0c;第一反应往往是&#xff1a;那是大神用来炫技的黑魔法&#xff0c;跟我没关系。我入行这些年&#xff0c;见过太多人一提到模板就把头摇成拨浪鼓&#xff0c;觉得那是《C Templates》里才有的高阶玩法&#xff0c;是只有写Bo…

作者头像 李华
网站建设 2026/9/30 12:00:08

npm.ps1无法加载?一文搞定PowerShell执行策略报错

很多朋友第一次在Windows上跑前端项目时&#xff0c;都会撞上同一个报错&#xff1a;装好了Node.js&#xff0c;兴冲冲地在项目目录里敲下npm run dev&#xff0c;结果终端毫不留情地弹出一行红字——npm : 无法加载文件 D:\app\nodejs\npm.ps1&#xff0c;因为在此系统上禁止运…

作者头像 李华
网站建设 2026/9/30 11:59:42

CSP第一题满分攻略:签到题题型、读入输出与边界条件汇总

CSP 第一题在选手圈子里有个外号叫"签到题"&#xff0c;意思是你进考场先把这题的分揣兜里&#xff0c;再去啃后面那些真正要动脑子的。但有意思的是&#xff0c;每年考完总有人在群里喊"第一题只过了 60%"&#xff0c;问题往往不是不会写&#xff0c;而是…

作者头像 李华