Share via


Entity SQL 與 Transact-SQL 的相異之處

本文說明 Entity SQL 與 Transact-SQL 之間的差異。

繼承和關聯性支援

Entity SQL 直接搭配概念實體結構描述運作,且支援概念模型功能 (如繼承和關聯性)。

當使用繼承時,從超型別執行個體的集合中選取子型別執行個體的作法通常會很實用。 Entity SQL 中的 oftype 運算子 (類似 C# Sequences 中的 oftype) 會提供這個功能。

集合的支援

Entity SQL 將集合視為第一級實體。 例如:

  • 集合運算式在 from 子句中是有效的。

  • inexists 子查詢已通用化,可允許任何集合。

    子查詢是一種集合。 e1 in e2exists(e) 是用來執行這些作業的 Entity SQL 建構。

  • Set 作業 (如 unionintersectexcept) 現在都可針對集合來操作。

  • 聯結可針對集合操作。

運算式的支援

Transact-SQL 具有子查詢 (資料表) 和運算式 (資料列和資料行)。

為了支援集合和巢狀集合,Entity SQL 將所有東西變成運算式。 與 Transact-SQL 相比,Entity SQL 更容易撰寫,每一個運算式都可在任何地方使用。 查詢運算式一定會產生投影的型別集合,而且可在允許集合運算式的任何地方使用。 如需 Entity SQL 中不支援的 Transact-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 運算子,然後從集合中擷取 singleton 值。

避免子查詢的隱含強制型轉

統一的子查詢處理有一個相關的副作用,就是會隱含地將子查詢轉換成純量值。 明確地說,Transact-SQL 中的資料列多重集 (具有單一欄位) 會隱含地轉換成一個純量值,這個值的資料型別是此欄位的資料型別。

Entity SQL 不支援這種隱含強制型轉。 Entity SQL 提供了可從集合中擷取 singleton 值的 ANYELEMENT 運算子,以及一個可在查詢運算式期間避免建立資料列包裝函式的 select value 子句。

Select Value:避免隱含資料列包裝函式

Transact-SQL 子查詢中的 select 子句會在子句的項目周圍建立資料列包裝函式。 這意味我們無法建立純量或物件的集合。 Transact-SQL 允許在具有一個欄位的 rowtype 與相同資料類型的 singleton 值之間進行隱含強制型轉。

Entity SQL 提供 select value 子句來略過隱含資料列建構。 select value 子句中只能指定一個項目。 使用這類子句時,將不會建構包含 select 子句中這個項目的資料列包裝函式,並且可以產生所需形狀的集合,例如:select value a

Entity SQL 也提供資料列建構函式來建構任意資料列。 select 會擷取投影中的一個或多個元素,並產生具有欄位的資料記錄:

select a, b, c

左邊相互關聯與別名

在 Transact-SQL 中,給定範圍中的運算式 (類似 selectfrom 的單一子句) 無法參考之前在相同範圍中所定義的運算式。 SQL 的某些方言 (包括 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 Tselect T1.* from T1, T2... 格式的 Transact-SQL 查詢可以分別在 Entity SQL 中表示為 select value t from T as tselect 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  

Identifiers

在 Transact-SQL 中,識別項比較是以目前資料庫的定序為基礎。 在 Entity SQL 中,識別項一律不會區分大小寫,但是會區分腔調字 (Accent Sensitive) (亦即,Entity SQL 會區別有腔調和無腔調字元。例如,'a' 不等於 'ấ')。 Entity SQL 會將看起來一樣卻來自不同字碼頁的字母版本視為不同字元。 如需詳細資訊,請參閱字元集 (機器翻譯)

Entity SQL 中無法使用 Transact-SQL 功能

Entity SQL 中無法使用下列 Transact-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 categories;

但是,不支援同等的 Entity SQL:

SELECT value p FROM Products AS p;
SELECT value c FROM Categories AS c;

Entity SQL 在每個命令中只支援一個產生結果的查詢陳述式。

另請參閱