2013-03-26 20 views
6

Wpadłem dzisiaj na kod podobny do tego.Czy NULL ma typ danych?

SELECT AuditDomain, 
    ObjectId, 
    AuditSubdomain = CONVERT(VARCHAR(50), NULL), 
    SubDomainObjectId = CONVERT(INT, NULL) 
FROM Audit 

Wydaje się sugerować, że informacje o typie danych mogą być powiązane z wartością NULL. Czy dołącza to metadane do wartości NULL, identyfikując ją jako określony typ danych?

This post szczegóły sposobu na znalezienie typ danych w SQL Server, ale gdy próbuję następujący wiersz wraca jako NULL:

SELECT CAST(SQL_VARIANT_PROPERTY(CONVERT(INT, NULL), 'BaseType') AS VARCHAR(20)) 
+0

Czy próbowałeś google "null datatype"? Może się okazać, że nie jest to typ danych ... a przyczyną działania powyższego kodu jest to, że varchar może mieć wartość zerową. – RandomUs1r

Odpowiedz

12

W SQL Server, NULL jest INT domyślnie u wszystkich scenariusze, które mogę wymyślić. Można to ustalić za pomocą następującego kodu:

SELECT x = NULL INTO #x; 
EXEC tempdb..sp_columns '#x'; 

Wyniki:

TABLE_QUALIFIER TABLE_OWNER TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME 
--------------- ----------- ---------- ----------- --------- --------- 
tempdb   dbo   #x___... x   4   int 

Przed umieściliśmy go na stole lub w inny sposób wiąże się to z pewnym kontekstowych metadanych, co powoduje, że ci kupić? Jaka jest różnica, czy jest to INT lub DATETIME lub coś innego? Co zrobisz z tymi informacjami?

SQL_VARIANT_PROPERTY zwraca NULL, ponieważ wydaje się wymagać podania zarówno metadanych , jak i. Obserwować (z użyciem innego rodzaju po prostu zmieszać go w górę):

SELECT SQL_VARIANT_PROPERTY(NULL, 'BaseType'); 

DECLARE @x DATE; 

SELECT SQL_VARIANT_PROPERTY(@x, 'BaseType'); 

DECLARE @y DATE = SYSDATETIME(); 

SELECT SQL_VARIANT_PROPERTY(@y, 'BaseType'); 

Wyniki:

NULL 

NULL 

date 

Więc wydaje się potrzebować wartość zarówno rodzajem i w celu dokładnego określenia typu bazowego.

Jeśli chodzi o dokładnie dlaczego działa w ten sposób, wzrusza ramionami. Musiałbyś poprosić ludzi o dostęp do kodu źródłowego.

Należy pamiętać, że NULL musi jedynie przyjąć typ bazowy po naciśnięciu ręki serwera SQL Server: utworzyłeś na jej podstawie tabelę. Mogłoby tak być, gdyby SQL Server zwrócił błąd w tej sytuacji (i tak naprawdę w wielu sytuacjach, w których musi odgadnąć, jaki typ danych miałeś na myśli). Sposobem na uniknięcie tego jest nie tworzenie sytuacji, w których SQL Server musi zgadywać (dlatego zapytałem, co zrobisz z tymi informacjami?).

+0

Czy masz odpowiedź, dlaczego funkcja 'sql_variant_property' zwraca" NULL "? – ErikE

+0

@ErikE to odpowiednie? –

+0

Jest to używane z UNION. Dwie tabele nie mają tego samego schematu i tam, gdzie w drugiej tabeli brakuje kolumny, w której zostały umieszczone te instrukcje CONVERT (, NULL). Uruchomiłem wiele testów, w których używam NULL zamiast konwertować i wszystko działa zgodnie z oczekiwaniami. Być może było to niezrozumienie, jak działa UNION i/lub konwersja typu. – Jason

0

wiem, masz już jakieś dobre odpowiedzi, ale myślę SQL_VARIANT_PROPERTY został źle zrozumiany.

Używasz SQL_Variant_Property z kolumną, a następnie wskazujesz, czego chcesz na jego właściwości metadanych. Jednak jeśli jest zerowy, niewiele ci to mówi.

EG:

declare 
    @Start date = getdate() 
, @End datetime= getdate() 
, @Int int = 1 
, @DateNull date 
; 


select 
    sql_variant_property(@Start, 'BaseType') 
, sql_variant_property(@End, 'BaseType') 
, sql_variant_property(@Int, 'BaseType') 
, sql_variant_property(@DateNull, 'BaseType') 

Wrócimy trzy typy danych oraz null. Obsługa NULL jest dużą częścią SQL. Bardzo wielu ludzi, łącznie z mną, czasami chce obsłużyć wartość zerową z wartością reprezentującą ją lub w innym czasie nie dbając o nią. Wariant SQL TYLKO DZIAŁA dla wypełnionej wartości z argumentem: "BaseType", w przeciwnym razie zwróci wartość zerową. O ile mi wiadomo, wynika to z tego, że SQL mówi: "Nie masz tu żadnych danych, nic do określenia dla użycia pamięci."

Ogólnie określę isnull (@thing, 0) podczas pracy z liczbami całkowitymi, gdy wyraźnie chcę, aby zbiór danych zawierał zera dla niewiadomych. Kiedy indziej mogę chcieć, aby użytkownik wiedział o wystąpieniu pustej wartości, coś innego nie było (np. "Nic", "brak") dla raportu. Jeszcze innym razem można użyć koalescencji, aby uzyskać szeroki wachlarz możliwości łączenia (@thing, @otherthing, @yotherotherthing, "unknown").

Myślę, że w kodzie, którego jesteś świadkiem, ktoś coś zmienia, gdy nie jestem pewien, gdzie naprawdę trzeba by coś takiego zrobić. Typ danych kolumny w tabeli jest przechowywany w tym, co musi być, a SQL nie będzie przechowywać w niej pamięci, gdy jest ona równa NULL. Tak więc potrzeba zmiany wydaje się arbitralne IMHO. Wiem, że można obsłużyć większe zużycie pamięci, gdy oczekujesz więcej zer z opcją SPARSE, która została wprowadzona Wierzę w SQL 2008. Ale nie wiem, kiedy rzucić coś, co nie zużywa prawie nic więcej.

0

Z couse NULL ma typ danych. Spróbuj następny kod w celu potwierdzenia:

SELECT 
    CAST(NULL AS date) AS c1, 
    CAST(NULL AS time) AS c2 
INTO #x; 
EXEC tempdb..sp_columns '#x'; 

i myślę, że jest błąd w sql_variant realizacji ponieważ lossing informacje o rodzaju NULL. Szkoda!

0

Nie zgadzam się z @ aaron-bertrand. Ponieważ domyślnie serwer SQl utworzył kolumnę z typem liczb całkowitych do przechowywania wartości NULL, ponieważ wartość Null można wstawić do Int, Datetime, Date, Varchar do dowolnej innej kolumny.

Podczas wstawiania wartości Null do tabeli z SELECT x = NULL INTO #x;

SQl utworzona przez serwer kolumna typu integer domyślnie jako Null można wstawić do kolumny Integer.

Może to być spowodowane charakterem zapytania, które napisaliśmy "SELECT x = NULL INTO #x;" co sprawia, że ​​kolumna jest liczbą całkowitą i wartość NULL.

Powiązane problemy