4

我正在尝试使用 javascript 和以下 sql 语句(sql server 2008)在我的 .NET 网站中进行无限滚动。此 sql 获取前 10 行,但我的 javascript 导致每次用户滚动到页面底部时执行 sql,并且每次它都会拉取相同的(前 10 条)记录,但我希望它拉下 NEXT 10 条记录,每次用户滚动到底部。每次用户滚动到页面底部时,如何使用此 sql 和 row_number 来获取 NEXT 10 行?

SELECT * FROM 
  (SELECT ROW_NUMBER() OVER (ORDER BY DateTime) As RowNum, 
  * From Topic) As a 
WHERE RowNum 
BETWEEN 1 AND 10

这是javascript:

<script type="text/javascript">
        $(document).ready(function () {

       function lastPostFunc() {
           $('#divPostsLoader').html('<img src="images/bigLoader.gif">');

           //send a query to server side to present new content
           $.ajax({
               type: "POST",
               url: "Default.aspx/Foo",
               data: "{}",
               contentType: "application/json; charset=utf-8",
               dataType: "json",
               success: function (data) {

                   if (data != "") {
                       $('.divLoadData:last').after(data.d);
                   }
                   $('#divPostsLoader').empty();
               }

           })
       };

       //When scroll down, the scroller is at the bottom with the function below and fire the lastPostFunc function
       $(window).scroll(function () {
           if ($(window).scrollTop() == $(document).height() - $(window).height()) {
               lastPostFunc();
           }
       });

    });
</script>

我现在在存储过程中有上面的 sql:

<System.Web.Services.WebMethod()>
Public Shared Function Foo() As String
    Dim strConn As String = "Data Source="
    Dim conn As New SqlConnection(strConn)
    Dim Cmd As New SqlCommand("InfiniteScroll", conn)
    Cmd.CommandType = CommandType.StoredProcedure
    Dim DA As New SqlDataAdapter(Cmd)
    Dim DS As New DataSet()
    DA.Fill(DS, "RefologyForumTopic")
    Dim getPostsText As New StringBuilder()
    Dim dv As DataView = DS.Tables(0).DefaultView

    For Each myDataRow As DataRowView In dv
        getPostsText.AppendFormat("price: {0}</br>", myDataRow("Topic"))
        getPostsText.AppendFormat("description: {0}</br></p>", myDataRow("UserID"))
    Next

    getPostsText.AppendFormat("<div style='height:15px;'></div>")
    Return getPostsText.ToString()
End Function
4

2 回答 2

3

通常,我们使用传递页面和/或结果计数器参数的存储过程来执行此操作。像这样的东西:

SELECT * 
FROM (
   SELECT ROW_NUMBER() OVER (ORDER BY DateTime) As RowNum, * 
   FROM Topic) As a 
WHERE RowNum BETWEEN 1+(@recsPerPage)*(@page-1) AND @recsPerPage*(@page)

这是SQL 小提琴

- 编辑

这一切都未经测试,但应该让你朝着正确的方向前进:

首先,在页面中添加一个隐藏页面来存储你当前的页码:

<input type=hidden id=hidPage name=hidPage value="1">

其次,在 ajax 调用中更新数据参数:

data: { Page: $("#hidPage").value() },

第三,更新您的网络方法以接受参数:

Public Shared Function Foo(page as string (or int -- would need to test for sure)) As String

然后更新您的 SQL 以传递参数。我不打算重写,但使用此链接寻求帮助:http: //msdn.microsoft.com/en-us/library/bbw6zyha (v=vs.71).aspx

最后,在 ajax 成功处理程序上重置 hidPage 变量。

var newPage = parseInt($("#hidPage").val());
$("#hidPage").val(newPage+1);

祝你好运。

于 2013-01-24T18:12:30.003 回答
1

您需要排除先前选择的行。为此,您需要创建一个历史表,您可以在其中插入先前选择的记录。

所以,如果topic表的某列有主键,我们就叫该列topic_id,而历史表是hist_topic用列上的主键调用的topic_id,你需要从表中查询出topic表中没有的前10条记录hist_topic

读取数据后,只需topic_idhist_topic. 这可以使用批量插入快速完成。

在第一次查询之前,您需要清空先前结果的表,这样您就不会得到误报。

为了处理多个用户,您需要使用附加字段session数字扩展历史表,该字段将包含为每个页面加载生成的唯一编号。当您使用 AJAX 时,您不必担心将这个唯一 id 从一个页面传递到另一个页面。可以通过在页面加载时调用附加脚本来生成唯一 ID。

如果您在查询时添加了新记录,这也会对您有所帮助。

步骤应该是这样的:页面加载-生成唯一ID查询

SELECT * FROM 
  (SELECT ROW_NUMBER() OVER (ORDER BY DateTime) As RowNum, 
  * From Topic) As a 
WHERE RowNum BETWEEN 1 AND 10
AND NOT EXISTS (SELECT 1 FROM HIST_TOPIC B WHERE A.TOPIC_ID = B.TOPIC_ID AND B.SESSION = @SESSION);

插入历史记录 - 使用批量插入

清理插入的值可以onunloadbody.

最重要的优点之一是使用这种方法不会丢失记录。让我们考虑将页面保留在客户端级别的方法。想象一下有以下记录:

id   |   some_number   |  some_text
------------------------------------
1    |   1             |    text1
2    |   4             |    text4
3    |   9             |    text9
4    |   10            |    text10
5    |   19            |    text19

假设您要求前 5 条记录,并且您在 some_number 上有一个 order by 子句,升序。

select * from topic where RowNum BETWEEN (@recsPerPage+1)*(@page-1) AND @recsPerPage*(@page) order by some_number

@recsPerPage = 5

然后系统得到一条新记录

6 11 text11

在下一个查询中,因为新记录将是新的数字 5,所以查询将再次为您带来您在第一页中看到的记录:

5 19 text19

LE:我对 .NET Web 应用程序没有经验,因为我在 Java 中工作,因此我只能在我的世界里给你一个例子,也许你可以翻译一下。

批量插入

至于批量插入,我找到了批量插入的链接

在页面加载时生成唯一 ID

我不知道如何在 .NET Web 应用程序中进行操作,但我会提示您如何使用 JSP 在 Java Web 应用程序中进行操作。在 JSP 中,首先执行 java 代码(放置在 servlet 中),然后生成 html。因此,如果我在开头添加一个 servlet,它将在页面加载时执行。

<% long uniqueId = UniqueIdGeneration.getUniqueId();%>

每当我在 scriptlet 中时,uniqueId该变量将在整个页面中可用。longgetUniqueId方法将以毫秒为单位返回时间。您应该在返回结果之前让它休眠一毫秒,以确保只生成唯一的数字。

卸载页面

使用. onunload_body

<javascript>
function doUnload() {
  var session=<%=uniqueId%>;
  //use the new session variable to pass it to the server using AJAX. The server will respond by deleting the records corresponding to it.
}
</javascript>
于 2013-01-24T18:14:15.757 回答