Sql server SQL Server过程设计,用于在单个调用中获取结果和结果计数

Sql server SQL Server过程设计,用于在单个调用中获取结果和结果计数,sql-server,count,multiple-results,Sql Server,Count,Multiple Results,我有一个要求,我需要提取数据结果集的前100名,以及满足过滤条件的总数据记录的计数 谢谢, Manoj.您可以使用输出参数返回记录总数,也可以使用select语句返回结果集 例如: create procedure test @totalCount int output as begin select * from something -- your select statement goes here select @totalCount = 'write your

我有一个要求,我需要提取数据结果集的前100名,以及满足过滤条件的总数据记录的计数

谢谢,
Manoj.

您可以使用输出参数返回记录总数,也可以使用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");
}

此方法只是一个示例,演示如何进行调用。不要这样写生产代码

我的一个答案类似于A2H,但如果您的计数与select的查询直接相关,则可以避免双击,但将结果放在临时表中

但是,您也可以使用@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


在显示可能的结果页面总数的同时,需要翻阅结果的情况并不少见,这里可能已经有很多关于这方面的问题。不幸的是,没有内置的机制来处理这个问题。这让您只有几个选择:

运行查询两次:一次获取总行数,然后再次获取所需结果的子集/页面。这里的缺点是您要运行它两次。这是@A2H答案的基础

运行一次查询,将结果转储到本地临时表中,并使用@ROWCOUNT捕获进入临时表的行数。然后,从临时表中选择所需的结果子集/页面。这里的缺点是您在IO tempdb数据文件和事务日志上遇到了麻烦,尽管使用内存中的OLTP可能会改进这一点。与@granadaCoder的答案类似,但该答案并不符合行的子集要求

将其构建到应用程序代码中:

声明一个计数器以跟踪总行数 运行完整查询 调用SqlDataReader.Read,假设您正在使用.NET(不实际检索任何数据)获取要跳过的行数,然后读取所需结果子集/页面的行,最后调用SqlDataReader.Read(再次调用),不实际检索任何数据,直到没有任何内容可读取为止。增加3个部分中每个部分的行计数器。 请参阅我关于StackOverflow的以下回答,其中提供了该方法的更多细节和变化:


Manoj,如果这个答案解决了你的问题,请考虑。在您的解决方案中,@TotalCount和返回的记录数总是相同的。我不认为这是@Manoj想要的。他想要前100行和所有符合标准的行数。我给海报和未来的读者不同的选择。显然,如果结果行与计数不匹配,将有两个不同的查询…这就是为什么我对您的回答进行了投票。是的,这是有意义的。我的回答更多的是一个关键点的布局,没有包括任何实施——这取决于实施者,他/她希望如何去做,并且您提供了有效实施的示例。
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'