Отличия Entity SQL и Transact-SQL

Tsql теория > Отличия Entity SQL и Transact-SQL
20.10.2017 15:58:32



Статья:

Язык Entity SQL работает непосредственно с концептуальными схемами сущности и поддерживает такие функции концептуальных моделей, как наследование и связи.

При работе с наследованием часто полезно выбрать экземпляры подтипа из коллекции экземпляров супертипа. Эту возможность предоставляет оператор oftype языка Entity SQL (аналогичный oftype в C# Sequences).

В языке Entity SQL коллекции рассматриваются как сущности первого класса. Например:

  • Выражения коллекций допускаются в предложении from.

  • Вложенные запросы in и exists были обобщены, чтобы разрешить любые коллекции.

    Вложенный запрос - один из видов коллекций. e1 in e2 и exists(e) - конструкции языка Entity SQL для выполнения этих операций.

  • Операторы работы с наборами, такие как union, intersect и except, теперь работают с коллекциями.

  • Операции соединения с коллекциями.

В языке Transact-SQL существуют вложенные запросы (таблицы) и выражения (строки и столбцы).

В целях поддержки коллекций и вложенных коллекций все элементы языка Entity SQL являются выражениями. Код Entity SQL является более легко компонуемым по сравнению с кодом Transact-SQL - любое выражение может использоваться в любом месте. Результатом выражения запроса всегда является коллекция проецируемых типов, которая может быть использована везде, где разрешено выражение коллекции. Сведения о выражениях Transact-SQL, которые не поддерживаются в языке Entity 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 во вложенном запросе Transact-SQL неявно создает оболочку строк вокруг элементов в предложении. Это означает, что нельзя создавать коллекции скалярных величин или объектов. Язык Transact-SQL обеспечивает неявное приведение между типом строки с одним полем и одноэлементным значением того же типа данных.

Язык Entity SQL предоставляет предложение select value, чтобы пропустить неявное построение строки. В предложении select valueможно указать только один элемент. При использовании такого предложения не создается оболочка строк вокруг элементов в предложении select, что позволяет получить коллекцию необходимой формы, например: select value a.

Язык Entity SQL поддерживает также конструктор строк, позволяющий создавать произвольные строки. Предложение select принимает один или несколько элементов в проекции и возвращает результаты в записи данных с полями, следующим образом:

select a, b, c

В языке Transact-SQL выражения в данной области (отдельное предложение, такое как select или from) не могут ссылаться на выражения, определенные ранее в той же области. Некоторые диалекты 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 поддерживает использование синтаксиса * в качестве псевдонима для всей строки и уточненного синтаксиса * (t.*) в качестве шаблона для ее полей. Кроме того, в Transact-SQL разрешается специальное статистическое выражение count(*), включающее значения NULL.

Язык Entity SQL не поддерживает конструкцию «*». Запросы Transact-SQL в форме select * from T и select T1.* from T1, T2...могут быть выражены в языке Entity SQL как select value t from T as t и select value t1 from T1 as t1, T2 as t2..., соответственно. Эти конструкции также обеспечивают наследование (заменяемость значений), в то время как варианты select *ограничены свойствами верхнего уровня объявленного типа.

Язык Entity SQL не поддерживает статистическую функцию count(*). Взамен рекомендуется использовать count(0).

Язык 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

В языке Transact-SQL предложения ORDER BY могут быть указаны только в самом верхнем блоке инструкции SELECT .. FROM .. WHERE. В языке 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 сравнение идентификаторов всегда осуществляется с учетом параметров сортировки текущей базы данных. В Entity SQL идентификаторы всегда чувствительны к регистру и диакритическим знакам (то есть Entity SQL различает диакритические знаки, например «а» отличается от «?»). Entity SQL обрабатывает версии букв, которые кажутся такими же, но являются другими символами и происходят из других кодовых страниц. Для получения дополнительной информации см. Набор символов ввода (Entity 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 поддерживает только запросы, которые выдают один результат на одну команду.