分页 - 如果满足某个条件,如何跳过记录

时间:2014-10-14 15:34:56

标签: mysql coldfusion pagination coldfusion-9

我有各种条目设置为' online'和'离线'在数据库中。 当下一条记录离线时,如何跳过分页设置中的下一条记录。

CF查询效果很好,它的分页不起作用。

我有6行,其中2行在一个字段中设置为离线,所以总共有4行设置为在线。分页效果很好,它输出显示4个中的1个(而不是6个),但查看结果,当我点击下一个时,它会将我带到下一个记录,即使它已关闭或在线。

所以,我正在寻找一种检查字段的方法,并忽略它是否设置为离线。

<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>&nbsp;
[
<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>

非常感谢任何帮助

1 个答案:

答案 0 :(得分:2)

更新了不同的代码

注释

  • 将perpage设置为&gt; 1.这意味着您可以将perpage的实例更改为1(并除去除以1的线)。
  • 它使用列news_id上的数组函数来确定位置和基于该位置的pageinate ..
  • 你好像不再需要url.start了。我注释掉了使用它的代码。
  • 如果您愿意,也可以缓存GetNewsPag查询,并在添加/更新/删除新闻的页面上刷新查询。
  • 以前使用查询getNewsPag&#34;选择*&#34;。我没有看到使用getNewsPag而不是news_id,所以我更改了* the news_id。
  • 使用这种方法,你不应该需要任何&#34; TOP 1 ....其中&gt; =&#34;正如我之前的建议所说的那样,所以我使用<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>&nbsp;
            [
                <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>
            ]

First Effort,保存用于可能从中找到的任何潜在用途

这应该是必要的查询更改,它会搜索大于或等于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>

此时,您的查询(在您的问题中)特别容易被破解。

如果我更改了网址,使其显示为news.cfm?newsid=4; DROP TABLE News,那么您的新闻表就会消失。然后,我可以定位其他常用表名称,如Users或Members。现在,我不会这样做,但它对于恶意用户来说是一个容易攻击的目标。

好消息,这是一个简单的解决方法:<cfqueryparam>我将让您阅读有关该标记的信息,但我会为您解决此问题。 CFQUERYPARAM应该是字面上每个查询都采用任何类型的#variable#input,在它所做的任何地方。

因为您的其他查询不使用#variable变量#input,所以它不会受到任何类型的注入攻击。

从变量输入的字符串值同样容易受到攻击。

如果您使用cfqueryparam,则不应在标记周围放置引号。标签可以识别cfsqltype是否需要引号。

是的,一个人仍然可以像我上面那样更改网址,但他们所做的只是获取页面错误,而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>

编辑:是的,我的s / n是cfqueryparam并非巧合。这是一个非常重要的问题,我倾向于频繁地说明它。 CFqueryparam是一个很棒的工具,应该(必须)充分发挥它的作用。