2015-12-17 3 views
0

У меня есть следующий запрос, который бросает:SQL Server: оператор Case отображает Msg 8115, Ошибка арифметического переполнения преобразования VARCHAR в тип данных числовой

арифметическая ошибка переполнения преобразовывая VARCHAR к типу данных числовой.

Запрос:

Select 
    @Fee = Case 
       When IsNull(Fee, '') = '' Then 0.00 
       Else Fee 
      End 

@Fee имеет тип Money и Fee является Varchar типа.

Я также наблюдаю, что для следующих типов данных в пункте Then ошибка не отображается.

Select @Fee = Case When IsNull(Fee, '') = '' Then 1 Else Fee End 
Select @Fee = Case When IsNull(Fee, '') = '' Then 1.0 Else Fee End 

Таким образом, только для значений 0.00 или 0.0 в Then статье я получаю сообщение об ошибке.

Я также протестировали с ниже запроса и работал отлично:

Select @Fee = Case When IsNull(Fee, '') = '' Then Cast(0.00 as money) Else Fee End 

И еще интересно то, что, согласно данным мы имеем в таблице, Then часть Case заявления никогда не будет выполнена. Пожалуйста, помогите мне понять это поведение оператора Case.

+0

делает взнос на колонке? Если это так, пожалуйста, дайте образцы данных столбца сборов. – Dhaval

+0

Да @Dhaval Fee - это столбец типа Varchar, и все, что у меня есть, есть значение 2 в столбце – PS078

ответ

2

Я играл вокруг этого, и это то, что происходит:

DECLARE @v VARCHAR(20) = '1' 
SELECT CASE WHEN '' <> '' THEN 0.00 ELSE @v END col1 INTO tempTable 

Когда вы выполняете вышеприведенный запрос, вы увидите сообщение об ошибке, но будет создана таблица и Ty pe столбца, созданного col1, составляет numeric(2,2).Если вы измените на 0.0000, тип будет numeric(4,4). Это означает, что на самом деле тип выражения зависит от этого значения. Также (2,2) означает, что вы можете хранить только значения длиной 2 и все после точки (.12, .25 и т. Д.). Поэтому он не может отличать 1.00 от numeric(2,2), потому что тип не позволяет иметь цифры перед точкой.

Лучшее правило состоит в том, чтобы всегда возвращать одни и те же типы из разных путей выражения case.

Это от Microsoft о возвратном типе случае выражения (https://msdn.microsoft.com/en-us/library/ms181765.aspx):

Возвращает высший тип очередности из множества типов в result_expressions и опциональной else_result_expression. Для получения дополнительной информации о см. Приоритет типа данных (Transact-SQL).

Это примерно типа старшинства, где вы можете увидеть, что numeric предшествует varchar (https://msdn.microsoft.com/en-us/library/ms190309.aspx). Таким образом, возвращаемый тип выражения вашего дела становится numeric(2,2), и это ответ на ваш вопрос.

Я также дам вам совет: никогда не храните money значения в столбцах varchar. Всегда сохраняйте значения в соответствующем типе (доступно так много типов, что все ваши потребности будут удовлетворены).

1

У вас есть CASE выражение, которое возвращает два различных типов данных - вот всегда действительно плохая идея ....

Select 
    @Fee = Case 
       When IsNull(Fee, '') = '' Then 0.00 
       Else Fee 
      End 
  • Когда Fee фактически является NULL, то вы возвращаете 0.00 - числовое значение
  • Когда Fee (varchar) является NOT NULL, то вернуть это значение - строка

Поскольку оба случая назначены одной и той же переменной @Fee - SQL Server должен принуждать их к одному типу данных - независимо от того, что @Fee диктует (money в вашем случае).

И по какой-то причине, в случае Fee, являющийся NOT NULL, это кажется неудачным в разы.

Так дело: всякий раз, когда это возможно, вернуть же тип данных из всех возможных значений в CASE заявление - и сделать это явно (с помощью CAST или CONVERT) - не заставить SQL Server для обработки это для вас

+0

Спасибо @marc_s, но когда я использую 1.0 вместо 0.00, ошибка не отображается. Пожалуйста, помогите мне понять это поведение на основе данных. – PS078

1

код будет воспроизводить ваш вопрос

DECLARE @Fee MONEY 
DECLARE @test VARCHAR 

SELECT @Fee = ISNULL(@test, 0.00) 

Select @fee 

но это одно исправление

DECLARE @Fee MONEY 
DECLARE @test VARCHAR 

SELECT @Fee = ISNULL(@test, '0.00') 

Select @fee 
Смежные вопросы

 Смежные вопросы