- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在更新一个存储过程,该存储过程当前最多选择n行,如果返回的行= n,则执行无限制的选择计数,然后返回原始的select和受影响的行总数。
有点像:
SELECT TOP (@rowsToReturn)
A.data1,
A.data2
FROM
mytable A
SET @maxRows = @@ROWCOUNT
IF @rowsToReturn = @@ROWCOUNT
BEGIN
SET @maxRows = (SELECT COUNT(1) FROM mytableA)
END
COUNT(*) OVER()
允许这样做,但是它放在每一行中,而不是放在输出参数中。也许像MYSQL中的
FOUND_ROWS()
之类的东西,例如@@ TOTALROWCOUNT之类。
最佳答案
正如@MartinSmith在对此问题的评论中提到的那样,没有直接(即纯T-SQL)方法来获取将要返回的行总数,同时限制了它。过去,我已完成以下方法:
将查询转储到临时表中以获取@@ROWCOUNT
(总集)
在主查询的排序结果上使用ROW_NUBMER() AS [ResultID]
SELECT TOP (n) FROM #Temp ORDER BY [ResultID]
或类似的内容
当然,这里的缺点是您需要将这些记录放入temp表中的磁盘I / O成本。将[tempdb]
放在SSD上? :)
我还经历了“先用其余的查询运行COUNT(*),然后再运行常规的SELECT”方法(如@Blam所倡导的那样),这不是对查询的“免费”重新运行:
在许多情况下,它是完全重新运行。问题是,在执行COUNT(*)
时(因此不返回任何字段),优化器仅需要担心JOIN,WHERE,GROUP BY,ORDER BY子句中的索引。但是,当您需要返回一些实际数据时,这可能会相当大地改变执行计划,尤其是如果用于获取COUNT(*)的索引没有“覆盖” SELECT列表中的字段时。
另一个问题是,即使索引全部相同,因此所有数据页仍在高速缓存中,这只会使您免于物理读取。但是您仍然具有逻辑读物。
我并不是说这种方法行不通,但我认为Question中仅在条件上仅COUNT(*)
起作用的方法对系统的压力要小得多。
@Gordon提倡的方法实际上在功能上与我上面描述的临时表方法非常相似:它将全部结果集转储到[tempdb](INSERTED
表在[tempdb]中)以获得完整的@@ROWCOUNT
和然后得到一个子集。不利的一面是,INSTEAD OF TRIGGER方法是:
需要做更多的工作(例如,增加10倍至20倍):您需要一个真实的表来表示每个不同的结果集,需要一个触发器,该触发器需要动态构建,或者获取要返回的行数从某些配置表,或者我想它可以从CONTEXT_INFO()
或临时表中获取它。尽管如此,整个过程还是很多步骤,而且很复杂。
非常低效:首先,它执行相同的工作量,将全部结果集转储到表中(即,放入INSERTED
表中,该表位于[tempdb]
中),然后又执行了另外一个选择所需记录子集的步骤(这不是真正的问题,因为它仍应位于缓冲池中)以返回到实际表中。更糟糕的是,第二步实际上是双重I / O,因为该操作还在实际表所在的数据库的事务日志中表示。但是,等等,还有更多:下一次查询运行如何?您需要清除此真实表。不管是通过DELETE
还是TRUNCATE TABLE
,它都是在事务日志中显示的另一项操作(基于使用这两个操作中的哪一个来表示的数量),加上在该附加操作上花费的额外时间。 AND,别忘了从INSERTED
中选择子集进入真实表的步骤:由于您无法为INSERTED
和DELETED
表建立索引,因此它没有机会使用索引。并不是说您总是想向临时表添加索引,但是有时它会有所帮助(取决于情况),并且您至少可以选择。
过于复杂:当两个进程需要同时运行查询时会发生什么?如果它们共享同一真实表以转储到然后选择out作为最终输出,则需要添加另一列以区分SPID。可能是@@SPID
。也可以是在调用初始INSERT
到真实表之前创建的GUID(以便可以通过INSTEAD OF
或临时表将其传递给CONTEXT_INFO()
触发器)。无论值是多少,一旦选择了最终输出,它将用于执行DELETE
操作。而且,即使不是很明显,这部分也会影响前面的项目符号中提到的性能问题:TRUNCATE TABLE
不能使用,因为它会清除整个表,而DELETE FROM dbo.RealTable WHERE ProcessID = @WhateverID;
则是唯一的选择。
现在,公平地说,可以从触发器本身内部进行最终的SELECT。这将减少一些效率低下的情况,因为数据永远不会进入真实表,然后再也不需要删除。由于也无需通过SPID分离数据,因此也减少了过度复杂的情况。但是,这是一个非常有限的解决方案,因为在SQL Server的下一发行版中,从触发器内返回结果的能力正在逐渐消失,因此请说一下disallow results from triggers Server Configuration Option的MSDN页面:
在下一版本的Microsoft SQL Server中将删除此功能。不要在新的开发工作中使用此功能,请尽快修改当前使用此功能的应用程序。我们建议您将此值设置为1。
唯一的实际方法是:
查询一次
获取行的子集
仍然获得完整结果集的总行数
是使用.Net。如果从应用代码中调用了proc,请参阅底部的“ EDIT 2”。如果您希望能够通过即席查询随机运行各种存储过程,则它必须是SQLCLR存储过程,以便它可以是通用的并且适用于任何查询,因为存储过程可以返回动态结果集而函数不能。该过程至少需要3个参数:
@QueryToExec NVARCHAR(最大)
@RowsToReturn INT
@TotalRows INT输出
这个想法是使用“ Context Connection = true;”。利用内部/进程内连接。然后,您执行以下基本步骤:
致电ExecuteDataReader()
在读取任何行之前,请先执行GetSchemaTable()
从SchemaTable中,您可以获得结果集字段名称和数据类型
从结果集结构中构造一个SqlDataRecord
用那个SqlDataRecord
您呼叫SqlContext.Pipe.SendResultsStart(_DataRecord)
现在您开始呼叫Reader.Read()
对于您调用的每一行:Reader.GetValues()
DataRecord.SetValues()
SqlContext.Pipe.SendResultRow(_DataRecord)
RowCounter++
而不是执行典型的“ while (Reader.Read())
”,而是包括@RowsToReturn参数:while(Reader.Read() && RowCounter < RowsToReturn.Value)
在while循环之后,调用SqlContext.Pipe.SendResultsEnd()
关闭结果集(正在发送的结果集,而不是正在读取的结果集)
然后执行第二次while循环,循环遍历其余结果,但从不获取任何字段:
而(Reader.Read())
{
RowCounter ++;
}
然后只需设置TotalRows = RowCounter;
即可返回完整结果集的行数,即使您只返回了它的前n行:)
不知道它是如何针对临时表方法,双重调用方法甚至@ M.Ali的方法(我也曾尝试过,有点类似,但是问题是不将值作为列发送),但是它应该很好,并且可以按要求完成任务。
编辑:
更好!另一个选择(上述C#建议的一种变化)是使用T-SQL存储过程中的@@ROWCOUNT
作为OUTPUT
参数发送,而不是循环遍历SqlDataReader
中的其余行。因此,存储过程将类似于:
CREATE PROCEDURE SchemaName.ProcName
(
@Param1 INT,
@Param2 VARCHAR(05),
@RowCount INT OUTPUT = -1 -- default so it doesn't have to be passed in
)
AS
SET NOCOUNT ON;
{any ol' query}
SET @RowCount = @@ROWCOUNT;
Reader.Close()
TotalRows = (int)RowCountOutputParam.Value;
SqlDataRecord
或
SqlContext.Pipe
方法。假设您已经设置了
SqlDataReader
来拉回结果,则只需要:
SET @RowCount = @@ROWCOUNT;
SqlParameter
while(Reader.Read() && RowCounter < RowsToReturn)
,以便在您拉回所需的数量后就可以停止检索结果。
TOP (n)
)
SqlDataReader
并获取OUTPUT参数的
.Value
即可:)。
关于sql - TSQL:是否有办法限制返回的行并计算没有限制的返回总数(不将其添加到每一行)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27070104/
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
在编码时,我问了自己这个问题: 这样更快吗: if(false) return true; else return false; 比这个? if(false) return true; return
如何在逻辑条件下进行“返回”? 在这样的情况下这会很有用 checkConfig() || return false; var iNeedThis=doSomething() || return fa
这是我的正则表达式 demo 如问题所述: 如果第一个数字是 1 则返回 1 但如果是 145 则返回 145 但如果是 133 则返回 133 样本数据a: K'8134567 K'81345678
在代码高尔夫问答部分查看谜题和答案时,我遇到了 this solution返回 1 的最长和最晦涩的方法 引用答案, int foo(void) { return! 0; } int bar(
我想在下面返回 JSON。 { "name": "jackie" } postman 给我错误。说明 Unexpected 'n' 这里是 Spring Boot 的新手。 1日龄。有没有正确的方法来
只要“is”返回 True,“==”不应该返回 True 吗? In [101]: np.NAN is np.nan is np.NaN Out[101]: True In [102]: np.NAN
我需要获取所有在 6 号或 7 号房间或根本不在任何房间的学生的详细信息。如果他们在其他房间,简单地说,我不希望有那个记录。 我的架构是: students(roll_no, name,class,.
我有一个表单,我将它发送到 php 以通过 ajax 插入到 mysql 数据库中。一切顺利,php 返回 "true" 值,但在 ajax 中它显示 false 消息。 在这里你可以查看php代码:
我在 Kotlin 中遇到了一个非常奇怪的无法解释的值比较问题,以下代码打印 假 data class Foo ( val a: Byte ) fun main() { val NUM
请注意,这并非特定于 Protractor。问题在于 Angular 2 的内置 Testability service Protractor 碰巧使用。 Protractor 调用 Testabil
在调试窗口中,以下表达式均返回 1。 Application.WorksheetFunction.CountA(Cells(4 + (i - 1) * rows_per_record, 28) & "
我在本地使用 jsonplaceholder ( http://jsonplaceholder.typicode.com/)。我正在通过 extjs rest 代理测试我的 GET 和 POST 调用
这是 Postman 为成功调用我的页面而提供的(修改后的)代码段。 var client = new RestClient("http://sub.example.com/wp-json/wp/v2
这个问题在这里已经有了答案: What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must
我想我对 C 命令行参数有点生疏。我查看了我的一些旧代码,但无论这个版本是什么,都会出现段错误。 运行方式是 ./foo -n num(其中 num 是用户在命令行中输入的数字) 但不知何故它不起作用
我已经编写了一个类来处理命名管道连接,如果我创建了一个实例,关闭它,然后尝试创建另一个实例,调用 CreateFile() 返回 INVALID_HANDLE_VALUE,并且 GetLastErro
即使 is_writable() 返回 true,我也无法写入文件。当然,该文件存在并且显然是可读的。这是代码: $file = "data"; echo file_get_contents($fil
下面代码中的变量 $response 为 NULL,尽管它应该是 SOAP 请求的值。 (潮汐列表)。当我调用 $client->__getLastResponse() 时,我从 SOAP 服务获得了
我一直在网上的不同论坛上搜索答案,但似乎没有与我的情况相符的... 我正在使用 Windows 7,VS2010。 我有一个使用定时器来调用任务栏刷新功能的应用程序。在该任务栏函数中包含对 LoadI
我是一名优秀的程序员,十分优秀!