資料類型支援

不同於大部分 SQL 資料庫,Adobe AIR SQL 資料庫引擎不要求或強制資料表欄必須包含特定類型的值,而是由執行階段使用兩種概念 (儲存類別和欄相似性) 來控制資料類型。本節說明儲存類別和欄相似性,以及在不同情況下如何解決資料類型差異:

儲存類別

儲存類別代表用來在資料庫儲存值的實際資料類型。資料庫使用的儲存類別如下:

NULL
值是 NULL 值。

INTEGER
值是具有正負號的整數。

REAL
值是浮點值。

TEXT
值是文字字串 (僅限於 256 MB)。

BLOB
值是二進位大型物件 (Binary Large Object,BLOB),換句說話,就是原始的二進位資料 (僅限於 256 MB)。

凡是以內嵌在 SQL 陳述式中的常值方式提供給資料庫的值,或是使用參數方式繫結至準備好的 SQL 陳述式的值,在該 SQL 陳述式執行之前,執行階段都會為這些值指定一個儲存類別。

在 SQL 陳述式中的常值如果前後加上單引號或雙引號,執行階段會指定為儲存類別 TEXT,如果該常值是指定為未加引號的數字,而且既沒有小數點也沒有指數,則指定為 INTEGER,如果該常值是未加引號的數字,但是有小數點或指數,則指定為 REAL,如果值是 NULL 則指定為 NULL。儲存類別為 BLOB 的常值會使用 X'ABCD' 記號指定。如需詳細資訊,請參閱「運算式中的常值」。

使用 SQLStatement.parameters 關聯陣列提供為參數的值會被指定為最符合原始繫結資料類型的儲存類別。例如,int 值會繫結為 INTEGER 儲存類別,Number 值會指定為 REAL 儲存類別,String 值會指定為 TEXT 儲存類別,而 ByteArray 物件則會指定為 BLOB 儲存類別。

欄相似性

欄「相似性」 是該欄中資料的建議儲存類型。在欄中儲存值時 (透過 INSERT 或 UPDATE 陳述式),執行階段會嘗試將該值從其資料類型轉換為指定的相似性。例如,如果將 Date 值 (ActionScript 或 JavaScript Date 實體) 插入相似性為 TEXT 的欄,該 Date 值就會轉換為 String 形式 (等於呼叫物件的 toString() 方法),然後再儲存到資料庫中。如果該值無法轉換為指定的相似性,就會發生錯誤,而且作業不會執行。使用 SELECT 陳述式從資料庫中擷取值時,會傳回對應到相似性之類別的實體,不論該值原先儲存在資料庫時是否由不同資料類型轉換而成。

如果欄接受 NULL 值,就可以使用 ActionScript 或 JavaScript 值 null 做為參數值,以在該欄中儲存 NULL。在 SELECT 陳述式中擷取 NULL 儲存類別值時,該值一定會以 ActionScript 或 JavaScript 值 null 的形式傳回,不論欄的相似性為何。如果欄接受 NULL 值,務必先檢查從該欄擷取的值,以判斷是否為 null,之後才能嘗試將該值轉型成不可為 null 的類型 (例如 Number 或 Boolean)。

執行階段會為資料庫中的每個欄指定下列其中一個類型相似性:

  • TEXT (或 String)

  • NUMERIC

  • INTEGER (或 int)

  • REAL (或 Number)

  • Boolean

  • Date

  • XML

  • XMLLIST

  • Object

  • NONE

TEXT (或 String)

具有 TEXT 或 String 相似性的欄會使用儲存類別 NULL、TEXT 或 BLOB 儲存所有資料。如果在 TEXT 相似性的欄中插入數值資料,該資料會在儲存之前轉換為文字。

NUMERIC

具有 NUMERIC 相似性的欄會使用儲存類別 NULL、REAL 或 INTEGER 儲存所有資料。在 NUMERIC 欄中插入文字資料時,執行階段會在儲存之前嘗試將它轉換為整數或實數。如果轉換成功,就會使用 INTEGER 或 REAL 儲存類別儲存該值 (例如,'10.05' 的值會轉換為 REAL 儲存類別,再儲存起來)。如果無法執行轉換,則會發生錯誤。執行階段不會嘗試轉換為 NULL 值。從 NUMERIC 欄中擷取的值會以最符合該值的特定數值類型實體傳回。換句話說,如果值是正整數或 0,就會以 uint 實體傳回。如果值是負整數,則以 int 實體傳回。最後,如果值有浮點組件 (不是整數),則以 Number 實體傳回。

INTEGER (或 int)

使用 INTEGER 相似性的欄與具有 NUMERIC 相似性的欄行為類似,但有一個例外。如果要儲存的值是沒有浮點組件的實數 (例如 Number 實體),或該值是可轉換為沒有浮點組件之實數值的文字值,則該值會轉換為整數,並使用 INTEGER 儲存類別儲存。如果嘗試儲存有浮點組件的實數,則會發生錯誤。

REAL (或 Number)

具有 REAL 或 NUMBER 相似性的欄與具有 NUMERIC 相似性的欄行為類似,唯一的例外是它會強制以浮點表示整數值。REAL 欄中的值在從資料庫傳回時,一定會使用 Number 實體。

Boolean

具有 Boolean 相似性的欄會儲存 true 或 false 值。Boolean 欄可接受 ActionScript 或 JavaScript Boolean 實體的值。如果程式碼嘗試儲存 String 值,執行階段會將長度大於零的 String 視為 true,將空白 String 視為 false。如果程式碼嘗試儲存數值資料,任何非零值都儲存為 true,而 0 則儲存為 false。使用 SELECT 陳述式擷取 Boolean 值時,該值會以 Boolean 實體傳回。非 NULL 值會使用 INTEGER 儲存類別儲存 (0 代表 false,1 代表 true),而且在擷取資料時會轉換為 Boolean 物件。

Date

具有 Date 相似性的欄會儲存日期和時間值。Date 欄的用途是接受 ActionScript 或 JavaScript Date 實體的值。如果嘗試在 Date 欄中儲存 String 值,執行階段會嘗試將它轉換為凱撒曆日期。如果轉換失敗,就會發生錯誤。如果程式碼嘗試儲存 Number、int 或 uint 值,執行階段不會驗證資料,並假設它是有效的凱撒曆日期值。使用 SELECT 陳述式擷取的 Date 值會自動轉換為 Date 實體。Date 值會儲存為使用 REAL 儲存類別的凱撒曆日期,所以排序和比較作業會依照您預期的方式進行。

XML 或 XMLList

使用 XML 或 XMLList 相似性的欄會儲存 XML 結構。當程式碼嘗試使用 SQLStatement 參數在 XML 欄中儲存資料時,執行階段會使用 ActionScript XML() 或 XMLList() 函數嘗試轉換並驗證值。如果值無法轉換為有效的 XML,就會發生錯誤。如果嘗試使用常值 SQL 文字值儲存資料 (例如 INSERT INTO (col1) VALUES ('Invalid XML (no closing tag)')),驗證不會剖析或驗證該值,並假設它的格式正確。如果儲存無效的值,擷取時會以空白的 XML 物件傳回。XML 和 XMLList 資料會使用 TEXT 儲存類別或 NULL 儲存類別儲存。

Object

具有 Object 相似性的欄會儲存 ActionScript 或 JavaScript 複雜物件,包括 Object 類別實體,以及 Object 子類別的實體 (如 Array 實體和自訂的類別實體)。Object 欄資料會以 AMF3 格式序列化,並使用 BLOB 儲存類別儲存。擷取值時,該值會從 AMF3 還原序列化,並以儲存之類別的實體傳回。請注意,有些 ActionScript 類別 (尤其是顯示物件) 無法還原序列化為原始資料類型的實體,所以在儲存自訂類別實體之前,您必須使用 flash.net.registerClassAlias() 方法為類別註冊別名 (在 Flex 中則是在類別宣告中加入 [RemoteObject] 中繼資料)。此外,在擷取該資料之前,必須為該類別註冊相同的別名。任何無法正確還原序列化的資料 (不論是因為類別本質上無法還原序列化,或因為類別別名遺漏或不相符) 都會以匿名物件 (Object 類別實體) 傳回,其屬性和值則對應到原先儲存的實體。

NONE

具有 NONE 相似性的欄不偏好任一種儲存類別。它在插入資料之前不會嘗試轉換資料。

決定相似性

欄的類型相似性會由 CREATE TABLE 陳述式中該欄的宣告類型決定。決定類型時所套用的規則 (不區分大小寫) 如下:

  • 如果欄的資料類型包含 "CHAR"、"CLOB"、"STRI" 或 "TEXT" 中任一個字串,則該欄具有 TEXT/String 相似性。請注意,類型 VARCHAR 包含字串 "CHAR",所以會指定為 TEXT 相似性。

  • 如果欄的資料類型包含 "BLOB" 字串,或如果未指定資料類型,則該欄具有 NONE 相似性。

  • 如果欄的資料類型包含 "XMLL" 字串,則該欄具有 XMLList 相似性。

  • 如果資料類型是 "XML" 字串,則該欄具有 XML 相似性。

  • 如果資料類型是 "OBJE" 字串,則該欄具有 Object 相似性。

  • 如果資料類型是 "BOOL" 字串,則該欄具有 Boolean 相似性。

  • 如果資料類型是 "DATE" 字串,則該欄具有 Date 相似性。

  • 如果資料類型包含 "INT" (包括 "UINT") 字串,則該欄會指定為 INTEGER/int 相似性。

  • 如果欄的資料類型包含 "REAL"、"NUMB"、"FLOA" 或 "DOUB" 中任一個字串,則該欄具有 REAL/Number 相似性。

  • 否則,相似性會是 NUMERIC。

  • 如果資料表是使用 CREATE TABLE t AS SELECT... 陳述式所建立的,則所有欄都未指定資料類型,並指定為 NONE 相似性。

資料類型和比較運算子

執行階段支援二元比較運算子 =、<、<=、>= 和 !=,以及測試集合成員 IN 的作業,和三元比較運算子 BETWEEN。如需有關這些運算子的詳細資訊,請參閱「運算子」。

比較的結果須視所比較兩個值的儲存類別而定。比較兩個值時適用的規則如下:

  • 執行階段會將儲存類別為 NULL 的值視為小於其它任何值 (包括其它儲存類別為 NULL 的值)。

  • INTEGER 或 REAL 值小於任何 TEXT 或 BLOB 值。將 INTEGER 或 REAL 與其它 INTEGER 或 REAL 比較時,會執行數字比較。

  • TEXT 值小於 BLOB 值。比較兩個 TEXT 值時,會執行二進位比較。

  • 比較兩個 BLOB 值時,結果總是使用二進位比較來決定。

三元運算子 BETWEEN 一定會重新轉型為相等的二元運算式。例如,a BETWEEN b AND c 會重新轉型為 a >= b AND a <= c,即使這表示在每一個評估運算式所需的比較中會對 a 套用不同相似性。

類型 a IN (SELECT b ....) 的運算式由之前針對二元運算式列舉的三個規則處理,也就是類似 a = b。例如,如果 b 是欄值而 a 是運算式,則進行任何比較之前會先將 b 的相似性套用到 a。運算式 a IN (x, y, z) 會重新轉型為 a = +x OR a = +y OR a = +z。執行階段會將 IN 運算子右側的值 (在這個範例中是 x、y 和 z 值) 視為運算式,即使它們恰好是欄值。如果 IN 運算子左側的值是欄,就會使用該欄的相似性。如果該值是運算式,則不進行任何轉換。

比較執行方式也會受是否使用 COLLATE 子句影響。如需詳細資訊,請參閱「COLLATE」。

資料類型和數學運算子

對於每個支援的數學運算子 *、/、%、+ 和 -,評估運算式之前,會對每個運算元套用數值相似性。如果任何運算元無法成功轉換為 NUMERIC 儲存類別,運算式會評估為 NULL。

使用連接運算子 || 時,每個運算元都會在評估運算式之前轉換為 TEXT 儲存類別。如果任何運算元無法轉換為 TEXT 儲存類別,運算式的結果將是 NULL。有兩種情況可能發生這種無法轉換值的狀況:一種是運算元的值是 NULL,另一種是 BLOB 包含非 TEXT 的儲存類別。

資料類型和排序

以 ORDER BY 子句將值排序時,儲存類別為 NULL 的值會排在前面。後面接著 INTEGER 和 REAL 值依數值順序排列,後面接著 TEXT 值依二進位順序或指定的定序順序 (BINARY 或 NOCASE) 排列。最後,則是依二進位順序排列的 BLOB 值。排序之前不會進行儲存類別轉換。

資料類型和群組

使用 GROUP BY 子句將值分組時,不同儲存類別的值會被視為不同值。但 INTEGER 和 REAL 值例外,也就是這兩種值的數值如果相等,就會被視為相等。執行階段不會對 GROUP BY 子句的任何結果值套用相似性。

資料類型和複合 SELECT 陳述式

複合 SELECT 運算子 UNION、INTERSECT 和 EXCEPT 會執行數值之間的隱含比較。執行這些比較之前,每個值可能會先套用相似性。複合 SELECT 結果集之中單一欄可傳回的所有值會套用相同的相似性 (如果有的話)。所套用的相似性是第一個組件 SELECT 陳述式傳回的欄中,在該位置有欄值 (而不是其它種類的運算式) 之欄的相似性。如果某個複合 SELECT 欄的組件 SELECT 陳述式都不會傳回欄值,比較之前就不會對該欄的值套用相似性。