Я пытался понять, почему я получаю «деление на ноль» (Msg 8134) с моим запросом SQL, но я должен что-то упустить.Я хотел бы знать почему для конкретного случая ниже, я не ищу NULLIF
, CASE WHEN...
или подобное, как я уже знаю о них (и можетКонечно, используйте их в ситуации, описанной ниже).
У меня есть оператор SQL с вычисляемым столбцом, похожим на
SELECT
TotalSize,
FreeSpace,
(FreeSpace / TotalSize * 100)
FROM
tblComputer
...[ couple of joins ]...
WHERE
SomeCondition = SomeValue
Выполнение ошибок этого оператора с вышеупомянутыми сообщениями об ошибках, которыесама по себе не является проблемой - очевидно, TotalSize
вполне может быть 0 и, следовательно, вызвать ошибку.
Теперь я не понимаю, что у меня нет строк, где столбец TotalSize
равен 0, когда я закомментирую вычисляемый столбец, я дважды проверил, что это не так.
Тогда я подумал, что по какой-то причине вычисление столбца будет выполнено для всего набора результатов до фактической фильтрации с условиями условия where, но это а) не имеет смысла, imho иб) при попытке воспроизвести ошибку с тестовой настройкой все работает нормально (см. ниже):
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0001',1)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0002',1)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0003',1)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0004',0)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0005',1)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0006',0)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0007',1)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (1,100,21)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (2,100,10)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (3,100,55)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (4,0,10)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (5,100,23)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (6,100,18)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (7,100,11)
-- This statement does not throw an error as apparently the row for ComputerID 4
-- is filtered out before computing the (FreeSpace / TotalSize * 100)
SELECT
TotalSize,
FreeSpace,
(FreeSpace / TotalSize * 100)
FROM
tblComputer
JOIN
tblHDD ON
tblComputer.ID = tblHDD.ComputerID
WHERE
IsServer = 1
Я весьма озадачен и хотел бы знать, в чем причина.
Любые идеи или указатели в правильном направлении очень приветствуются, заранее спасибо
Обновление
Спасибо за ваш вклад, но, к сожалению, я, кажется, не будустановится ближе к корню проблемы.Мне удалось немного сократить оператор, и теперь есть случай, когда я могу выполнить его без ошибок, если будет удален один JOIN (он понадобится мне для дополнительных столбцов в выводе, который я временно удалил).
Я не понимаю, почему использование JOIN приводит к ошибке, не должен ли стандартный INNER JOIN всегда возвращать одинаковое количество строк или меньше , но никогда больше ?
Рабочий код
SELECT
TotalSize,
FreeSpace
((FreeSpace / TotalSize) * 100)
FROM
MyTable1
INNER JOIN
MyTable2 ON
MyTable1.ID = MyTable2.Table1ID
WHERE
SomeCondition
Ошибка, вызывающая код
SELECT
TotalSize,
FreeSpace
((FreeSpace / TotalSize) * 100)
FROM
MyTable1
INNER JOIN
MyTable2 ON
MyTable1.ID = MyTable2.Table1ID
-- This JOIN causes "divide by zero encountered" error
INNER JOIN
MyTable3 ON
MyTable2.ID = MyTable3.Table2ID
WHERE
SomeCondition
Я также попытал счастья, используя курсор и циклически повторяярезультат строка за строкой, но в этом случае ошибки не возникло (независимо от того, какое из двух утверждений выше я пробовал).
Извините за грязный отступ кода, каким-то образом правильное форматирование не выглядитприменяется.
G.