2012-02-03 8 views
31

Ktoś niedawno zadał mi to pytanie i pomyślałem, że opublikuję go w Stack Overflow, aby uzyskać trochę informacji.Dlaczego przesyłanie/konwersja z int zwraca gwiazdkę

Oczywiście oba poniższe scenariusze zawodzą.

# 1:

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

błąd oczywisty:

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)) 

nie jest oczywiste, zwraca * (Można by oczekiwać, że jest to arytmetyczna przepełnienie również?)


Teraz moje prawdziwe pytanie brzmi: dlaczego? Czy to tylko z założenia, czy jest za tym coś złego?

Sprawdziłem kilka witryn i nie mogłem uzyskać satysfakcjonującej odpowiedzi.

np. 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

Uwaga wiem/zrozumieć, że gdy liczba całkowita jest zbyt duża, aby być konwertowane do określonej wielkości napisu, że będzie to „przerobiona” na gwiazdkę, jest to oczywista odpowiedź i Żałuję, że nie mogę zgodzić się z każdym, kto ciągle daje tę odpowiedź. Chcę wiedzieć, dlaczego użyto gwiazdki, a nie wyjątku, np. historyczne powody itp.?

+5

wyszukać dziesiętny kod ASCII gwiazdki, aby rozwiązać "tajemnicę". – dasblinkenlight

+0

LOL, 42? Odpowiedź na życie wszechświata i wszystko inne? hehehe – Helix

+6

@ dasblinkenlight - To wyjaśnia, dlaczego 'select *' zwraca ** wszystko ** :). –

Odpowiedz

27

uzyskać jeszcze więcej zabawy, spróbuj tego:

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 

:)


Odpowiedź na zapytania to: "Ze względów historycznych"

typów danych INT i VARCHAR są starsze niż BIGINT i NVARCHAR. Znacznie starszy. W rzeczywistości są one w oryginalnej specyfikacji SQL . Również starsze jest podejście tłumiące wyjątki polegające na zastępowaniu wyjścia gwiazdkami.

Później osoby korzystające z SQL zdecydowały, że zgłaszanie błędu jest lepsze/bardziej spójne, niż zastępowanie fałszywych (i zazwyczaj mylących) łańcuchów wyjściowych. Jednak dla zachowania spójności zachowali wcześniejsze zachowanie dla wcześniej istniejących kombinacji typów danych (aby nie złamać istniejącego kodu).

Tak (dużo później), gdy dodano typy danych BIGINT i NVARCHAR, otrzymały nowe (er) zachowanie, ponieważ nie były objęte wspomnianym powyżej grandfatheringiem.

+1

Awesome, podejrzewałem coś takiego, ale chciałem tylko prawdziwe potwierdzenie, dzięki – Helix

+0

Chciałbym mieć łącze do tabeli konwersji MS SQL Server i odniesienia do wersji. – Markus

+1

To jest świetna odpowiedź. Mieliśmy podobny problem, rzucając 6,7 i 8-znakową INT na CHAR (6), co skutkowało gwiazdką dla osób w wieku 7 lub 8. Spodziewaliśmy się błędu i nasz proces nie importował tych danych. Otrzymaliśmy błąd, ale dane nadal były importowane, po prostu zastępując tę ​​część gwiazdką: ** ErrorMessage: Łańcuch lub dane binarne zostałyby obcięte. ErrorSeverity: 16 ErrorState: 14 ** – Brien

0

Możesz przeczytać na stronie CAST and CONVERT w sekcji "Obcinanie i zaokrąglanie wyników". Int, smallint i tinyint zwrócą *, gdy długość wyniku jest zbyt krótka, aby wyświetlić po przekonwertowaniu na char lub varchar.Inne konwersje liczbowe na ciąg znaków zwrócą błąd.

Powiązane problemy