2016-12-09 20 views
6

Natrafiłem niedawno na problem w skrypcie SQL, gdzie instrukcja insert (wstawiająca wiele wierszy) miała kolumnę typu varchar (10), a wiersze danych, które wstawiał, przekazywały w int.SQL po cichu konwertuje int na varchar, ale następnie generuje błąd, gdy napotka varchar?

Jednak, kiedy dodaje się nowy wiersz danych do wstawiania i stosowane varchar w kolumnie varchar SQL próbowali przekształcić int, mimo że kolumna typu VarChar (10)

Oto przykład, który możesz uruchomić lokalnie.

CREATE TABLE dbo.TestTable 
    (
    VarcharColumn varchar(10) NOT NULL 
    ) ON [PRIMARY] 

insert into TestTable(VarcharColumn) 
Values (1) 

Po uruchomieniu tego wstawia dobrze, SQL musi cicho przekonwertować wartość całkowitą na varchar za kulisami.

Jednak wtedy, jeśli spróbujesz to:

insert into TestTable(VarcharColumn) 
Values (1),(2),('Hello') 

SQL rzuci się następujący błąd:

Conversion failed when converting the varchar value 'Hello' to data type int.

Czy ktoś może zaoferować wyjaśnienie do wewnętrznych mechanizmów SQL w tym przypadku? Konkretnie:

  1. Dlaczego SQL pozwala na wstawianie liczb całkowitych w kolumnach varchar
  2. Dlaczego gdy SQL jest cicho konwersji tych wartości, jeśli przebiega rzeczywistej varchar będzie starał się przekształcić go na int.

Rozumiem, jak rozwiązać ten problem i jak go uniknąć, ale szukam wyjaśnienia, dlaczego SQL działa w ten sposób.

+2

przejść przez [dokumentacja] (https://msdn.microsoft.com/en-us/library/ms191530.aspx) –

+0

Co jest wyjaśniać? Twoje pytania pokazują, że dokładnie rozumiesz, jaka jest sytuacja. Odpowiedź brzmi: Tak działa SQL Server. –

+0

@GordonLinoff, to nie jest to, o co prosiłem. Zadałem dwa pytania: jedno, dlaczego zezwala na niejawną konwersję (która wydaje się wyjaśniać odsyłacz vkp do dokumentacji) i jak niejawna konwersja działa w instrukcjach wstawiania z wieloma wierszami. "Tak po prostu działa" to okropne, nic nie mówi. –

Odpowiedz

7

Oto co się stało. Po uruchomieniu programu SQL Server przeszedł on przez wiersze i zorientował się, że istnieje tam więcej niż jeden typ danych. Dlatego przekształcił go w ten o najwyższym priorytecie (int vs varchar).

Właśnie dlatego wystąpił błąd.

Zobacz więcej na temat typów danych pierwszeństwa tutaj

https://msdn.microsoft.com/en-us/library/ms190309.aspx

+0

@GordonLinoff Myślę, że masz rację. Zmieniłem odpowiedź. – DVT

+0

. . Myślę, że określa typy podczas kompilacji. Może generować błąd w kompilacji; może wygenerować błąd podczas działania. Jeśli znasz jej błąd kompilacji, to opis jest w porządku. –

+0

@GordonLinoff Próbowałem uruchomić test z INSERT ... VALUES (1), (2). Mam plan kwerend (od prawej do lewej) z Constant Scan -> Compute Scalar -> Table Insert -> INSERT. Domyślam się, że najpierw wykonano skanowanie ciągłe, konwertując wszystko na int, a następnie wstawiono Table int, aby przekształcić int w varchar. – DVT