2013-03-26 62 views
6

我今天遇到類似這樣的代碼。NULL是否有數據類型?

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

它似乎意味着數據類型信息可以與NULL值相關聯。這是否將元數據附加到將其標識爲指定數據類型的NULL值?

This post詳細辦法找到SQL Server中的數據類型,但是當我嘗試下面一行它回來爲NULL:

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

你有沒有試過Google搜索「空數據類型」?您可能會發現它不是數據類型......上述代碼的工作原因是因爲varchar可能爲空。 – RandomUs1r 2013-03-26 21:20:32

回答

12

在SQL Server中,NULLINT默認情況下,所有的我能想到的情景。你可以用下面的代碼確定此:

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

結果:

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

你已經把之前到表或以其他方式與一些上下文元數據相關聯的,是什麼給你買?它與INTDATETIME或其他什麼有什麼不同?你將如何處理這些信息?

SQL_VARIANT_PROPERTY返回NULL,因爲它似乎要求元數據的值是有意義的。觀察(使用不同類型的只是混合起來):

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

結果:

NULL 

NULL 

date 

所以它似乎既需要一個類型值,以便準確判斷基本類型。

至於爲什麼它這樣工作,聳聳肩。你必須要求訪問源代碼的人。

請注意,NULL只有在您強制SQL Server的時候才需要採用基本類型:您已經基於此創建了一個表。在這種情況下,SQL Server可能會返回一個錯誤(事實上在許多情況下,它必須猜測你的數據類型)。避免這種情況的方法是不要創建SQL Server必須猜測的情況(這就是爲什麼我問,爲什麼要使用這些信息?)。

+0

爲什麼'sql_variant_property'函數返回'NULL'你有答案嗎? – ErikE 2013-03-26 21:40:26

+0

@ErikE那合適? – 2013-03-26 21:47:27

+0

這與UNION一起使用。這兩個表格沒有相同的模式,而第二個表格缺少一列,他們放置了這些CONVERT(,NULL)語句。我已經運行了多個測試,在這裏我使用NULL來代替轉換,並且一切都按預期工作。也許這是對UNION和/或類型轉換如何工作的誤解。 – Jason 2013-03-26 22:11:23

0

我知道你已經有一些很好的答案,但SQL_VARIANT_PROPERTY我覺得被誤解了。

您將SQL_Variant_Property與列一起使用,然後指示您想要的元數據屬性。但是,如果它是空的,它不會告訴你很多。

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

將返回三個數據類型和空。處理NULL是SQL的重要組成部分。很多人,包括我自己在內,有時希望用價值來表示它,否則在其他時候不關心。 SQL Variant只能使用參數'BaseType'工作,否則它將返回一個空值。據我所知這是由於SQL說:「你沒有數據,沒有什麼可以確定內存使用。」

通常我會指定isnull(@thing,0),當我使用整數時,我明確地希望數據集包含未知數的零。在其他時候,我希望有一個用戶知道一個null事件爲某個報告做了別的事情(@thing,'not present')。還有一些時候,你可以使用coalesce來實現一系列的posizities coalesce(@thing,@otherthing,@yotheotherthing,'unknown')。

我認爲在代碼中你正在見證某人正在轉換某些東西,因爲我不確定你真的需要做這樣的事情。表中的列的數據類型保持其所需的內容,並且當SQL爲NULL時,SQL不會將內存存儲在其中。所以需要改變它似乎任意恕我直言。我知道,如果您希望通過SQL 2008中引入的SPARSE選項獲得更多的空值,那麼您可以處理更好的內存消耗。但是,我不知道什麼時候可以將幾乎沒有任何消耗的東西投入更多。

0

couse NULL有數據類型。 嘗試下一編碼確認:

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

,我認爲有錯誤的SQL_VARIANT實現,因爲它有關NULL類型損耗信息。太糟糕了!

0

我不同意@ aaron-bertrand。自從默認情況下,SQl服務器創建了具有整數數據類型的列來存儲NULL值,因爲Null可以插入到Int,Datetime,Date,Varchar任何其他列中。

在表中插入空值時使用 SELECT x = NULL INTO #x;

SQl服務器創建的整數類型列默認爲Null,可以插入Integer列。

所以可能是由於我們編寫的查詢的性質「SELECT x = NULL INTO #x;」這使列作爲整數並將NULL值。

相關問題