用织梦建站久了,后台文档列表里偶尔会冒出一些让人摸不着头脑的记录——既没有标题,正文也是空的,但确确实实占着一条数据。这种情况多半是采集插件闹的,或者当年发布文章时标题过滤规则写得太严,把不该滤掉的也滤掉了,最后在数据库里留下一堆半成品。直接在后台删吧,列表里根本看不到编辑入口,勾选框点了也没反应,其实这些记录本身没多少大碍,但数量攒多了会在列表页显示一串空链接,既不美观,也不利于搜索引擎抓取,该清还是得清。
处理这个麻烦得从根源上入手。先说个最简单的办法,织梦后台自带一个SQL命令行工具,位置在后台的“系统”菜单里,找到“SQL命令行工具”这一项,打开之后可以直接执行数据库查询。不过动SQL之前建议先把数据库导出一份备份,谁也不敢保证手一抖就删错表,多个备份多一层保险。
想找出这些废物记录,关键得知道织梦的数据库结构。文档的基本信息存在dede_archives这张表里,标题字段叫title,正文存在dede_addonarticle表里,正文内容字段叫body。那些没标题没内容的文档,通常就是title字段是空的,或者只有几个空格,同时body字段也是空的。用下面这条SQL可以把它们揪出来:
SELECT * FROM dede_archives WHERE title='''' OR title IS NULL
查出来之后别急着删,先看一眼结果里有没有误伤的。有些用户发布文章时标题就是空的,但正文有内容,这种不算纯废物,手动补个标题就能继续用。真正要清理的是那种标题和正文都空着的,所以更稳妥的查法是关联两张表,看哪些记录两张表里都是空的:

SELECT a.id FROM dede_archives a LEFT JOIN dede_addonarticle b ON a.id=b.aid WHERE (a.title='''' OR a.title IS NULL) AND (b.body='''' OR b.body IS NULL)
确认好要删的记录ID之后,再执行删除操作。删除的时候注意,光删dede_archives里的记录不够,因为dede_addonarticle里可能还残留着对应的正文记录,不一起删掉的话,数据库里会留下孤儿数据。两步走,先删除副表再删主表:
DELETE FROM dede_addonarticle WHERE aid IN (SELECT id FROM dede_archives WHERE title='''' AND body='''')
但如果body在另一张表,上面的写法需要调整一下换成JOIN子查询。其实织梦里文章模型的正文确实存在dede_addonarticle,可以直接用这个逻辑。不过更保险的方式是分两步,先查出所有需要删除的ID列表,然后一次性删掉两张表里的数据。例如查询出来的ID是 23, 44, 66,那就执行:
DELETE FROM dede_addonarticle WHERE aid IN (23, 44, 66);
DELETE FROM dede_archives WHERE id IN (23, 44, 66);
顺序很重要,副表里的数据和主表是关联的,先删除副表避免外键报错,然后再抹掉主表记录。有些主机环境的MySQL版本严格,可能不允许子查询和DELETE一起用,这时候就得把ID列表手动粘贴进去执行,麻烦是麻烦了点,但胜在安全。
还有一种情况,如果这些空文档的发布管理里能看到,但编辑页面打不开,可能是文档类型判断出了问题。某些文章模型走了自定义内容字段,正文不在默认的body字段里,这种情况下写SQL就得先弄清楚该类型对应的附加表结构。用后台的“数据库内容替换”功能或许也能处理,但处理不了删除操作。
嫌SQL麻烦的朋友,还可以用织梦自带的批量删除功能,在文档列表页的筛选条件里,标题搜索框输入一个通配符,然后把搜索结果全部勾选,再做删除。不过这个方法用处不大,因为空标题本身就没法用关键字筛出来,所以SQL其实是唯一能根治的办法。
另外建议处理完这波空文档之后,到后台的“系统基本参数”里检查一下发布文章的过滤设置,把那些过于激进的标题过滤规则改掉,不然采集下回还会继续产出这种无头文档。有些站点的采集规则压根就没把标题作为必填项,采集回来的内容标题本来就是空值,这需要在采集器配置里给标题加个“为空时取文件名”的默认值,源头一堵,后面就不用反复清理了。
删除完记录之后,记得去后台“更新缓存”和“生成HTML”,因为列表页可能还引用了旧的数据缓存。跑一次“更新系统缓存”之后再到前台看看,那些空链接应该就没了,文档列表页也清爽多了。整个过程其实没什么高深的技术含量,但只要搞清楚了织梦的数据存储逻辑,花几分钟就能解决,以后再见着这种空记录也不会觉得膈应。