2012-08-30 7 views
6

Este es bastante sencillo. ¿Por qué el código siguiente causa el siguiente error?Variable decimal (10,9) no puede contener el número 50 (SQL Server 2008)

declare @dTest decimal(10, 9) 
set @dTest = 50 

Error:

Msg 8115, Level 16, State 8, Line 3 
Arithmetic overflow error converting int to data type numeric. 

Según la MSDN documentation en decimal(p, s), p (o 10 en mi caso) es el "número máximo total de dígitos decimales que se pueden almacenar, tanto a la izquierda y a la derecha del punto decimal "mientras que s (o 9 en mi caso) es el" número máximo de dígitos decimales que se pueden almacenar a la derecha de la d punto ecimal ".

mi número, 50, tiene sólo 2 dígitos en total (que menos de los máximos 10), y 0 dígitos a la derecha del punto decimal (que es menor que el máximo 9), por lo tanto, debería funcionar .

Encontré this question esencialmente el mismo problema, pero nadie explicó por qué la documentación parece estar en conflicto con el comportamiento. Parece que la dimensión s en realidad está siendo interpretado como el fija número de dígitos a la derecha del punto decimal, y siendo resta de la número p, que en mi caso deja 10-9 = 1 solo dígito restante para manejar el lado izquierdo.

¿Alguien puede proporcionar una forma razonable de interpretar la documentación tal como está escrita para que coincida con el comportamiento?

EDIT:

veo algunas explicaciones a continuación, pero no abordan el problema fundamental con el texto de los documentos. Yo sugeriría que este cambio en la redacción:

Por "p (precisión)" cambio "El número total máximo de dígitos decimales que se puede almacenar" leer "El número total máximo de dígitos decimales que se almacenar" .

Y para "s (scale)" change "El número máximo de dígitos decimales que se pueden almacenar a la derecha del punto decimal". a "Se almacenará a la derecha del punto decimal el número de dígitos decimales que . Este número se resta de p para determinar el número máximo de dígitos a la izquierda del punto decimal".

Voy a enviar un informe de error a Connect a menos que alguien tenga una mejor explicación.

+0

MS respondió a mi informe de errores y ahora ha actualizado la documentación de SQL Server 2012 como sugerí. Consulte https://connect.microsoft.com/SQLServer/feedback/details/760495/. ¡Toma eso, downvoters! : P –

Respuesta

5

presenté un informe de error a Conectar: ​​Misleading documentation on the decimal data type

+1

Ah, y para aquellos que me votan, por favor, lea un poco más de cerca. Dos expertos anteriores han admitido en los comentarios a continuación sus respuestas que esto es un error u omisión en los documentos. Esta no es la primera vez que encuentro errores en MSDN donde la redacción precisa no coincide con el comportamiento del idioma. La última vez fue hace solo unos meses, y no solo Jon Skeet estuvo de acuerdo, sino que un empleado de MS ayudó a impulsar el informe de errores en Connect, y consiguió los documentos cambiados: http://stackoverflow.com/questions/9689839/msdn -documentation-error-if-the-procedure-is-shared-all-its-local-variables-a. –

+2

MS respondió a mi informe de errores y ahora ha actualizado la documentación de SQL Server 2012 como sugerí. https://connect.microsoft.com/SQLServer/feedback/details/760495/. Toma eso, downvoters :-) –

+1

Estoy votando para negar algunos de los votos a la baja, porque la documentación * es * incorrecta y la pregunta original y esta respuesta son correctas al señalar eso. –

10

10 - 9 es 1. DECIMAL(10, 9) puede contener un número en el formato 0.000000000. 50 tiene dos dígitos antes del punto decimal, y por lo tanto está fuera de rango. Usted ha citado usted mismo:

According to the MSDN documentation on decimal(p, s), p (or 10 in my case) is the "maximum total number of decimal digits that can be stored, both to the left and to the right of the decimal point" whereas s (or 9 in my case) is the "maximum number of decimal digits that can be stored to the right of the decimal point."

+2

"DECIMAL (10, 9) puede contener un número en el formato 0.000000000". ¿Cómo se sigue de la documentación? No se trata de restar * s * de * p *, se trata de los * máximos * dígitos almacenables en total, y en el lado derecho. Como 50 no tiene ninguno en el lado derecho, debe seguir que los 10 dígitos * totales * restantes se pueden usar en el lado izquierdo. –

+0

@JordanRieger: No, especificó que la precisión es 9 a la izquierda, por lo que será 9 a la izquierda y 1 a la derecha. No varía – Ryan

+1

Creo que te refieres a 9 a la * derecha *. ¿Dónde dice el doctor que (10, 9) significa que hay * siempre * 9 dígitos a la derecha? Solo dice que el * máximo * a la derecha es 9. –

2

Una forma razonable interpretar la documentación es que se arrastran decimales cero dígitos no se tienen en cuenta. Entonces su número tiene 9 dígitos decimales a la derecha del punto decimal, y todos son 0.

+0

No, porque podría haber una cantidad infinita de dígitos cero finales. ¿Qué hay para decir que el número "50" tiene 9 o 999 cero? –

+0

El parámetro 's' en tu tipo' DECIMAL (p, s) 'especifica exactamente cuántos dígitos finales se almacenan en la representación. –

+0

No, según los documentos, especifica la cantidad * máxima * de dígitos finales. Por favor, comprenda, no cuestiono el comportamiento de SQL Server, sino que cuestiono la redacción de los documentos. –

1

DECIMAL(10, 9) es un tipo de datos numéricos de escala y precisión fijos. Esto significa que siempre almacena el mismo número de dígitos a la derecha del punto decimal. Por lo tanto, el tipo de datos que especificó puede solo almacenar números con un dígito a la izquierda del punto decimal y 9 dígitos a la derecha. Obviamente, 50 no cabe en un número de ese formato.

1

Ir pesar de que el enlace de más abajo. http://msdn.microsoft.com/en-gb/library/ms190476.aspx

Precisión es el número de dígitos de un número. La escala es la cantidad de dígitos a la derecha del punto decimal en un número. Por ejemplo, el número 123.45 tiene una precisión de 5 y una escala de 2.

+0

Desafortunadamente esa definición entra en conflicto con http://msdn.microsoft.com/en-us/library/ms187746(v=sql.110).aspx, que usa la palabra "máximo", por lo que dos empleados de Microsoft por separado aceptaron mi presentación para obtener la documentación engañosa modificada. Consulte https://connect.microsoft.com/SQLServer/feedback/details/760495/misleading-documentation-on-the-decimal-data-type. Todo lo que necesitan hacer es eliminar la palabra "máximo" y cambiar "puede" por "voluntad" en la definición "s", y agregar la otra oración que mencioné en mi pregunta original. Parece que aún no han llegado a eso :) –