{dede:sql} 标签用于直接执行自定义的 SQL 查询语句,但它本身不自带分页功能,要实现分页,你需要结合 DedeCMS 的分页机制和一些特定的参数。

(图片来源网络,侵删)
下面我将为你介绍两种最常用和最稳定的方法:
使用 GetPagebreaks() 函数(推荐,最常用)
这是 DedeCMS 官方文档中推荐的方法,也是使用最广泛、最稳定的方法,它的核心思想是:
- 执行查询:在
{dede:sql}中执行你的 SQL 语句,获取当前页的数据。 - 获取总数:使用一个独立的
{dede:sql}查询,获取符合条件的总记录数。 - 调用分页函数:使用 DedeCMS 内置的
GetPagebreaks()函数,根据总记录数、每页显示数和当前页码,自动生成分页链接。
操作步骤:
编写 SQL 查询语句
你需要两个 SQL 语句:

(图片来源网络,侵删)
- 一个用于获取当前页的数据(需要用到
limit)。 - 一个用于获取总记录数(
count(*)即可)。
在模板中使用标签
我们将这两个 SQL 语句和分页逻辑组合在一起。
示例模板代码 (sql_page.htm):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">SQL 分页示例</title>
</head>
<body>
<h1>自定义 SQL 查询分页</h1>
<!-- 第一步:显示当前页的数据 -->
{dede:sql sql="SELECT id, title, pubdate FROM dede_archives WHERE typeid = 1 ORDER BY id DESC LIMIT 0,10"}
<div class="item">
<a href="[field:id function='MakeArcUrl(@me)'/]">[field:title/]</a>
<span>发布时间:[field:pubdate function='MyDate("Y-m-d", @me)'/]</span>
</div>
{/dede:sql}
<!-- 第二步:获取总记录数,并赋值给一个变量 -->
{dede:sql sql="SELECT COUNT(*) AS total FROM dede_archives WHERE typeid = 1"}
{dede:getvar name='total' value='@me.total'/}
{/dede:sql}
<!-- 第三步:调用分页函数,生成分页链接 -->
<div class="page">
{dede:pagelist listsize="4" listitem="info,index,end,pre,next,pageno" function="GetPagebreaks(@me, 10, @total, 'aid=[field:aid/]', 'typeid=1')"/}
</div>
</body>
</html>
代码详解:
-
数据查询部分:
(图片来源网络,侵删){dede:sql sql="SELECT id, title, pubdate FROM dede_archives WHERE typeid = 1 ORDER BY id DESC LIMIT 0,10"} ... {/dede:sql}sql="...": 你的 SQL 语句。LIMIT 0,10: 这是分页的关键。LIMIT的格式是LIMIT offset, count。count: 每页显示的记录数(这里是10条)。offset: 偏移量,计算公式为(当前页码 - 1) * 每页显示数,首页是0,第二页是10,以此类推。
-
总记录数查询部分:
{dede:sql sql="SELECT COUNT(*) AS total FROM dede_archives WHERE typeid = 1"} {dede:getvar name='total' value='@me.total'/} {/dede:sql}- 这个查询很简单,只计算总数。
AS total: 给计算结果起一个别名total。{dede:getvar name='total' value='@me.total'/}: 这是 DedeCMS 5.7 版本后引入的标签,用于将内部变量的值(这里是@me.total)保存为一个全局变量(这里是total),以便在后面的分页函数中调用。这一步非常重要。
-
分页链接生成部分:
{dede:pagelist listsize="4" listitem="info,index,end,pre,next,pageno" function="GetPagebreaks(@me, 10, @total, 'aid=[field:aid/]', 'typeid=1')"/}function="GetPagebreaks(...)": 调用核心分页函数。@me:pagelist标签本身的一些默认参数(这里我们基本不用,但需要占位)。10: 每页显示的记录数,必须和LIMIT子句中的count保持一致。@total: 总记录数,就是上一步通过{dede:getvar}创建的变量。'aid=[field:aid/]': 动态链接的附加参数。aid是当前栏目的 ID,你需要根据你的实际情况修改。[field:aid/]会自动获取当前栏目的 ID,如果你的链接不需要带参数,可以写空字符串 。'typeid=1': 静态链接的附加参数,如果你的列表是静态的(如/plus/list-1-1.html),这里可以写上你的栏目 ID 和其他固定参数,如果你的链接是动态的(如/plus/list.php?tid=1),这部分可以省略或与前面合并。
使用 php 和 GetOnePage() 函数(更灵活)
如果你的分页逻辑非常复杂,或者需要 PHP 的强大功能,可以在模板中嵌入 PHP 代码来实现,这种方法更灵活,但需要对 PHP 和 DedeCMS 比较熟悉。
操作步骤:
在模板中启用 PHP 在 DedeCMS 后台,确保你的模板支持 PHP 调用,通常需要开启“使支持PHP”选项(在模板引擎设置里)。
编写 PHP 代码
示例模板代码 (sql_page_php.htm):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">PHP 分页示例</title>
</head>
<body>
<h1>自定义 PHP 查询分页</h1>
<?php
// 1. 获取分页参数
$page = isset($_GET['page']) && is_numeric($_GET['page']) ? intval($_GET['page']) : 1;
$pagesize = 10; // 每页显示10条
$offset = ($page - 1) * $pagesize;
// 2. 获取总记录数
$count_sql = "SELECT COUNT(*) AS total FROM dede_archives WHERE typeid = 1";
$row = $dsql->GetOne($count_sql);
$total_count = $row['total'];
// 3. 获取当前页数据
$data_sql = "SELECT id, title, pubdate FROM dede_archives WHERE typeid = 1 ORDER BY id DESC LIMIT {$offset}, {$pagesize}";
$dlist = new DataListCP();
$dlist->SetTemplate($this->Fields['tempindex']); // 设置当前模板
$dlist->SetSource($data_sql);
$dlist->Display(); // 显示数据列表
// 4. 生成分页条
$dlist->GetPageList($total_count, $page, $pagesize);
?>
</body>
</html>
代码详解:
- 获取分页参数: 从 URL 中获取
page参数,如果没有则默认为第1页。 - 计算偏移量:
offset = (page - 1) * pagesize。 - 获取总记录数: 使用
$dsql->GetOne()执行count查询。 - 获取当前页数据: 使用
$dsql->GetSetRows()或DataListCP类。DataListCP是 DedeCMS 内置的用于处理列表分页的类,能很好地整合到模板引擎中。 - 生成分页条: 调用
DataListCP对象的GetPageList()方法,它会自动处理分页逻辑并输出分页链接。
总结与对比
| 特性 | 方法一 (GetPagebreaks) |
方法二 (php 代码) |
|---|---|---|
| 易用性 | 高,标签化调用,无需 PHP 知识。 | 低,需要编写 PHP 代码,对新手不友好。 |
| 灵活性 | 中等,能满足大部分分页需求。 | 极高,可以编写任何复杂的 PHP 逻辑。 |
| 稳定性 | 高,官方推荐,经过长期验证。 | 较高,但依赖于开发者对 PHP 和 DedeCMS 的理解。 |
| 适用场景 | 绝大多数情况,特别是常规的数据列表分页。 | 需要复杂条件判断、动态生成 SQL 或其他 PHP 特殊功能时。 |
给你的建议:
- 如果你只是想实现一个简单的自定义 SQL 分页,强烈推荐使用方法一,它简单、稳定、官方支持。
- 只有当你发现方法一无法满足你的特殊需求时,再考虑使用方法二。
希望这个详细的教程能帮助你成功实现 DedeCMS 的 {dede:sql} 分页!
