Entity SQL 與 Transact-SQL 的差異處
本主題描述 Entity SQL 與 Transact-SQL 之間的差異。
繼承和關聯性支援
Entity SQL 直接搭配概念實體結構描述運作,且支援概念模型功能 (如繼承和關聯性)。
使用繼承時,從超型別執行個體的集合中選取子型別執行個體的作法通常會很實用。 Entity SQL 中的 oftype 運算子 (類似 C# Sequences 中的 oftype) 會提供這個功能。
集合的支援
Entity SQL 將集合視為第一級實體。 例如:
集合運算式在 from 子句中是有效的。
in 和 exists 子查詢已通用化,可允許任何集合。
子查詢是一種集合。
e1 in e2
和exists(e)
是用來執行這些作業的 Entity SQL 建構。Set 作業 (如 union、intersect 和 except) 現在都可針對集合來操作。
聯結可針對集合操作。
運算式的支援
Transact-SQL 具有子查詢 (資料表) 和運算式 (資料列和資料行)。
為了支援集合和巢狀集合,Entity SQL 會將所有項目變成運算式。Entity SQL 的可撰寫性高於 Transact-SQL ,任何地方都可以使用每一個運算式。 查詢運算式一定會產生投影的型別集合,而且可在允許集合運算式的任何地方使用。 如需 Entity SQL 中不支援之 Transact-SQL 運算式的資訊,請參閱不支援的運算式 (Entity SQL)。
下列全都是有效的 Entity SQL 查詢:
1+2 *3
"abc"
row(1 as a, 2 as b)
{ 1, 3, 5}
e1 union all e2
set(e1)
子查詢的統一處理
在資料表中強調時,Transact-SQL 會執行子查詢的內容解譯。 例如,from 子句中的子查詢會視為多重集 (資料表)。 但是 select 子句中使用的相同子查詢會視為純量子查詢。 同樣地,in 運算子左邊使用的子查詢會視為純量子查詢,而右邊的子查詢則必須是多重集子查詢。
Entity SQL 會消除這些差異。 運算式的統一解譯不依賴其使用所在的內容。Entity SQL 將所有子查詢都視為多重集子查詢。 如果想要子查詢中的純量值,Entity SQL 會提供一個可針對集合 (此案例中為子查詢) 運作的 anyelement 運算子,然後從集合中擷取單一值。
避免子查詢的隱含強制型轉
統一的子查詢處理有一個相關的副作用,就是會隱含地將子查詢轉換成純量值。 明確地說,Transact-SQL 中的資料列多重集 (具有單一欄位) 會隱含地轉換成一個純量值,這個值的資料型別是此欄位的資料型別。
Entity SQL 不支援這種隱含強制型轉。Entity SQL 提供了可從集合中擷取單一值的 ANYELEMENT 運算子,以及一個可在查詢運算式期間避免建立資料列包裝函式的 select value 子句。
Select Value:避免隱含資料列包裝函式
Transact-SQL 子查詢中的 select 子句會在子句的項目周圍建立資料列包裝函式。 這意味著,我們無法建立純量或物件的集合。Transact-SQL 允許在具有一個欄位的資料列型別與相同資料型別的單一值之間進行隱含的強制型轉。
Entity SQL 提供 select value 子句來略過隱含資料列建構。 select value 子句中只能指定一個項目。 使用這類子句時,將不會建構包含 select 子句中這個項目的資料列包裝函式,並且可以產生所需形狀的集合,例如:select value a
。
Entity SQL 也提供資料列建構函式來建構任意資料列。select 會擷取投影中的一個或多個項目,並且產生具有欄位的資料記錄,例如:
select a, b, c
左邊相互關聯與別名
在 Transact-SQL 中,給定範圍中的運算式 (類似 select 或 from 的單一子句) 無法參考之前在相同範圍中所定義的運算式。 SQL 的某些 Dialect (包括 Transact-SQL ) 確實支援 from 子句中受限形式的這些運算式。
Entity SQL 會將 from 子句中的左邊相互關聯通用化,並以統一的方式來處理。 from 子句中的運算式可參考相同子句中的先前定義 (左邊的定義),而不需要其他語法。
Entity SQL 也會針對與 group by 子句有關的查詢做出其他限制。 這類查詢之 select 子句和 having 子句中的運算式可能只會透過其別名參考 group by 索引鍵。 下列建構在 Transact-SQL 中是有效的,但是在 Entity SQL 中則無效:
select t.x + t.y from T as t group by t.x + t.y
若要在 Entity SQL 中進行這項處理:
select k from T as t group by (t.x + t.y) as k
參考資料表 (集合) 的資料行 (屬性)
Entity SQL 中的所有資料行參考都必須以資料表別名來限定。 下列建構 (假設 a
是資料表 T
的有效資料行) 在 Transact-SQL 中是有效的,但是在 Entity SQL 中無效。
select a from T
Entity SQL 格式如下:
select t.a as A from T as t
資料表別名在 from 子句中為選擇性。 資料表名稱會當做隱含別名使用。Entity SQL 也會顯示下列格式:
select Tab.a from Tab
導覽物件
Transact-SQL 會使用 "." 標記法來參考資料表 (之資料列) 的資料行。Entity SQL 會擴充這個標記法 (從程式語言借來) 來支援物件屬性的導覽。
例如,如果 p
是 Person 型別的運算式,下列是用來參考這個人之地址所在城市的 Entity SQL 語法。
p.Address.City
* 表示不支援
Transact-SQL 支援使用資格不符的 * 語法當做整個資料列的別名,而且支援使用符合資格的 * syntax (t.*) 當做該資料表之欄位的捷徑。 此外,Transact-SQL 也允許特殊 count(*) 彙總,其中包含 null。
Entity SQL 不支援 * 建構。select * from T
和 select T1.* from T1, T2...
格式的 Transact-SQL 查詢可以分別在 Entity SQL 中表示為 select value t from T as t
和 select value t1 from T1 as t1, T2 as t2...
。 此外,這些建構會處理繼承 (值的可替代性),而 select * Variant 則限制為宣告之型別的最上層屬性。
Entity SQL 不支援 count(*) 彙總, 請改用 count(0)。
變更成 Group By
Entity SQL 支援 group by 索引鍵的別名。 select 子句和 having 子句中的運算式必須透過這些別名參考 group by 索引鍵。 例如,這個 Entity SQL 語法:
select k1, count(t.a), sum(t.a)
from T as t
group by t.b + t.c as k1
...等於下列 Transact-SQL :
select b + c, count(*), sum(a)
from T
group by b + c
以集合為基礎的彙總
Entity SQL 支援兩種彙總。
以集合為基礎的彙總會針對集合運作,並產生彙總的結果。 這些可以出現在查詢中的任何地方,而且不需要 group by 子句。 例如:
select t.a as a, count({1,2,3}) as b from T as t
Entity SQL 也支援 SQL 樣式彙總。 例如:
select a, sum(t.b) from T as t group by t.a as a
ORDER BY 子句使用方式
Transact-SQL 允許只能在最上層 SELECT ..FROM .. WHERE 區塊中指定 ORDER BY 子句 。 在 Entity SQL 中,您可以使用巢狀 ORDER BY 運算式,並將它放在查詢內的任何地方,但是巢狀查詢中的排序並不會保留下來。
-- The following query will order the results by the last name
SELECT C1.FirstName, C1.LastName
FROM AdventureWorks.Contact as C1
ORDER BY C1.LastName
-- In the following query ordering of the nested query is ignored.
SELECT C2.FirstName, C2.LastName
FROM (SELECT C1.FirstName, C1.LastName
FROM AdventureWorks.Contact as C1
ORDER BY C1.LastName) as C2
識別項
在 Transact-SQL 中,識別項比較是以目前資料庫的定序 (Collation) 為基礎。 在 Entity SQL 中,識別項一律不會區分大小寫,但是會區分腔調字 (亦即 Entity SQL 會區別有腔調和無腔調字元。例如,'a' 不等於 'ấ')。Entity SQL 會將外觀相同但來自不同字碼頁的字母版本視為不同的字元。 如需詳細資訊,請參閱輸入字元集 (Entity SQL)。
Entity SQL 中無法使用 Transact-SQL 功能
下列 Transact-SQL 功能無法在 Entity SQL 中使用。
- DML
Entity SQL 目前不提供 DML 陳述式 (插入、更新、刪除) 的任何支援。
- DDL
Entity SQL 不提供目前版本中的任何 DDL 支援。
- 命令式程式設計
Entity SQL 不提供命令式程式設計的任何支援,與 Transact-SQL 不同。 請改用程式語言。
- 群組函式
Entity SQL 尚未提供群組函式 (如 CUBE、ROLLUP 和 GROUPING_SET) 的支援。
- 分析函式
Entity SQL 尚未提供分析函式的支援。
- 內建函式,運算子
Entity SQL 支援 Transact-SQL 之內建函式和運算子的子集。 這些運算子和函式可能會受到主要存放區提供者的支援。Entity SQL 會使用提供者資訊清單中宣告的存放區特有函式。 此外,Entity Framework 可讓您宣告內建及使用者定義的現有存放區函式,以供 Entity SQL 使用。
- 提示
Entity SQL 不提供查詢提示的機制。
- 批次處理查詢結果
Entity SQL 不支援批次處理查詢結果。 例如,下列是有效的 Transact-SQL (傳送做為批次):
select * from products;
select * from catagories;
但是,同等的 Entity SQL 未受到支援:
Select value p from Products as p;
Select value c from Categories as c;
Entity SQL 在每個命令中只支援一個產生結果的查詢陳述式。