Я нашел несколько утверждений в одной процедуре, которые я сначала счел неверными, но после их проверки я убедился, что они работают нормально. Чего я не могу понять, так это пути.
У меня есть простая таблица с записью столбцов id, pts и ptsOf:
DECLARE @DataSource TABLE
(
RecordID TINYINT
,Pts INT
,PtsOf INT
)
INSERT INTO @DataSource
VALUES (1,5,5)
,(1,7,8)
,(1,3,5)
,(2,5,0)
и мне нужно рассчитать общий балл для каждой записи, используя следующую формулу:
SUM(pts)/SUM(ptsOf) * 100
Итак, приведенный выше оператор сгенерирует следующую ошибку, потому что для последней записи у меня будет 5/0:
Сообщение 8134, уровень 16, состояние 1, строка 21 Разделить на ноль обнаружена ошибка.
Но оператор, который я нашел, проверяет деление на ноль только в предложении select и не делает этого в предложении order by:
SELECT RecordID
,CAST(CAST(SUM(Pts) AS decimal) / CASE SUM(PtsOf) WHEN 0 THEN NULL ELSE SUM(PtsOf) END * 100 AS decimal(18, 0))
FROM @DataSource
GROUP BY RecordID
ORDER BY RecordID, CAST(CAST(SUM(Pts) AS decimal) / SUM(PtsOf) * 100 AS decimal(18, 0)) ASC
Почему вычисление в разделе order by не приводит к ошибке?
Ниже приведен полный пример:
SET NOCOUNT ON
GO
DECLARE @DataSource TABLE
(
RecordID TINYINT
,Pts INT
,PtsOf INT
)
INSERT INTO @DataSource
VALUES (1,5,5)
,(1,7,8)
,(1,3,5)
,(2,5,0)
SELECT RecordID
,CAST(CAST(SUM(Pts) AS decimal) / CASE SUM(PtsOf) WHEN 0 THEN NULL ELSE SUM(PtsOf) END * 100 AS decimal(18, 0))
FROM @DataSource
GROUP BY RecordID
ORDER BY RecordID, CAST(CAST(SUM(Pts) AS decimal) / SUM(PtsOf) * 100 AS decimal(18, 0)) ASC
SET NOCOUNT OFF
GO
ORDER BY RecordID, (CRYPT_GEN_RANDOM(1) *0) + CAST(CAST(SUM(Pts) AS decimal) / SUM(PtsOf) * 100 AS decimal(18, 0))
, вы увидите, что оценка больше не откладывается и возникает ошибка, как в примере 4 в этой статье. - person Martin Smith   schedule 30.03.2013