Dede SQL 标签 ({dede:sql})
{dede:sql} 标签允许你在模板文件(如 .htm)中直接编写 SQL 语句,并执行它,然后将查询结果输出到页面上。

(图片来源网络,侵删)
基本语法
{dede:sql sql="你的SQL语句"}
// 循环输出查询结果
[field:字段名/]
{/dede:sql}
{dede:sql}: 标签开始。sql="...": 必需属性,里面是你想要执行的 SQL 语句。[field:字段名/]: 在标签内部,用于循环输出查询结果的每一行数据。字段名就是你的 SQL 查询语句中SELECT后面的字段名。{/dede:sql}: 标签结束。
简单示例
假设你想从 dede_archives (文章表) 中随机获取 5 篇文章的标题和链接。
<h3>随机推荐文章</h3>
<ul>
{dede:sql sql="SELECT title, id FROM dede_archives ORDER BY RAND() LIMIT 5"}
<li>
<a href="[field:id runphp='yes'] $id = @me; @me = GetOneArchive($id); @me = $arc['arcurl']; [/field:id]" title="[field:title/]">
[field:title/]
</a>
</li>
{/dede:sql}
</ul>
代码解释:
sql="SELECT title, id FROM dede_archives ORDER BY RAND() LIMIT 5": 这句 SQL 从文章表中随机选取 5 条记录,只查询title和id字段。[field:title/]: 输出文章标题。[field:id ...]: 这是一个更复杂的用法,我们会在下面的“变量”部分详细解释,它的作用是通过文章 ID 获取到文章的最终 URL。
变量在 Dede SQL 标签中的使用
在 SQL 标签中使用变量,是实现动态查询的关键,DedeCMS 提供了多种方式来传递变量到 SQL 语句中。
使用 global 全局变量
这是最常用、最安全的方式,用于获取 DedeCMS 系统的预定义变量,如当前栏目 ID、会员 ID 等。

(图片来源网络,侵删)
语法: {$变量名}
常用全局变量:
{$typeid}: 当前栏目 ID。{$typeid2}: 当前父栏目 ID。{$aid}: 当前文章 ID。{$memberid}: 当前登录会员的 ID。{$cfg_phpurl}: 网站程序路径。
示例:获取当前栏目下的所有文章
{dede:sql sql="SELECT title, id FROM dede_archives WHERE typeid={$typeid}"}
<a href="[field:id runphp='yes'] $id = @me; @me = GetOneArchive($id); @me = $arc['arcurl']; [/field:id]">[field:title/]</a>
<br>
{/dede:sql}
这段代码会查询并输出当前栏目 ({$typeid}) 下的所有文章标题和链接。

(图片来源网络,侵删)
使用 php 标签定义变量
如果你需要一个变量,但它不是 DedeCMS 的全局变量,你可以使用 {dede:php} 标签在 SQL 标签外部定义它,然后在内部使用。
语法:
{dede:php}
$myVariable = '自定义的值';
{/dede:php}
{dede:sql sql="SELECT * FROM dede_table WHERE field='{$myVariable}'"}
// ...
{/dede:sql}
示例:根据 URL 参数查询
假设你的网址是 http://your.com/list.php?keyword=织梦,你想查询标题包含“织梦”的文章。
{dede:php}
// 获取 URL 中的 keyword 参数值
$keyword = isset($_GET['keyword']) ? addslashes($_GET['keyword']) : '';
{/dede:php}
{dede:sql sql="SELECT title, id FROM dede_archives WHERE title LIKE '%{$keyword}%'"}
{if $keyword != ''}
<a href="[field:id runphp='yes'] $id = @me; @me = GetOneArchive($id); @me = $arc['arcurl']; [/field:id]">[field:title/]</a>
<br>
{/if}
{/dede:sql}
注意: 使用 addslashes() 对用户输入进行转义,可以有效防止 SQL 注入攻击,这是一个非常重要的安全习惯。
使用 field 标签的值作为变量
你可以获取当前文档(如文章、栏目页)的字段值,并将其用作 SQL 查询的条件。
示例:获取当前文章的标签,并查找带有相同标签的其他文章
这比较复杂,需要结合 DedeCMS 的标签和函数,但原理就是将一个字段的值作为变量传递给另一个 SQL 查询。
{dede:field.tags runphp='yes'}
$tags = @me;
// 将标签字符串(如"标签1,标签2")转换成数组
$tagArray = explode(',', $tags);
// 清理标签,去掉多余空格
$tagArray = array_map('trim', $tagArray);
// 将数组用引号包裹,用于 IN 查询
$tagString = "('" . implode("','", $tagArray) . "')";
@me = $tagString;
{/dede:field.tags}
{dede:sql sql="SELECT title, id FROM dede_archives WHERE id NOT IN {dede:field.id/} AND CONCAT(',',keywords,',') LIKE '%,{$tagString},%' LIMIT 10"}
<li>
<a href="[field:id runphp='yes'] $id = @me; @me = GetOneArchive($id); @me = $arc['arcurl']; [/field:id]" title="[field:title/]">
[field:title/]
</a>
</li>
{/dede:sql}
这段代码解释:
{dede:field.tags runphp='yes'}: 获取当前文章的tags字段。- 在 PHP 代码中,我们将标签字符串(如"织梦,CMS")处理成
('织梦','CMS')这样的格式,并最终将这个结果赋值给@me变量。 {dede:field.id/}: 获取当前文章的 ID,用于排除当前文章。- SQL 语句中的
{$tagString}就使用了上一步处理好的变量值,从而实现了查找包含相同标签的其他文章。
重要注意事项与最佳实践
-
安全性 (SQL注入)
- 永远不要直接信任用户输入,如果你使用了 URL 参数、表单提交的值作为变量,必须使用
addslashes()或mysql_real_escape_string()(在较新版本中建议使用 PDO 或 MySQLi) 进行过滤。 - 推荐使用
global变量,因为它们是 DedeCMS 内部处理的,相对安全。
- 永远不要直接信任用户输入,如果你使用了 URL 参数、表单提交的值作为变量,必须使用
-
性能影响
- SQL 查询是直接操作数据库,如果使用不当(如复杂的 JOIN、不合理的
WHERE条件、缺少索引),会严重影响网站性能。 - 避免在首页或高并发页面上使用复杂的 SQL 查询。
- 尽量使用 DedeCMS 自带的标签,因为它们通常有缓存机制,而
{dede:sql}默认没有缓存,如果数据不常变化,可以考虑结合缓存技术。
- SQL 查询是直接操作数据库,如果使用不当(如复杂的 JOIN、不合理的
-
可读性与维护性
- 在模板中写复杂的 SQL 语句会使代码难以阅读和维护。
- 对于非常复杂的查询,建议通过修改 DedeCMS 的核心文件(如
include/extend.func.php)来创建自定义函数,然后在模板中调用这个函数,这样逻辑和视图分离,更清晰。
-
标签嵌套
- 可以在
{dede:sql}标签内部使用其他 DedeCMS 标签,如{dede:php}、{dede:field}等,以实现更复杂的功能,如上面示例中的runphp。
- 可以在
| 变量类型 | 语法 | 说明 | 示例 |
|---|---|---|---|
| 全局变量 | {$变量名} |
获取 DedeCMS 系统预定义的变量,最常用也最安全。 | {$typeid}, {$aid} |
| PHP定义变量 | {dede:php} $var = 'value'; {/dede:php} |
在模板中自定义变量,常用于处理 URL 参数等。 | {$keyword} |
| 字段值变量 | {dede:field.字段名/} |
获取当前文档的字段值作为变量。 | {dede:field.id/} |
掌握 {dede:sql} 和变量使用,能让你在 DedeCMS 开发中游刃有余,实现许多标准标签无法完成的功能,但请务必时刻牢记安全和性能这两条红线。
