CREATE PROCEDURE [dbo].[uspGetLogs]
(
@StartDate DATETIME,
@EndDate DATETIME
)
AS
SELECT
sl.ID,
LOG10(sl.Value)
FROM
dbo.SampleList sl
INNER JOIN
(
SELECT
ID,
RANK() OVER(PARTITION BY Codec ORDER BY TimeStampUTC DESC, d.ID DESC) ranked
FROM
dbo.SampleList
WHERE
ListDate BETWEEN @StartDate AND @EndDate
) r
ON
r.ID = sl.ID AND
r.ranked = 1
我用@StartDate = 2014-01-29 @EndDate = 2015-03-14尝试了这个存储过程。
并收到此错误
发生了无效的浮点运算
出错的原因"发生了无效的浮点运算"是数学函数的无效用法。
SELECT LOG10(-3);
SELECT LOG10(0);
如果运行上述功能,则会返回错误。
我能够从整个表集中获取值小于1的单个值。但是该值的ListDate是2015-03-14,因此不应该包括它,因为它没有被存储过程中传递的日期范围转换。
因此,在加入和过滤具有日期范围的数据集之前,存储过程似乎首先在整个集合中执行该函数。
这是预期的吗?
答案 0 :(得分:0)
我不认为有一个保证点可以执行函数,所以我的答案取决于查询计划,取决于优化器决定执行函数的“早期” - 在连接之前或之后。要确保仅对有效值执行该功能,您可以更改为:
CASE WHEN sl.Value < 1 THEN 0 ELSE LOG10(sl.Value) END
答案 1 :(得分:0)
我认为这里可能存在数据问题,因为代码的基本逻辑不会导致问题,请参阅以下示例:
CREATE TABLE #temp1 ( id INT, val INT )
CREATE TABLE #temp2 ( id INT, val INT )
INSERT INTO #temp1 ( id, val )
VALUES ( 1, 1 ), ( 2, 10 ), ( 3, -1 ) -- Negative value for id=3 exculded in subquery
INSERT INTO #temp2 ( id, val )
VALUES ( 1, 1 ), ( 2, 10 ), ( 3, 20 )
SELECT t1.id ,
LOG10(t1.val) AS Val
FROM #temp1 t1
INNER JOIN ( SELECT * ,
RANK() OVER ( PARTITION BY id ORDER BY val ) ranked
FROM #temp2
WHERE id BETWEEN 1 AND 2 -- excludes id 3
) t2 ON t2.id = t1.id
AND t2.ranked = 1
DROP TABLE #temp1
DROP TABLE #temp2
<强>产地:强>
id val
1 0
2 1
如果您将BETWEEN
子句修改为WHERE id BETWEEN 1 AND 3
,则会看到错误,因为包含了负值。
所以我会对数据进行三重检查,如果还有问题,请尝试发布一个重新创建问题的小样本。