我正在尝试使用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
答案 0 :(得分:2)
通常我们使用传入页面和/或结果计数器参数的存储过程来执行此操作。像这样:
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 Fiddle。
- 编辑
这都是未经测试的,但应该让你朝着正确的方向前进:
首先,在页面中添加隐藏页面以存储当前页码:
<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);
祝你好运。
答案 1 :(得分:1)
您需要排除以前选定的行。 为此,您需要创建一个历史表,您可以在其中插入以前选择的记录。
因此,如果topic
表在列上有主键,则让我们调用列topic_id
,并使用主键调用历史表hist_topic
列topic_id
,您需要查询topic
表中未在hist_topic
表中找到的前10条记录。
阅读数据后,只需在topic_id
中插入所选的hist_topic
值即可。这可以使用批量插入快速完成。
在第一次查询之前,您需要清空以前结果的表格,以免误报。
为了处理多个用户,您需要使用附加字段session
,numeric来扩展历史记录表,该字段将包含为每个页面加载生成的唯一编号。在使用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);
插入历史记录 - 使用批量插入
可以在onunload
的{{1}}事件中清理插入的值。
最重要的优势之一是您不会使用此方法丢失记录。让我们考虑页面保持在客户端级别的方法。想象一下,有以下记录:
body
并且假设你要求前5个记录,并且你在some_number上有一个order by子句,升序。
id | some_number | some_text
------------------------------------
1 | 1 | text1
2 | 4 | text4
3 | 9 | text9
4 | 10 | text10
5 | 19 | text19
select * from topic where RowNum BETWEEN (@recsPerPage+1)*(@page-1) AND @recsPerPage*(@page) order by some_number
然后系统获得新记录
@recsPerPage = 5
在下一个查询中,由于新记录将是新的数字5,查询将再次为您显示您在第一页中看到的记录:
6 11 text11
LE: 我对.NET Web应用程序没有经验,因为我使用Java,因此我只能在我的世界中给你一个例子,也许你可以翻译它。
批量插入
关于批量插入,我找到了bulk insert
的链接在页面加载时生成唯一ID
我不知道如何在.NET Web应用程序中做什么,但我给你一个关于如何使用JSP在Java Web应用程序中执行此操作的提示。在JSP中,首先执行java代码(放在servlet中),然后生成html。因此,如果我在开头添加一个servlet,它将在页面加载时执行。
5 19 text19
<% long uniqueId = UniqueIdGeneration.getUniqueId();%>
是一个uniqueId
变量,只要我在一个scriptlet中,它就会在整个页面中可用。 long
方法将以毫秒为单位返回时间。在返回结果之前,您应该让它休眠一毫秒,以确保只生成唯一的数字。
卸载页面
使用getUniqueId
的{{1}}事件。
onunload