2012-02-03 13 views
31

Alguien me hizo esta pregunta recientemente y pensé que la publicaría en Stack Overflow para obtener alguna entrada.Por qué lanzar/convertir de int devuelve un asterisco

Ahora, obviamente, se supone que ambos de los siguientes escenarios fallan.

# 1:

DECLARE @x BIGINT 
SET @x = 100 
SELECT CAST(@x AS VARCHAR(2)) 

error evidente:

Msg 8115, Level 16, State 2, Line 3
Arithmetic overflow error converting expression to data type varchar.

# 2:

DECLARE @x INT 
SET @x = 100 
SELECT CAST(@x AS VARCHAR(2)) 

No es obvio, se devuelve un * (Uno esperaría que esto sea una aritmética desbordamiento también??)


Ahora mi verdadera pregunta es, ¿por qué ??? ¿Es esto simplemente por diseño o hay historia o algo sin sentido detrás de esto?

Miré algunos sitios y no pude obtener una respuesta satisfactoria.

p. Ej. http://beyondrelational.com/quiz/sqlserver/tsql/2011/questions/Why-does-CAST-function-return-an-asterik--star.aspx

http://msdn.microsoft.com/en-us/library/aa226054(v=sql.80).aspx

Tenga en cuenta que sé/entienden que cuando un entero es demasiado grande para ser convertido a una cadena de tamaño específico que va a ser "convertido" a un asterisco, esta es la respuesta obvia y Desearía poder rechazar a todos los que siguen dando esta respuesta. Quiero saber por qué se usa un asterisco y no una excepción, p. Ej. razones históricas, etc?

+5

busca el código ASCII decimal de un asterisco para resolver el "misterio". – dasblinkenlight

+0

LOL, 42? La respuesta a la vida del universo y todo lo demás? hehehe – Helix

+6

@dasblinkenlight - Eso explica por qué 'select *' devuelve ** todo ** :). –

Respuesta

27

Para más diversión, prueba este:

DECLARE @i INT 
SET @i = 100 
SELECT CAST(@i AS VARCHAR(2)) -- result: '*' 
go 

DECLARE @i INT 
SET @i = 100 
SELECT CAST(@i AS NVARCHAR(2)) -- result: Arithmetic overflow error 

:)


La respuesta a su consulta es: "razones históricas"

Los tipos de datos INT y VARCHAR son más antiguos que BIGINT y NVARCHAR. Mucho anterior. De hecho, están en las especificaciones originales de SQL. También es más antiguo el enfoque de supresión de excepciones de reemplazar la salida con asteriscos.

Más tarde, la gente de SQL decidió que arrojar un error era mejor/más consistente, etc. que sustituir cadenas de salida falsas (y generalmente confusas). Sin embargo, por coherencia mantuvieron el comportamiento anterior para las combinaciones preexistentes de tipos de datos (para no romper el código existente).

De modo que (mucho más tarde) cuando se agregaron los tipos de datos BIGINT y NVARCHAR, obtuvieron el nuevo comportamiento (er) porque no estaban cubiertos por la ampliación mencionada anteriormente.

+1

Impresionante, sospeché algo como esto, pero solo quería una confirmación real, gracias – Helix

+0

Me gustaría tener un enlace a la tabla de conversión de MS SQL Server y una referencia de versión. – Markus

+1

Esta es una gran respuesta. Tuvimos un problema similar aquí, lanzando 6,7 y 8 dígitos INT a CHAR (6), lo que dio como resultado un asterisco para aquellos que tenían 7 u 8. Esperábamos obtener un error y nuestro proceso no importó esta información. Recibimos un error, pero los datos todavía se importaron, simplemente reemplazando esta parte con un asterisco: ** ErrorMessage: cadena o datos binarios se truncarán. ErrorSeverity: 16 ErrorState: 14 ** – Brien

0

Puede leer en la página CAST and CONVERT en la sección "Truncar y redondear resultados". Int, smallint y tinyint devolverán * cuando la longitud del resultado sea demasiado corta para mostrar cuando se convierte en char o varchar.Otras conversiones de cadena a numérica devolverán un error.

Cuestiones relacionadas