我有一个要求,我需要提取数据结果集的前100个,以及满足我的过滤条件的总数据记录的数量。
谢谢, 的Manoj。
答案 0 :(得分:3)
您可以使用输出参数返回记录总数以及返回结果集的select
语句。
例如:
create procedure test
@totalCount int output
as begin
select * from something -- your select statement goes here
select @totalCount = 'write your statement that counts the records.'
end
如果您需要通过代码拨打电话,请参阅Java
示例以说明如何拨打电话:
public void test(Connection con) throws SQLException{
CallableStatement cs = con.prepareCall("test");
//you can set more parameters if you need to, i.e.: cs.setInt(0,id);
//you need to register your output parameter. If you are referencing it by name, it should match with the name given in the stored procedure.
cs.registerOutputParameter("totalCount", Types.INTEGER);
ResultSet rs = cs.executeQuery();
while(rs.next()){
//you can save the data into a data structure; a list for example.
//Or just print the records.
}
//here's how you can get the total count
int total = cs.getInt("totalCount");
}
此方法只是向您展示如何进行通话的示例。不要写这样的生产代码!!!
答案 1 :(得分:1)
我的一个答案类似于A2H, ,但如果 您的"计数"与您的选择查询直接相关,您可以避免"双击",但将结果放在#temp表中。
但是,您也可以使用@@ ROWCOUNT技巧。这是一个新答案,恕我直言。
CREATE PROCEDURE dbo.SelectAndCountExample
@TotalCount int output
as
BEGIN
IF OBJECT_ID('tempdb..#Holder') IS NOT NULL
begin
drop table #Holder
end
CREATE TABLE #Holder
(SurrogateKey INT, SomeValue VARCHAR(64) )
/* simulate your insert */
INSERT INTO #HOLDER (SurrogateKey , SomeValue)
select 101 , 'A' union all select 102, 'B' union all select 103, 'C' union all select 104, 'D'
/* optional stuff */
/* CREATE CLUSTERED INDEX IDX_TempHolder_ID ON #Holder (ID) */
/* CREATE INDEX IDX_TempHolder_ID ON #Holder (ID) */
Select @TotalCount = count(*) From #Holder
Select SurrogateKey , SomeValue from #HOLDER
IF OBJECT_ID('tempdb..#Holder') IS NOT NULL
begin
drop table #Holder
end
END
GO
declare @MyVariable int
EXEC dbo.SelectAndCountExample @MyVariable output
Select @MyVariable as '@MyVariable Value'
GO
和
CREATE PROCEDURE dbo.SelectAndCountExampleUsingRowCount
@TotalCount int output
as
BEGIN
select 101 , 'A' union all select 102, 'B' union all select 103, 'C' union all select 104, 'D'
Select @TotalCount = @@ROWCOUNT
IF OBJECT_ID('tempdb..#Holder') IS NOT NULL
begin
drop table #Holder
end
END
GO
declare @MyVariable int
EXEC dbo.SelectAndCountExampleUsingRowCount @MyVariable output
Select @MyVariable as '@MyVariable Value'
答案 2 :(得分:1)
在显示结果的可能页面总数的同时,需要翻阅结果并不常见,这里可能存在很多问题。不幸的是,没有内置的机制来处理这个问题。这让你只有几个选择:
运行查询两次:一次获取总行数,然后再次获取所需结果的子集/页面。这里的缺点是你运行了两次。 (这是@ A2H'答案的基础)
运行一次查询,将结果转储到本地临时表中,并使用@@ROWCOUNT
捕获进入临时表的行数。然后,从临时表中选择所需结果的子集/页面。这里的缺点是你正在点击IO(tempdb数据文件和事务日志),尽管可以通过使用内存中OLTP来改进。 (类似于@ granadaCoder的答案,但该答案并未跟进行子集的要求)
将其构建到应用代码中:
SqlDataReader.Read()
(假设您正在使用.NET) - 没有实际检索任何数据 - 要跳过的行数,然后读取所需结果的子集/页面的行,最后再次调用SqlDataReader.Read()
- 而不实际检索任何数据 - 直到没有什么可读的。增加3个部分中每个部分的行计数器。 请参阅我的以下答案,也在StackOverflow上,它提供了有关此方法的更多详细信息(和变体):