支援的 SQL 語法Adobe AIR SQL 資料庫引擎支援下列 SQL 語法清單。這些清單分為幾個部分,分別說明不同陳述式和子句類型、運算式、內建函數和運算子。涵蓋的主題如下:
一般 SQL 語法除了各種陳述式和運算式的特定語法之外,SQL 語法的一般規則如下:
資料操作陳述式資料操作陳述式是最常用的 SQL 陳述式。這些陳述式會用來擷取、新增、修改和移除資料庫資料表中的資料。支援的資料操作陳述式如下:SELECT、INSERT、UPDATE 和 DELETE。 SELECT SELECT 陳述式會用來查詢資料庫。SELECT 的結果是零或多個資料列,其中每一列都有固定數目的欄。結果中的欄數由 SELECT 和選擇性的 FROM 關鍵字之間的 result 欄名稱或運算式清單指定。 sql-statement ::= SELECT [ALL | DISTINCT] result [FROM table-list] [WHERE expr] [GROUP BY expr-list] [HAVING expr] [compound-op select-statement]* [ORDER BY sort-expr-list] [LIMIT integer [( OFFSET | , ) integer]] result ::= result-column [, result-column]* result-column ::= * | table-name . * | expr [[AS] string] table-list ::= table [ join-op table join-args ]* table ::= table-name [AS alias] | ( select ) [AS alias] join-op ::= , | [NATURAL] [LEFT | RIGHT | FULL] [OUTER | INNER | CROSS] JOIN join-args ::= [ON expr] [USING ( id-list )] compound-op ::= UNION | UNION ALL | INTERSECT | EXCEPT sort-expr-list ::= expr [sort-order] [, expr [sort-order]]* sort-order ::= [COLLATE collation-name] [ASC | DESC] collation-name ::= BINARY | NOCASE 任何隨意的運算式都可做為結果。如果結果運算式是 *,則那一個運算式就會由所有資料表的所有欄取代。如果運算式是資料表名稱後面接著 .*,則結果便是該資料表的所有欄。 DISTINCT 關鍵字會導致傳回結果列的子集,這些結果列每個各不相同。NULL 值不會被視為與其它值不同。預設行為會傳回所有結果列,這也可用關鍵字 ALL 明確指定。 查詢執行時,會針對 FROM 關鍵字後指定的一或多個資料表進行查詢。如果用逗號分隔多個資料表名稱,查詢會使用各個資料表的交叉聯結。JOIN 語法也可用來指定資料表的聯結方式。唯一支援的一種外部聯結類型是 LEFT OUTER JOIN。join-args 中的 ON 子句運算式必須解析成 Boolean 值。FROM 子句中可以使用括在括弧中的子查詢做為資料表。整個 FROM 子句可以完全省略,如此一來,結果便是由 result 運算式清單的值所構成的單一列。 WHERE 子句會用來限制查詢擷取的列數。WHERE 子句運算式必須解析成 Boolean 值。WHERE 子句篩選是在任何群組動作之前執行,所以 WHERE 子句運算式不得包含彙總函數。 GROUP BY 子句會導致一或多個結果列在輸出中合併成單一列。當結果包含彙總函數時,GROUP BY 子句會特別好用。GROUP BY 子句中的運算式不一定要是出現在 SELECT 運算式清單中的運算式。 HAVING 子句類似 WHERE,可用來限制陳述式傳回的列。但 HAVING 子句是在 GROUP BY 子句指定的任何群組動作之後套用。因此,HAVING 運算式可以參考包含彙總函數的值。HAVING 子句運算式不一定要出現在 SELECT 清單中。HAVING 運算式和 WHERE 運算式一樣,都必須解析成 Boolean 值。 ORDER BY 子句會導致輸出列經過排序。ORDER BY 子句的 sort-expr-list 引數是做為排序索引鍵的運算式清單。在簡單 SELECT 中,這些運算式不一定要是結果的一部分,但在複合 SELECT (使用其中一個 compound-op 運算子的 SELECT) 中,每個排序運算式都必須確實符合其中一個結果欄。每個排序運算式後面可以選擇性的接著一個 sort-order 子句,內含 COLLATE 關鍵字和用於排列文字的定序函數名稱和 (或) 關鍵字 ASC 或 DESC 以指定排序順序 (遞增或遞減)。sort-order 可以省略,這時會使用預設值 (遞增順序)。如需 COLLATE 子句和定序函數的定義,請參閱「COLLATE」。 LIMIT 子句會設定結果中傳回的列數上限。負數的 LIMIT 表示沒有上限。LIMIT 後面可以選擇性接著 OFFSET,以指定須略過結果集開頭的多少列。在複合 SELECT 查詢中,LIMIT 子句只能出現在最後的 SELECT 陳述式之後,而且限制適用於整個查詢。請注意,如果 LIMIT 子句中使用 OFFSET 關鍵字,則限制是第一個整數,位移是第二個整數。如果用逗號取代 OFFSET 關鍵字,則位移是第一個數字,而限制是第二個數字。這種看起來很矛盾的語法是為了儘可能與舊式 SQL 資料庫系統相容而故意設計的。 複合 SELECT 是由兩個或多個簡單 SELECT 陳述式組成,陳述式之間可使用 UNION、UNION ALL、INTERSECT 或 EXCEPT 其中一個運算子連接。在複合 SELECT 中,所有組成的 SELECT 陳述式都必須指定相同數目的結果欄。只有在最後的 SELECT 陳述式之後 (和唯一的 LIMIT 子句之前,如果有指定的話) 才能有一個 ORDER BY 子句。UNION 和 UNION ALL 運算子會合併前後 SELECT 陳述式的結果,成為單一資料表。差別在於,UNION 的所有結果列各不相同,而 UNION ALL 的所有結果則可以有重複項目。INTERSECT 運算子會取得前後 SELECT 陳述式結果的交集。EXCEPT 會在移除後一個 SELECT 的結果之後取得前一個 SELECT 的結果。如果將三個或更多 SELECT 陳述式複合連接在一起,它們會從第一個到最後一個群組在一起。 如需允許之運算式的定義,請參閱「運算式」。 從 AIR 2.5 開始,支援 SQL CAST 運算子讀取,以便將 BLOB 資料轉換成 ActionScript ByteArray 物件。例如,下列程式碼會讀取不是以 AMF 格式儲存的原始資料,並將它儲存在 ByteArray 物件中: stmt.text = "SELECT CAST(data AS ByteArray) AS data FROM pictures;"; stmt.execute(); var result:SQLResult = stmt.getResult(); var bytes:ByteArray = result.data[0].data; INSERTINSERT 陳述式有兩種基本形式,可用來在資料表中填入資料。
sql-statement ::= INSERT [OR conflict-algorithm] INTO [database-name.] table-name [(column-list)] VALUES (value-list) | INSERT [OR conflict-algorithm] INTO [database-name.] table-name [(column-list)] select-statement REPLACE INTO [database-name.] table-name [(column-list)] VALUES (value-list) | REPLACE INTO [database-name.] table-name [(column-list)] select-statement 第一種形式 (使用 VALUES 關鍵字) 會在現有資料表中建立一個新列。如果未指定 column-list,則值的數目必須與資料表中的欄數相同。如果指定 column-list,則值的數目必須符合指定的欄數。資料表中的欄如果未出現在欄清單中,則該欄將填入建立資料表時所定義的預設值,或填入 NULL (如果未定義預設值)。 第二種形式的 INSERT 陳述式會從 SELECT 陳述式取得資料。如果未指定 column-list,SELECT 結果中的欄數必須完全符合資料表的欄數,否則就必須符合 column-list 中指定的欄數。SELECT 結果中的每一列都會成為資料表中的一個新項目。SELECT 可以是簡單或複合形式。如需允許的 SELECT 陳述式定義,請參閱「SELECT」。 選擇性的 conflict-algorithm 可以指定在這一個命令執行期間使用另一個條件約束衝突解決演算法。如需衝突演算法的說明及定義,請參閱特殊陳述式和子句。 兩個 REPLACE INTO 形式的陳述式相當於使用標準的 INSERT [OR conflict-algorithm] 形式加上 REPLACE 衝突演算法 (即 INSERT OR REPLACE... 形式)。 兩個 REPLACE INTO 形式的陳述式相當於使用標準的 INSERT [OR conflict-algorithm] 形式加上 REPLACE 衝突演算法 (即 INSERT OR REPLACE... 形式)。 UPDATE更新命令會變更表格中現有的記錄。 sql-statement ::= UPDATE [database-name.] table-name SET column1=value1, column2=value2,... [WHERE expr] 命令是由 UPDATE 關鍵字加上您要更新記錄的表格名稱所組成。在 SET 關鍵字後面,請以逗號分隔的清單,提供欄名稱與要變更的欄值。WHERE 子句運算式提供更新記錄的一或多列。 DELETE刪除命令會用來移除資料表中的記錄。
sql-statement ::= DELETE FROM [database-name.] table-name [WHERE expr] 命令包含 DELETE FROM 關鍵字,後面接著要從中移除記錄的資料表名稱。 如果沒有 WHERE 子句,就會移除資料表的所有列。如果提供 WHERE 子句,只會移除符合運算式的列。WHERE 子句運算式必須解析成 Boolean 值。如需允許之運算式的定義,請參閱「運算式」。 資料定義陳述式資料定義陳述式會用來建立、修改和移除資料庫物件,例如資料表、檢視、索引和觸發程序。支援的資料定義陳述式如下:
CREATE TABLECREATE TABLE 陳述式包含關鍵字 CREATE TABLE,後面接著新資料表的名稱,之後則是 (括在括弧裡) 欄定義和條件約束的清單。資料表名稱可為識別名稱或字串。
sql-statement ::= CREATE [TEMP | TEMPORARY] TABLE [IF NOT EXISTS] [database-name.] table-name ( column-def [, column-def]* [, constraint]* ) sql-statement ::= CREATE [TEMP | TEMPORARY] TABLE [database-name.] table-name AS select-statement column-def ::= name [type] [[CONSTRAINT name] column-constraint]* type ::= typename | typename ( number ) | typename ( number , number ) column-constraint ::= NOT NULL [ conflict-clause ] | PRIMARY KEY [sort-order] [ conflict-clause ] [AUTOINCREMENT] | UNIQUE [conflict-clause] | CHECK ( expr ) | DEFAULT default-value | COLLATE collation-name constraint ::= PRIMARY KEY ( column-list ) [conflict-clause] | UNIQUE ( column-list ) [conflict-clause] | CHECK ( expr ) conflict-clause ::= ON CONFLICT conflict-algorithm conflict-algorithm ::= ROLLBACK | ABORT | FAIL | IGNORE | REPLACE default-value ::= NULL | string | number | CURRENT_TIME | CURRENT_DATE | CURRENT_TIMESTAMP sort-order ::= ASC | DESC collation-name ::= BINARY | NOCASE column-list ::= column-name [, column-name]* 每個欄定義是欄名稱後面接著該欄的資料類型,再接著一或多個選擇性的欄條件約束。欄的資料類型會限制該欄中可儲存的資料內容。如果試圖在欄中儲存不同資料類型的值,執行階段將會儘可能將值轉換為適當類型,或引發錯誤。如需其它資訊,請參閱「資料類型支援」一節。 NOT NULL 欄條件約束表示該欄不能包含 NULL 值。 UNIQUE 條件約束會導致對指定的一或多個欄建立索引。這個索引必須包含唯一的索引鍵,也就是針對指定的一或多個欄,任兩列均不得包含重複值或值組合。CREATE TABLE 陳述式可以有多個 UNIQUE 條件約束,包括在欄定義中為多個欄指定一個 UNIQUE 條件約束,和 (或) 多個資料表層級的 UNIQUE 條件約束。 CHECK 條件約束會定義一個要評估的運算式,而且該運算式必須為 True,才會插入或更新列的資料。CHECK 運算式必須解析成 Boolean 值。 欄定義中的 COLLATE 子句會指定比較欄的文字項目時所使用的文字定序函數。預設狀況下會使用 BINARY 定序函數。如需有關 COLLATE 子句和定序函數的詳細資料,請參閱「COLLATE」。 DEFAULT 條件約束會指定執行 INSERT 時所用的預設值。這個值可為 NULL、字串常數或數字。預設值也可以是 CURRENT_TIME、CURRENT_DATE 或 CURRENT_TIMESTAMP 這幾個不區分大小寫的特殊關鍵字中的一個。如果值是 NULL、字串常數或數字,每當 INSERT 陳述式未針對該欄指定值時,這個值就會逐字插入欄中。如果值是 CURRENT_TIME、CURRENT_DATE 或 CURRENT_TIMESTAMP,則會將目前的 UTC 日期和 (或) 時間插入欄中。CURRENT_TIME 的格式是 HH:MM:SS。CURRENT_DATE 的格式是 YYYY-MM-DD。CURRENT_TIMESTAMP 的格式是 YYYY-MM-DD HH:MM:SS。 指定 PRIMARY KEY 通常只會在對應的欄上建立 UNIQUE 索引。但如果在具有 INTEGER 資料類型 (或其中一個同義詞,例如 int) 的單一欄上指定 PRIMARY KEY 條件約束,資料庫便會使用該欄做為資料表的實際主索引鍵。這表示該欄只能存放唯一的整數值 (請注意,在許多 SQLite 實作中,只有 INTEGER 欄類型會將欄當做內部主索引鍵使用,但是在 INTEGER 的 Adobe AIR 同義詞 (例如 int) 中,也會指定該行為)。 如果資料表沒有 INTEGER PRIMARY KEY 欄,則插入列時會自動產生整數索引鍵。只要使用 ROWID、OID 或 _ROWID_ 幾個特殊名稱的其中一個,便可以隨時存取列的主索引鍵。不論是明確宣告的 INTEGER PRIMARY KEY 或內部產生的值,都可以使用這些名稱。但是,如果資料表具有明確的 INTEGER PRIMARY KEY,結果資料中的欄名稱便是實際的欄名稱,而不是特殊名稱。 INTEGER PRIMARY KEY 欄也可以包含關鍵字 AUTOINCREMENT。使用AUTOINCREMENT 關鍵字時,資料庫會在執行沒有明確指定欄值的 INSERT 陳述式時,自動在 INTEGER PRIMARY KEY 欄中產生並插入循序遞增的整數索引鍵。 CREATE TABLE 陳述式中只能有一個 PRIMARY KEY 條件約束。它可以是一個欄定義的一部分,也可以是一個單一資料表層級 PRIMARY KEY 條件約束。主索引鍵欄是隱含的 NOT NULL。 接在許多條件約束後面的選擇性 conflict-clause,可以為該條件約束指定另一個預設的條件約束衝突解決演算法。預設值為 ABORT。同一個資料表中的不同條件約束可以使用不同的預設衝突解決演算法。如果 INSERT 或 UPDATE 陳述式指定不同的衝突解決演算法,就會使用該演算法取代 CREATE TABLE 陳述式中指定的演算法。如需詳細資訊,請參閱特殊陳述式和子句的「ON CONFLICT (衝突演算法)」小節。 額外的條件約束 (如 FOREIGN KEY 條件約束) 不會造成錯誤,但執行階段會予以忽略。 如果 CREATE 和 TABLE 之間出現 TEMP 或 TEMPORARY 關鍵字,則所建立的資料表只會顯示在同一個資料庫連線 (SQLConnection 實體) 中。關閉資料庫連線時,就會自動刪除該資料表。在暫存資料表上建立的任何索引也都是暫時性的。暫存資料表和索引儲存在與主要資料庫檔案不同的另一個檔案中。 如果指定選擇性的 database-name 前置詞,就會在具名資料庫 (以指定的資料庫名稱呼叫 attach() 方法而連接到 SQLConnection 實體的資料庫) 中建立該資料表。除非 database-name 前置詞是 temp,否則,同時指定 database-name 前置詞和 TEMP 關鍵字是錯誤的。如果未指定資料庫名稱,而且沒有 TEMP 關鍵字,則會在主要資料庫 (使用 open() 或 openAsync() 方法連接到 SQLConnection 實體的資料庫) 中建立該資料表。 欄數或資料表的條件約束數目可隨意自訂且沒有限制,另外,列中的資料數量也可隨意自訂且沒有限制。 CREATE TABLE AS 形式會以查詢結果集的形式定義資料表。資料表欄的名稱是結果中欄的名稱。 如果使用選擇性的 IF NOT EXISTS 子句,而且已經有同名的其它資料表,則資料庫會忽略 CREATE TABLE 命令。 使用 DROP TABLE 陳述式可以移除資料表,而使用 ALTER TABLE 陳述式可以進行有限的變更。 ALTER TABLEALTER TABLE 命令可讓使用者將現有資料表重新命名或加入新欄。資料表中的欄無法移除。 sql-statement ::= ALTER TABLE [database-name.] table-name alteration alteration ::= RENAME TO new-table-name alteration ::= ADD [COLUMN] column-def RENAME TO 語法會用來將以 [database-name.] table-name 識別的資料表重新命名成 new-table-name。這個命令無法用來在附加的資料庫之間移動資料表,只能重新命名相同資料庫中的資料表。 如果重新命名的資料表有觸發程序或索引,它們在重新命名後仍會附加到資料表。但如果有任何檢視定義或由觸發程序執行的陳述式參考到重新命名的資料表,它們不會自動修改為使用新資料表名稱。如果重新命名的資料表有關聯的檢視或觸發程序,您必須手動卸除並重新建立觸發程序,或使用新的資料表名稱檢視定義。 ADD [COLUMN] 語法會用來在現有資料表中加入新欄。新欄一定會附加到現有欄清單結束處。column-def 子句可以接受 CREATE TABLE 陳述式中允許的任何形式,但有下列限制:
ALTER TABLE 陳述式的執行時間不受資料表中的資料量影響。 DROP TABLEDROP TABLE 陳述式會移除以 CREATE TABLE 陳述式加入的資料表。卸除的資料表是具有指定 table-name 的資料表。它會從資料庫和磁碟檔案中完全移除。資料表無法復原。與資料表相關聯的所有索引也都會刪除。
sql-statement ::= DROP TABLE [IF EXISTS] [database-name.] table-name 根據預設,DROP TABLE 陳述式不會使資料庫檔案變小。資料庫中的空白空間仍會保留,並供之後的 INSERT 作業使用。若要移除資料庫中的可用空間,請使用 SQLConnection.clean() 方法。如果最初建立資料庫時,將 autoClean 參數設定為 true,則會自動釋放空間。 選擇性的 IF EXISTS 子句會抑制資料庫不存在時所發生的錯誤。 CREATE INDEXCREATE INDEX 命令包含關鍵字 CREATE INDEX,後面接著新索引的名稱、關鍵字 ON、要編製索引的先前已建立資料表名稱,和括在括弧裡的欄名稱清單 (清單中所列是資料表中要做為索引鍵值的欄名稱)。 sql-statement ::= CREATE [UNIQUE] INDEX [IF NOT EXISTS] [database-name.] index-name ON table-name ( column-name [, column-name]* ) column-name ::= name [COLLATE collation-name] [ASC | DESC] 每個欄名稱後面可以接著 ASC 或 DESC 關鍵字以指定排序順序,但執行階段會忽略指定的排序順序。排序方式固定採用遞增順序。 每個欄名稱後面的 COLLATE 子句會定義該欄中文字值所用的定序順序。預設的定序順序是 CREATE TABLE 陳述式中為該欄定義的定序順序。如果未指定定序順序,則使用 BINARY 定序順序。如需 COLLATE 子句和定序函數的定義,請參閱「COLLATE」。 單一資料表可附加的索引數目可隨意自訂且沒有限制,一個索引中的欄數也沒有限制。 DROP INDEXDROP INDEX 陳述式會移除使用 CREATE INDEX 陳述式所加入的索引。指定的索引會從資料庫檔案中完全移除。唯一一個復原索引的方法是重新輸入適當的 CREATE INDEX 命令。 sql-statement ::= DROP INDEX [IF EXISTS] [database-name.] index-name 根據預設,DROP INDEX 陳述式不會使資料庫檔案變小。資料庫中的空白空間仍會保留,並供之後的 INSERT 作業使用。若要移除資料庫中的可用空間,請使用 SQLConnection.clean() 方法。如果最初建立資料庫時,將 autoClean 參數設定為 true,則會自動釋放空間。 CREATE VIEWCREATE VIEW 命令會為預先定義的 SELECT 陳述式指定名稱。然後,這個新名稱就可以用在另一個 SELECT 陳述式的 FROM 子句中,取代資料表名稱。檢視常用來簡化查詢,可將複雜 (且常用) 的資料集合併成結構,以供其它作業使用。 sql-statement ::= CREATE [TEMP | TEMPORARY] VIEW [IF NOT EXISTS] [database-name.] view-name AS select-statement 如果 CREATE 和 VIEW 之間出現 TEMP 或 TEMPORARY 關鍵字,則所建立的檢視只會顯示在開啟資料庫的 SQLConnection 實體中,而且關閉資料庫時就會自動刪除。 如果指定 [database-name],系統會在具名資料庫 (使用 attach() 方法以指定的 name 引數連接到 SQLConnection 實體的資料庫) 中建立該檢視。除非 [database-name] 是 temp,否則,同時指定 [database-name] 和 TEMP 關鍵字是錯誤的。如果未指定資料庫名稱,而且沒有 TEMP 關鍵字,則會在主要資料庫 (使用 open() 或 openAsync() 方法連接到 SQLConnection 實體的資料庫) 中建立該檢視。 檢視是唯讀的,所以 DELETE、INSERT 或 UPDATE 陳述式不能用在檢視上,除非至少定義一個相關類型 (INSTEAD OF DELETE、INSTEAD OF INSERT、INSTEAD OF UPDATE) 的觸發程序。如需為檢視建立觸發程序的詳細資訊,請參閱「CREATE TRIGGER」。 使用 DROP VIEW 陳述式可從資料庫中移除檢視。 DROP VIEWDROP VIEW 陳述式會移除 CREATE VIEW 陳述式所建立的檢視。 sql-statement ::= DROP VIEW [IF EXISTS] view-name 指定的 view-name 是要卸除的檢視名稱。該檢視會從資料庫移除,但基礎資料表中的任何資料都不會修改。 CREATE TRIGGERCREATE TRIGGER 陳述式會用來在資料庫結構中加入觸發程序。觸發程序是當指定的資料庫事件 (database-event) 發生時,會自動執行的資料庫作業 (trigger-action)。 sql-statement ::= CREATE [TEMP | TEMPORARY] TRIGGER [IF NOT EXISTS] [database-name.] trigger-name [BEFORE | AFTER] database-event ON table-name trigger-action sql-statement ::= CREATE [TEMP | TEMPORARY] TRIGGER [IF NOT EXISTS] [database-name.] trigger-name INSTEAD OF database-event ON view-name trigger-action database-event ::= DELETE | INSERT | UPDATE | UPDATE OF column-list trigger-action ::= [FOR EACH ROW] [WHEN expr] BEGIN trigger-step ; [ trigger-step ; ]* END trigger-step ::= update-statement | insert-statement | delete-statement | select-statement column-list ::= column-name [, column-name]* 觸發程序是指定為每當特定資料庫資料表發生 DELETE、INSERT 或 UPDATE 時就會引發,或每當資料表的一或多個指定欄的 UPDATE 發生更新時就會引發。除非使用 TEMP 或 TEMPORARY 關鍵字,否則觸發程序是永久性的。在這種情況下,每當 SQLConnection 實體的主要資料庫連線關閉時,就會移除該觸發程序。如果未指定時間 (BEFORE 或 AFTER),觸發程序會預設為 BEFORE。 由於只支援 FOR EACH ROW 觸發程序,所以 FOR EACH ROW 文字是選擇性的。使用 FOR EACH ROW 觸發程序時,如果 WHEN 子句陳述式評估為 true,就會針對導致引發觸發程序之陳述式所插入、更新或刪除的每個資料庫列執行 trigger-step 陳述式。 如果提供 WHEN 子句,指定為觸發程序步驟的 SQL 陳述式只會針對 WHEN 子句為 True 的列執行。如果未提供 WHEN 子句,則會針對所有列執行這些 SQL 陳述式。 在觸發程序主體 (trigger-action 子句) 內,使用特殊的資料表名稱 OLD 和 NEW,可取得受影響資料表的變更前和變更後值。OLD 和 NEW 資料表的結構符合建立觸發程序之資料表的結構。OLD 資料表包含所觸發的陳述式修改或刪除的任何列,且為執行觸發陳述式作業之前的狀態。NEW 資料表句含所觸發的陳述式修改或建立的任何列,且為執行觸發陳述式作業之後的狀態。WHEN 子句和 trigger-step 陳述式都可以使用 NEW.column-name 和 OLD.column-name 形式的參考從插入、刪除或更新的列中存取值,其中 column-name 是觸發程序相關資料表中的欄名稱。能否使用 OLD 和 NEW 資料表參考需要視觸發程序處理的 database-event 類型而定:
指定的時間 (BEFORE、AFTER 或 INSTEAD OF) 會決定 trigger-step 陳述式相對於插入、修改或移除相關列的執行時間。在 UPDATE 或 INSERT 陳述式的 trigger-step 中可以指定 ON CONFLICT 子句。但如果在導致引發觸發程序的陳述式中指定 ON CONFLICT 子句,則會改用該衝突處理原則。 除了資料表觸發程序外,您也可以在檢視上建立 INSTEAD OF 觸發程序。如果在檢視上定義一或多個 INSTEAD OF INSERT、INSTEAD OF DELETE 或 INSTEAD OF UPDATE 觸發程序,則在檢視上執行相關類型的陳述式 (INSERT、DELETE 或 UPDATE) 並不是錯誤。在這種情況下,在檢視上執行 INSERT、DELETE 或 UPDATE 會導致引發相關的觸發程序。因為觸發程序是 INSTEAD OF 觸發程序,所以導致引發觸發程序的陳述式不會修改檢視的基礎資料表。但是,您可以使用觸發程序對基礎資料表執行修改作業。 在具有 INTEGER PRIMARY KEY 欄的資料表上建立觸發程序時,必須記住一個重點。如果 BEFORE 觸發程序修改了某列的 INTEGER PRIMARY KEY 欄,但導致引發觸發程序的陳述式原本即將修改該列,則更新不會發生。暫時解決方法是建立具有 PRIMARY KEY 欄的資料表,而非具有 INTEGER PRIMARY KEY 欄的資料表。 使用 DROP TRIGGER 陳述式可以移除觸發程序。卸除資料表或檢視時,與該資料表或檢視相關聯的所有觸發程序也都會自動卸除。 RAISE() 函數特殊的 SQL 函數 RAISE() 可以使用在觸發程序的 trigger-step 陳述式中。這個函數的語法如下: raise-function ::= RAISE ( ABORT, error-message ) | RAISE ( FAIL, error-message ) | RAISE ( ROLLBACK, error-message ) | RAISE ( IGNORE ) 在執行觸發程序期間,如果呼叫前三種形式之一,系統會執行指定的 ON CONFLICT 處理動作 (ABORT、FAIL 或 ROLLBACK),並結束目前陳述式的執行。由於 ROLLBACK 表示陳述式執行失敗,所以執行 execute() 方法的 SQLStatement 實體會傳送 error (SQLErrorEvent.ERROR) 事件。在傳送的事件物件中,error 屬性的 SQLError 物件會將其 details 屬性設定為 RAISE() 函數中指定的 error-message。 呼叫 RAISE(IGNORE) 時,目前觸發程序的其餘部分、導致執行觸發程序的陳述式,以及原本接著會執行的任何觸發程序都會放棄。不會回復任何資料庫變更。如果導致執行觸發程序的陳述式本身是某個觸發程序的一部分,則該觸發程序程式會從下一個步驟開頭繼續執行。如需有關衝突解決演算法的詳細資訊,請參閱「ON CONFLICT (衝突演算法)」一節。 DROP TRIGGERDROP TRIGGER 陳述式會移除 CREATE TRIGGER 陳述式所建立的觸發程序。 sql-statement ::= DROP TRIGGER [IF EXISTS] [database-name.] trigger-name 觸發程序會從資料庫中移除。請注意,與觸發程序相關的資料表卸除時,該觸發程序就會自動卸除。 特殊陳述式和子句本節說明執行階段為 SQL 提供的幾個擴充子句,以及可用在許多陳述式、註解和運算式中的兩個語言元素。本節中的元素包括: COLLATECOLLATE 子句會用在 SELECT、CREATE TABLE 和 CREATE INDEX 陳述式中,以指定比較和排序值時所用的比較演算法。 sql-statement ::= COLLATE collation-name collation-name ::= BINARY | NOCASE 欄的預設定序類型是 BINARY。將 BINARY 定序用於 TEXT 儲存類別的值時,二進位定序的執行方式是比較記憶體中代表值的位元組,而不管其文字編碼。 NOCASE 定序順序只適用於 TEXT 儲存類別的值。使用時,NOCASE 定序會執行不區分大小寫的比較。 NULL、BLOB、INTEGER 或 REAL 類型的儲存類別不會使用任何定序順序。 若要針對欄使用 BINARY 以外的定序類型,您必須在 CREATE TABLE 陳述式的欄定義中指定 COLLATE 子句。比較兩個 TEXT 值時,會根據下列規則,使用定序順序來決定比較的結果:
EXPLAINEXPLAIN 命令修飾詞是 SQL 的非標準擴充。 sql-statement ::= EXPLAIN sql-statement 如果 EXPLAIN 關鍵字出現在其它任何 SQL 陳述式之前,則結果是不實際執行命令,而是報告在沒有 EXPLAIN 關鍵字的情況下,將用來執行命令的虛擬機器指令順序。EXPLAIN 功能屬於進階功能,讓開發人員可以變更 SQL 陳述式文字,以嘗試最佳化效能,或針對似乎無法正常運作的陳述式進行除錯。 ON CONFLICT (衝突演算法)ON CONFLICT 子句不是單獨的 SQL 命令。它是可能出現在許多其它 SQL 命令中的非標準子句。 conflict-clause ::= ON CONFLICT conflict-algorithm conflict-clause ::= OR conflict-algorithm conflict-algorithm ::= ROLLBACK | ABORT | FAIL | IGNORE | REPLACE 第一種形式的 ON CONFLICT 子句會使用關鍵字 ON CONFLICT,並用在 CREATE TABLE 陳述式中。INSERT 或 UPDATE 陳述式使用第二種形式,並用 OR 取代 ON CONFLICT 使語法看起來比較自然。例如,陳述式不會是 INSERT ON CONFLICT IGNORE,而是 INSERT OR IGNORE。雖然關鍵字不同,但這兩種形式的子句有著相同的意思。 ON CONFLICT 子句會指定用來解析條件約束衝突的演算法。五個演算法分別為 ROLLBACK、ABORT、FAIL、IGNORE 和 REPLACE。預設演算法為 ABORT。五個衝突演算法的說明如下:
在 INSERT 或 UPDATE 陳述式的 OR 子句中指定的演算法,會覆寫 CREATE TABLE 陳述式中指定的任何演算法。如果 CREATE TABLE 陳述式或執行 INSERT 或 UPDATE 陳述式中沒有指定演算法,便會使用 ABORT 演算法。 REINDEXREINDEX 命令會用來刪除並重新建立一或多個索引。這個命令在定序順序的定義變更時很好用。 sql-statement ::= REINDEX collation-name sql-statement ::= REINDEX [database-name .] ( table-name | index-name ) 使用第一種形式時,使用具名定序順序的所有附加資料庫中的所有索引都會重新建立。使用第二種形式時,若指定 table-name,與該資料表相關的所有索引都會重建。如果提供 index-name,便只會刪除及重新建立指定的索引。 註解註解不是 SQL 命令,但可以出現在 SQL 查詢中。執行階段會把它們視為空白。可以使用空白的位置都可以開始註解,包括跨越數行的運算式內部。 comment ::= single-line-comment | block-comment single-line-comment ::= -- single-line block-comment ::= /* multiple-lines or block [*/] 單行註解會以兩個虛線表示。單行註解的範圍只到目前行結束處。 區塊註解可以跨越任何行數,或內嵌在單一行中。如果沒有終止分隔符號,區塊註解的範圍會延伸至輸入結束處。這種狀況不會被視為錯誤。新的 SQL 陳述式可以在區塊註解結束後的下一行開始。區塊註解可以內嵌在可出現空白的任何位置,包括運算式內部和其它 SQL 陳述式中間。區塊註解無法採用巢狀方式。區塊註解內部的單行註解會遭到忽略。 運算式運算式是其它 SQL 區塊中的子命令。SQL 陳述式中運算式的有效語法說明如下: expr ::= expr binary-op expr | expr [NOT] like-op expr [ESCAPE expr] | unary-op expr | ( expr ) | column-name | table-name.column-name | database-name.table-name.column-name | literal-value | parameter | function-name( expr-list | * ) | expr ISNULL | expr NOTNULL | expr [NOT] BETWEEN expr AND expr | expr [NOT] IN ( value-list ) | expr [NOT] IN ( select-statement ) | expr [NOT] IN [database-name.] table-name | [EXISTS] ( select-statement ) | CASE [expr] ( WHEN expr THEN expr )+ [ELSE expr] END | CAST ( expr AS type ) | expr COLLATE collation-name like-op ::= LIKE | GLOB binary-op ::= see Operators unary-op ::= see Operators parameter ::= :param-name | @param-name | ? value-list ::= literal-value [, literal-value]* literal-value ::= literal-string | literal-number | literal-boolean | literal-blob | literal-null literal-string ::= 'string value' literal-number ::= integer | number literal-boolean ::= true | false literal-blob ::= X'string of hexadecimal data' literal-null ::= NULL 運算式是值和運算子的任何組合,而且可解析成單一值。運算式一般可分為兩種類型,一種可解析成 Boolean (True 或 False) 值,一種可解析成非 Boolean 值。 在許多常見狀況中 (包括在 WHERE 子句、HAVING 子句、JOIN 子句中的 ON 運算式和 CHECK 運算式),運算式必須解析成 Boolean 值。符合這種狀況的運算式類型如下:
常值常值數值會寫成整數或浮點數,且支援科學記號。小數點固定使用 . (句點) 字元。 字串常值會以字串前後加上單引號 ' 表示。若要在字串中包含單引號,須依照範例連續使用兩個單引號:''。 Boolean 常值會以值 true 或 false 表示。常值 Boolean 值用於 Boolean 欄資料類型。 BLOB 常值是一種字串常值,它包含十六進位資料,前面加上一個 x 或 X 字元,例如 X'53514697465'。 常值也可以是字符 NULL。 欄名稱欄名稱可以是 CREATE TABLE 陳述式中定義的任何名稱,或下列特殊識別名稱:ROWID、OID 或 _ROWID_。這些特殊識別名稱全都描述與每個資料表中每個列相關的唯一隨機整數索引鍵 (「列索引鍵」)。這些特殊識別名稱只有在 CREATE TABLE 陳述式未定義同名的真實欄時才會參考到列索引鍵。列索引鍵的作用類似唯讀欄。凡是可以使用一般欄的位置都可以使用列索引鍵,唯一的例外是您無法在 UPDATE 或 INSERT 陳述式中變更列索引鍵的值。SELECT * FROM table 陳述式不會在結果集中包含列索引鍵。 SELECT 陳述式SELECT 陳述式可出現在運算式中,做為 IN 運算子右側的運算元、純量 (單一結果值) 或 EXISTS 運算子的運算元。做為純量或 IN 運算子的運算元使用時,SELECT 的結果中只能有一欄,但可以使用複合 SELECT 陳述式 (用 UNION 或 EXCEPT 關鍵字連接)。使用 EXISTS 運算子時,運算式會忽略 SELECT 的結果集中的欄,並在有一或多個欄存在時傳回 TRUE,在結果集空白時傳回 FALSE。如果 SELECT 運算式中沒有條件參考到包含查詢中的值,則運算式會在其它任何處理之前評估一次,並視需要重複使用該結果。如果 SELECT 運算式不包含外部查詢中的變數 (稱為相關子查詢),則每次需要時都會重新評估 SELECT。 當 SELECT 是 IN 運算子的右側運算元時,如果左側運算元的結果等於 SELECT 陳述式結果集中的任何值時,IN 運算子會傳回 TRUE。IN 運算子前面可以加上 NOT 關鍵字以反轉測試的意義。 當 SELECT 出現在運算式中,但不是 IN 運算子的右側運算元時,SELECT 結果中的第一列會成為運算式中使用的值。如果 SELECT 產生多個結果列,則會忽略第一列之後的所有列。如果 SELECT 產生零列,則 SELECT 的值是 NULL。 CAST 運算式CAST 運算式會將指定值的資料類型變更成指定的資料類型。指定的類型可以是任何非空白類型名稱,但必須是 CREATE TABLE 陳述式的欄定義中有效的類型。如需詳細資訊,請參閱「資料類型支援」。 額外的運算式元素下列 SQL 元素也可以用在運算式中:
內建函數內建函數分為三個主要類別:
除了這些函數之外,還有一個特殊函數 RAISE() 會用來在執行觸發程序時提供錯誤通知。這個函數只可以用在 CREATE TRIGGER 陳述式主體內。如需有關 RAISE() 函數的詳細資訊,請參閱「CREATE TRIGGER > RAISE()」。 就像 SQL 中的所有關鍵字一樣,函數名稱不區分大小寫。 彙總函數彙總函數會對多列的值執行作業。這些函數主要用在 SELECT 陳述式中搭配 GROUP BY 子句一起使用。
在上述使用單一引數的任何彙總函數中,該引數前都可以加上關鍵字 DISTINCT。在這種情況下,會先篩選掉重複項目,再傳給彙總函數。例如,函數呼叫 COUNT(DISTINCT x) 會傳回欄 X 中不同值的數目,而不是欄 x 中非 NULL 值的總數。 純量函數純量函數會一次處理一列的值。
日期和時間格式函數日期和時間格式函數是一組純量函數,用來建立格式化的日期和時間資料。請注意,這些函數會操作和傳回字串和數值。這些函數無法用於 DATE 資料類型。如果在宣告資料類型為 DATE 的欄資料上使用這些函數,函數將無法依預期方式運作。
時間格式時間字串可為下列格式中任一項:
字元 T 在這些格式中是分隔日期和時間的常值字元 "T"。只包含時間的格式會假設日期為 2001-01-01。 修飾詞時間字串後面可接著零或多個修飾詞,以改變日期或改變日期的解譯方式。可用修飾詞如下:
運算子SQL 支援大量運算子,包括大部分程式語言都提供的一般運算子,以及數個 SQL 專用的運算子。 一般運算子SQL 區塊中可使用下列二元運算子,清單中依其優先順序由高而低排列: * / % + - << >> & | < >= > >= = == != <> IN AND OR 支援的一元前置運算子包括: ! ~ NOT COLLATE 運算子可視為一元前置運算子。COLLATE 運算子的優先順序最高。它的繫結緊密程度一定高於其它任何前置一元運算子或任何二元運算子。 請注意,等於和不等於運算子有兩種變形。等於可以用 = 或 == 表示。不等於運算子可以用 != 或 <> 表示。 || 運算子是字串連接運算子,可將運算元的兩個字串接在一起。 運算子 % 會輸出其左側運算元除以右側運算元的餘數。 任何二元運算子的結果都是數值,只有 || 連接運算子例外,它的結果是字串。 SQL 運算子LIKE LIKE 運算子會執行樣式符合比較。 expr ::= (column-name | expr) LIKE pattern pattern ::= '[ string | % | _ ]' LIKE 運算子右側的運算元包含樣式,而左側的運算元則包含要符合樣式的字串。樣式中的百分比符號 (%) 是萬用字元,會符合字串中任何順序的零或多個字元。樣式中的底線 (_) 會符合字串中的任何單一字元。其它任何字元會符合其本身或大小寫的同一字元,也就是說,符合會以不區分大小寫的方式執行(注意:資料庫引擎只了解 7 位元拉丁字元的大小寫。因此,LIKE 運算子對 8 位元 iso8859 字元或 UTF-8 字元而言會區分大小寫。例如,運算式 'a' LIKE 'A' 為 TRUE,但 'æ' LIKE 'Æ' 則為 FALSE)。使用 SQLConnection.caseSensitiveLike 屬性可改變拉丁字元是否需要區分大小寫。 如果使用選擇性的 ESCAPE 子句,則 ESCAPE 關鍵字後面的運算式必須評估為包含單一字元的字串。這個字元可以用在 LIKE 樣式中,以符合百分比或底線字元常值。跳脫字元如果接在百分比符號、底線或其本身後面,就會分別符合字串中的百分比符號、底線或跳脫字元常值。 GLOB GLOB 運算子類似 LIKE,但使用 Unix 檔案萬用字元語法做為萬用字元。與 LIKE 不同的是,GLOB 會區分大小寫。 IN IN 運算子會計算其左側運算元是否等於其中一個右側運算元 (括在括弧中的一組數值)。 in-expr ::= expr [NOT] IN ( value-list ) | expr [NOT] IN ( select-statement ) | expr [NOT] IN [database-name.] table-name value-list ::= literal-value [, literal-value]* 右側運算元可以是一組以逗號分隔的常值,或是 SELECT 陳述式的結果。如需有關使用 SELECT 陳述式做為 IN 運算子之右側運算元的說明和限制,請參閱運算式中的 SELECT 陳述式。 BETWEEN...AND BETWEEN...AND 運算子相當於使用包含 >= 和 <= 運算子的兩個運算式。例如,運算式 x BETWEEN y AND z 相當於 x >= y AND x <= z。 NOT NOT 運算子是否定運算子。NOT 關鍵字可以放在 GLOB、LIKE 和 IN 運算子前面,以反轉測試的意義 (換句話說,即檢查值是否不符合指示的樣式)。 參數參數會指定運算式中常值的預留位置,之後再藉由為 SQLStatement.parameters 關聯陣列指定值,而於執行階段填入常值。參數有三種形式:
不支援的 SQL 功能以下清單列出 Adobe AIR 中不支援的標準 SQL 元素:
下列 SQL 元素和 SQLite 功能雖然在某些 SQLite 實作中受到支援,但在 Adobe AIR 中不受支援。當中的大部分功能都可以透過 SQLConnection 類別取得:
下列功能在許多 SQLite 實作與 Adobe AIR 中並不相同:
額外的 SQL 功能根據預設,下列欄相似性類型在 SQLite 中不受支援,但在 Adobe AIR 中則受到支援 (請注意,就像 SQL 中的所有關鍵字一樣,這些資料類型名稱不區分大小寫):
根據預設,下列常值在 SQLite 中不受支援,但在 Adobe AIR 中則受到支援:
|
|