我在数据库中将各种条目设置为“在线”和“离线”。
当下一个记录离线时,如何跳过分页设置中的下一个记录。
CF查询效果很好,它的分页不起作用。
我有6行,其中有2行在一个字段中设置为脱机,因此总共有4行设置为在线。分页效果很好,它输出“显示4个中的1个(而不是6个)”,但是查看结果,当我单击“ next”时,即使关闭或在线,它也带我到下一个记录。
因此,我正在寻找一种方法来检查文件并忽略它是否设置为脱机。
<cfquery name="getNews" datasource="#session.odbcname#">
SELECT *
FROM news
WHERE news_id = #url.newsid#
AND news_status = 'online'
</cfquery>
<cfif not getNews.recordcount>
<cflocation url="#defurl#" addtoken="No">
</cfif>
<cfquery name="getNewsPag" datasource="#session.odbcname#">
SELECT *
FROM news
WHERE news_status = 'online'
ORDER by news_id asc
</cfquery>
<cfset perpage = 1>
<cfparam name="url.start" default="#url.newsid#">
<cfif not isNumeric(url.start) or url.start lt 1 or url.start gt getNewsPag.recordCount or round(url.start) neq url.start>
<cfset url.start = #url.newsid#>
</cfif>
<cfset totalPages = ceiling(getNewsPag.recordCount / perpage)>
<cfset thisPage = ceiling(url.start / perpage)>
<div>
<cfif getNewsPag.recordcount>
<cfoutput>#getNewsPag.recordcount#</cfoutput><br>
<div>
<p>
<cfoutput>#lang_pagination_info# #thisPage# #lang_pagination_of# #totalPages#.</cfoutput>
[
<cfif url.start gt 1>
<cfset link = cgi.script_name & "?newsid=" & (url.start - perpage)>
<cfoutput><a href="#link#">Previous</a></cfoutput>
<cfelse>
Previous
</cfif>
/
<cfif (url.start + perpage - 1) lt getNewsPag.recordCount>
<cfset link = cgi.script_name & "?newsid=" & (url.start + perpage)>
<cfoutput><a href="#link#">Next</a></cfoutput>
<cfelse>
Next
</cfif>
非常感激任何的帮助
最佳答案
用不同的代码更新
笔记
当将perpage设置为> 1时,它将不起作用。这意味着您可以将perpage的实例更改为1(并摆脱以1除的行)。
它在news_id列上使用数组函数来确定位置并基于此进行分页。
您似乎实际上不再需要url.start了。我注释掉了使用它的代码。
如果您愿意,也可以缓存GetNewsPag查询,并在添加/更新/删除新闻的页面上刷新查询。
以前,查询getNewsPag使用“选择*”。我没有看到除news_id之外的getNewsPag用法,因此我更改了* news_id。
使用此方法,您不需要任何“ TOP 1 ....其中> =“,如我先前的建议所述,因此我使用<cfqueryparam>
将getNews还原为其原始形式。
希望这可以帮助
<!--- <cfparam name="url.start" default="#url.newsid#"> --->
<cfquery name="getNews" datasource="#session.odbcname#">
SELECT *
FROM news
WHERE news_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#url.newsid#">
AND news_status = 'online'
ORDER BY news_id
</cfquery>
<cfif not getNews.recordcount>
<cflocation url="#defurl#" addtoken="No">
</cfif>
<cfquery name="getNewsPag" datasource="#session.odbcname#">
SELECT news_id
FROM news
WHERE news_status = 'online'
ORDER by news_id asc
</cfquery>
<cfset perpage = 1>
<!--- <cfset url.start="#max(val(url.newsid),val(getNews.news_id))#">
<cfif not isNumeric(url.start) or url.start lt 1 or url.start gt getNewsPag.recordCount or int(url.start) neq url.start>
<cfset url.start = #url.newsid#>
</cfif> --->
<cfset totalPages = getNewsPag.recordCount>
<cfset thisPage = ArrayFind(getNewsPag["news_id"],url.news_id)>
<div>
<cfif getNewsPag.recordcount>
<cfoutput>#getNewsPag.recordcount#</cfoutput><br>
<div>
<p>
<cfoutput>#lang_pagination_info# #thisPage# #lang_pagination_of# #totalPages#.</cfoutput>
[
<cfif ArrayMin(GetNewsPag["news_id"]) lt getNews.news_id>
<cfset link = cgi.script_name & "?newsid=" & (GetNewsPag.news_id[ArrayFind(GetNewsPag["news_id"],getNews.news_id)+perpage])>
<cfoutput><a href="#link#">Previous</a></cfoutput>
<cfelse>
Previous
</cfif>
/
<cfif ArrayMax(GetNewsPag["news_id"]) gt getNews.news_id>
<cfset link = cgi.script_name & "?newsid=" & (GetNewsPag.news_id[ArrayFind(GetNewsPag["news_id"],getNews.news_id)-perpage])>
<cfoutput><a href="#link#">Next</a></cfoutput>
<cfelse>
Next
</cfif>
]
尽力而为,将其保存下来,以备他人使用
这应该是必要的查询更改,它搜索大于或等于url.newsID的第一行。
(我实际上不使用mysql,但这是一个非常基本的查询。语法应该正确,但是如果需要调整,请告诉我。)
<cfquery name="getNews" datasource="#session.odbcname#">
SELECT TOP 1 *
FROM news
WHERE news_id >= #url.newsid#
AND news_status = 'online'
ORDER BY news_id
</cfquery>
您需要更改一些分页以使用getNews.news_id而不是url.newsid。
<cfparam name="url.start" default="#max(val(url.newsid),val(getNews.news_id))#">
这条线可以帮助您到达那里。如果未设置url.start,它将在url.newsID和getNews.news_ID之间找到更大(整数)的参数。 val()函数只需确保传递的参数都是数字,否则就将其转换为零。方便,例如,getnews.news_id返回0个结果。
关于
<cfqueryparam>
目前,您的查询(在您的问题中)特别容易被入侵。
如果我更改URL,使其显示为
news.cfm?newsid=4; DROP TABLE News
,则您的新闻表不见了。然后,我可以定位其他常见的表名,例如“用户”或“成员”。现在,我不会这样做,但是对于恶意用户而言,这是一个简单的目标。好消息,有一个简单的解决方法:
<cfqueryparam>
我将让您阅读有关该标签的信息,但我将为您解决此查询。CFQUERYPARAM实际上应在接受任何类型的#variable#输入的每个查询中,它所做的任何地方。因为您的其他查询不使用任何#variable#输入,所以它不受任何类型的注入攻击的影响。
从变量输入的字符串值同样容易受到攻击。
在任何情况下,使用cfqueryparam时,都不应在标记周围引起引号。标记识别cfsqltype是否需要引号。
是的,一个人仍然可以像我上面那样更改url,但是他们要做的只是页面错误,而sql脚本将无效。如果是字符串,则不会出现错误,但是会得到错误的结果。
<cfquery name="getNews" datasource="#session.odbcname#">
SELECT *
FROM news
WHERE news_id >= <cfqueryparam cfsqltype="cf_sql_integer" value="#url.newsid#">
AND news_status = 'online'
ORDER BY news_id
</cfquery>
编辑:是的,我的序列号是cfqueryparam并非偶然。这个问题很重要,我倾向于经常说明。 CFqueryparam是一个很棒的工具,应该(必须)充分发挥作用。