Примеры. Пример 1. Удалить из таблицы department отдел с номером (deptno) ‘d11’

AND

Примеры

Пример 1. Удалить из таблицы DEPARTMENT отдел с номером (DeptNo) ‘D11’

DELETE FROM DEPARTMENT

WHERE DeptNo = ’D11’

Пример 2. Удалить из таблицы DEPARTMENT все строки (т.е. опустошить таблицу).

DELETE FROM DEPARTMENT

Пример 3. Удалить из таблицы EMPLOYEE сотрудников, выполняющих операции SALESREP или FIELDREP, кто не выполнял продажи в 1995 г.

DELETE FROM EMPLOYEE

WHERE Job IN (’SALESREP’,’FIELDREP’)

LastName NOT IN (SELECT Sales_Person

FROM SALES

WHERE YEAR (Sales_Date)=1995)

Предложение UPDATE

Предложение UPDATE позволяет изменить значения указанных колонок во всех или некоторых строках таблицы.

В общем случае предложение UPDATE имеет следующий вид:

UPDATE имя_таблицы SET имя_колонки = значение, … [ WHERE условие_поиска ]

имя_таблицы – должно указывать имя существующей таблицы базы данных.

Конструкция SET определяет, какие колонки таблицы и каким образом изменяют свои значения.

имя_колонки – указывает колонку, значение которой должно быть модифицировано. Имя одной и той же колонки в конструкции SET не должно повторяться.

значение – указывает новое значение колонки. Может быть представлено некоторым выражением или ключевыми словами NULL или DEFAULT и подчиняется тем же правилам, в соответствии с которыми задается новое значение в предложении INSERT. Кроме того, в выражении может быть использовано имя обновляемой колонки.

условие_поиска – условие, определяющее, какие строки должны быть модифицированы. Если конструкция WHERE опущена, модифицируются все строки таблицы.

В условии поиска в конструкции WHERE могут быть использованы только колонки таблицы, указанной в предложении UPDATE. Условие поиска применяется к каждой строке таблицы, и модифицируются те строки, для которых результатом условия поиска является значение true. Если условие поиска содержит подзапрос, можно считать, что подзапрос будет выполняться каждый раз, когда условие поиска применяется к строке, и результаты подзапроса используются в условии поиска. Если подзапрос ссылается на таблицу, указанную в этом же предложении UPDATE, подзапрос выполняется полностью прежде, чем будет обновлена хотя бы одна строка таблицы.

Если в предложении UPDATE модифицируются колонки таблицы, для которых определены некоторые ограничения целостности, все ограничения проверяются, и если хотя бы одно из них будет нарушено, соответствующая таблица изменена не будет, а предложение UPDATE завершится с ошибкой.

Пример 1. Изменить должность (JOB) сотрудника с номером (EMPNO) ‘000290’ в таблице EMPLOYEE на ‘LABORER’.

UPDATE EMPLOYEE

SET JOB = ’LABORER’

WHERE EMPNO = ’000290’

Пример 2. Увеличить значение колонки PRSTAFF (оценка средней обеспеченности проекта персоналом) в таблице PROJECT на 1.5 для всех проектов, за которые отвечает отдел (DEPTNO) с кодом ‘D21’.

UPDATE PROJECT

SET PRSTAFF = PRSTAFF + 1.5

WHERE DEPTNO = ’D21’

Пример 3. Для всех сотрудников, кроме менеджера отдела (WORKDEPT) ‘E21’, были сделаны временные переназначения. Необходимо отразить эту операцию, установив в таблице EMPLOYEE должность (JOB) соответствующих сотрудников в NULL и их оплату (SALARY, BONUS, COMM) в 0.

UPDATE EMPLOYEE

SET JOB= NULL, SALARY=0, BONUS=0, COMM=0

WHERE WORKDEPT = ’E21’ AND JOB <> ’MANAGER’

Это предложение может быть также записано следующим образом:

UPDATE EMPLOYEE

SET ( JOB, SALARY, BONUS, COMM ) = (NULL, 0, 0, 0 )

WHERE WORKDEPT = ’E21’ AND JOB <> ’MANAGER’

Конструкция VALUES

Конструкция VALUES представляет собой форму запроса, возвращающую некоторую таблицу.

В конструкции VALUES указываются одна или несколько строк, перечисляемых через запятую:

VALUES строка, …

Конструкция VALUES позволяет определить некоторую таблицу, явно задавая значения колонок и строк этой таблицы. Каждая строка конструкции VALUES задает одну строку таблицы и может быть представлена в виде одного выражения, определяющего таблицу, содержащую только одну колонку, или в виде списка выражений, перечисленных через запятую и заключенных в круглые скобки: (выражение, …), задающих многоколоночную таблицу. Если в конструкции VALUES указывается несколько строк, все строки должны иметь одинаковое количество колонок, и соответствующие значения каждой строки должны быть совместимыми.

Вместо выражения в многострочной конструкции VALUES может быть указано значение NULL, только если, по крайней мере, в одной строке в той же самой колонке указано не NULL значение.

Рассмотрим некоторые примеры.

VALUES (1), (2), (3) – определяет таблицу, содержащую 3 строки, состоящие из одной колонки.

VALUES 1, 2, 3 – эквивалентно предыдущему примеру: 3 строки из одной колонки.

VALUES (1, 2, 3) – определяет таблицу, содержащую одну строку из трех колонок.

VALUES (1, 21), (2, 22), (3, 23) – определяет таблицу, содержащую три строки из двух колонок.

Предложение SELECT

В общем случае, предложение SELECT состоит из семи конструкций и имеет следующий вид:

SELECT список_вывода

FROM источники

WHERE условие_отбора_строк

GROUP BY список_для_группирования

HAVING условие_отбора_групп

ORDER BY список_для_упорядочивания

FETCH FIRST ограничение_вывода

Предложение SELECT реализует запросы к базе данных, и поэтому его часто называют запросом. Внутри одного предложения SELECT могут использоваться другие предложения; такие вложенные предложения SELECT часто называют подзапросом. В дальнейшем мы будем использовать эти два термина.

В результате выполнения запроса, представленного предложением SELECT, формируется результирующая таблица, вид и состав которой определяются следующим образом:

• конструкция SELECT определяет совокупность колонок результирующей таблицы и их имена;

• конструкция FROM определяет, из каких таблиц объектов базы данных извлекаются данные в результирующую таблицу;

• конструкция WHERE определяет дополнительные условия, накладываемые на строки данных, которые должны войти в результирующую таблицу;

• конструкция GROUP BY позволяет сгруппировать строки по определенному признаку для последующей обработки; определяет некоторую совокупность групп, каждая из которых состоит из нескольких строк данных;

• конструкция HAVING позволяет из всех групп выбрать некоторые группы, удовлетворяющие дополнительным условиям;

• конструкция ORDER BY позволяет упорядочить строки результирующей таблицы;

• конструкция FETCH FIRST позволяет ограничить результирующую таблицу заданным количеством строк.

Все конструкции, кроме SELECT и FROM, являются не обязательными и могут быть опущены; если же все они или некоторые из них указываются, они должны быть записаны именно в таком порядке, в каком представлены в описании предложения SELECT.

Не вдаваясь в особенности работы СУБД, можно считать, что конструкции запроса обрабатываются последовательно, в некотором порядке; на каждом этапе формируется некоторая промежуточная результирующая таблица, которая используется в качестве исходной таблицы на следующем этапе. Порядок обработки запроса следующий:

1. FROM – выделяются таблицы и представления, из которых выбираются нужные данные.

2. WHERE – из выбранных таблиц выбираются строки, удовлетворяющие указанному условию отбора строк.

3. GROUP BY – выбранные строки объединяются в группы (группируются) по указанным признакам.

4. HAVING – из созданных групп выделяются группы, удовлетворяющие условию отбора групп.

5. SELECT – из выбранных групп в соответствии со списком вывода выделяются и обрабатываются необходимые данные, создавая строки и столбцы результирующей таблицы.

6. ORDER BY – полученные строки упорядочиваются по указанным столбцам.

7. FETCH FIRST – из полученных строк выбираются первые указанное количество строк.

Рассмотрим особенности задания каждой конструкции предложения SELECT.

Конструкция SELECT

Конструкция SELECT имеет следующий вид:

SELECT список_вывода

список вывода определяет колонки в результирующей таблице и представляет собой совокупность элементов, перечисленных через запятую, которым может предшествовать ключевое слово DISTINCT или ALL. Слово DISTINCT предписывает, в случае если в результирующей таблице встречаются повторяющиеся строки, выводить только одну (любую) строку из группы повторяющихся строк, тогда как слово ALL предписывает выводить все строки. Если ни одно из этих слов не указано, по умолчанию предполагается, что задано ALL.

Чаще всего в качестве элемента списка вывода используется имя колонки таблицы, указанной в конструкции FROM. Каждое имя колонки должно однозначно идентифицировать колонку таблицы. Если в запросе используются несколько таблиц, имеющих одинаковые имена колонок, и в списке вывода необходимо указать имя такой колонки, оно должно быть уточнено именем таблицы: имя_таблицы. имя_колонки – получается так называемое уточненное имя.

Если требуется получить все колонки таблицы, вместо перечисления имен колонок можно указать символ *. Если в запросе используются несколько таблиц, и из некоторой таблицы (или из всех таблиц) нужно получить все колонки, используется конструкция имя_таблицы. *.

В качестве элемента списка вывода может быть указана константа или выражение, которое строится в соответствии с правилами записи выражений, рассмотренными выше. В этих случаях соответствующая колонка результирующей таблицы оказывается безымянной. Чтобы определить имя колонки результирующей таблицы, или переименовать колонку результата, используется следующая конструкция:

элемент AS новое_имя

Новое имя задается в виде идентификатора – простого или с ограничителем.

Кроме того, в качестве элемента списка вывода может быть указан скалярный подзапрос – запрос, который возвращает только одну строку, возможно, содержащую несколько колонок. В этом случае элемент списка вывода задается следующим образом:

(запрос) AS имя_строки (имя_колонки, …)

Список имен колонок опускается, если запрос возвращает единственное значение.

Имена результирующих колонок формируются в соответствии со следующими правилами:

• если указана конструкция AS, именем результирующей колонки является имя, указанное в конструкции AS;

• если конструкция AS не указанна и результирующая колонка получается из колонки таблицы, тогда именем результирующей колонки является не уточненное имя колонки таблицы;

• в остальных случаях результирующая колонка будет безымянной. Таким колонкам система назначает временные номера (в виде символьных строк).

Рассмотрим некоторые примеры задания конструкции SELECT.

Предположим, что есть две таблицы – T1 и T2. Пусть в таблице T1 определены колонки T1_ID, TName, TNum, а в таблице T2 – колонки T2_ID, T1_ID и TName.

Тогда предложению SELECT * FROM T1 соответствует следующий заголовок результирующей таблицы:

T1_ID TNAME TNum

Предложению SELECT DISTINCT TNAME, TNUM FROM T1 соответствует следующий заголовок результирующей таблицы:

TNAME TNUM

Данное предложение SELECT реализует операцию проекции реляционной алгебры.

Предложению SELECT DISTINCT T1.TNAME, T2.TNAME FROM T1, T2 соответствует следующий заголовок результирующей таблицы:

TNAME TNAME

Предложению SELECT T1_ID, TNAME AS "Name for Table" FROM T1 соответствует следующий заголовок результирующей таблицы:

T1_ID Name for Table

Предложению SELECT T1_ID, TName, TNum + 100 FROM T1 соответствует следующий заголовок результирующей таблицы:

T1_ID TName  

Предложению SELECT T1.*, T2.* FROM T1, T2 соответствует следующий заголовок результирующей таблицы:

T1_ID TName TNum T2_ID T1_ID TName

Следующий пример предложения SELECT содержит ошибку:

SELECT T1_ID, T2_ID FROM T1, T2

Имя колонки T1_ID встречается и в T1, и в T2, поэтому имя T1_ID в списке вывода в заголовке

SELECT не однозначно.

Конструкция FROM

Конструкция FROM, в общем случае, может быть представлена следующим образом:

FROM элемент1, элемент2, …

Каждый элемент может быть представлен в виде ссылки на таблицу, соединения таблиц или вложенного табличного выражения.

Ссылка на таблицу имеет следующий вид:

имя_таблицы [[ AS ] корреляционное имя ]

Имя таблицы должно определять существующую таблицу базы данных.

Корреляционное имя, если оно используется, заменяет (в пределах данного предложения SELECT) непосредственно предшествующее ему имя таблицы. Если для таблицы указано корреляционное имя, именно оно должно использоваться при записи уточненного имени колонки такой таблицы. Если одна и та же таблица указывается в конструкции FROM дважды, по крайней мере, после одного указания должно следовать корреляционное имя.

Предложение SELECT T1.*, T2.* FROM T1, T2 реализует операцию декартова произведения.

Соединение таблиц записывается следующим образом:

элемент1 [ тип_соединения ] JOIN элемент2 ON условие_соединения

Здесь каждый элемент также может быть представлен в виде ссылки на таблицу, соединения таблиц или вложенного табличного выражения.

В качестве типа соединения может быть указано внутреннее (INNER) или внешнее (OUTER) соединение. Если тип соединения не указан, по умолчанию принимается внутреннее соединение.

Для внешнего соединения должен быть обязательно указан его вид: левое (LEFT), правое (RIGHT) или полное (FULL) внешнее соединение. При этом ключевое слово OUTER может быть опущено; так, указание LEFT JOIN эквивалентно LEFT OUTER JOIN.

Условие соединения записывается аналогично условию поиска, за следующими ограничениями:

• любая колонка, на которую ссылается выражение в условии соединения, должна быть колонкой одной из таблиц, указанных в соответствующей операции соединения;

• условие соединения не может содержать никаких подзапросов.

Соединение таблиц реализует соответствующую операцию соединения реляционной алгебры.

Рассмотрим примеры.

Пусть даны две таблицы – T1 и T2, имеющие следующее содержание:

T1 W X   T2 Y Z
  A       A  
  B       C  
  C       D  

Ниже приведены результаты всех операций соединения.

Внутреннее соединение – T1 INNER JOIN T2 ON W = Y

W X Y Z
A   A  
C   C  

Левое внешнее соединение – T1 LEFT OUTER JOIN T2 ON W=Y

W X Y Z
A   A  
B   - -
C   C  

Правое внешнее соединение –T1 RIGHT OUTER JOIN T2 ON W=Y

W X Y Z
A   A  
C   C  
- - D  

Полное внешнее соединение –T1 FULL OUTER JOIN T2 ON W=Y

W X Y Z
A   A  
C   C  
- - D  
B   - -

В соответствии с определением элементов, используемых в соединении таблиц, соединение может быть вложено в другое соединение. Несколько соединений обычно выполняются в порядке слева направо, основываясь на положении требуемого условия соединения. Для улучшения читабельности при использовании вложенных соединений рекомендуется использовать скобки. Например, конструкция:

TB1 LEFT JOIN TB2 ON TB1.C1=TB2.C1

RIGHT JOIN TB3 LEFT JOIN TB4 ON TB3.C1=TB4.C1

ON TB1.C1=TB3.C1

Эквивалентна следующей:

(TB1 LEFT JOIN TB2 ON TB1.C1=TB2.C1)

RIGHT JOIN (TB3 LEFT JOIN TB4 ON TB3.C1=TB4.C1)

ON TB1.C1=TB3.C1

Подзапрос, представленный предложением SELECT и заключенный в скобки, за которым следует корреляционное имя, называется вложенным табличным выражением. Подзапросу может предшествовать ключевое слово TABLE, и за подзапросом обязательно должно быть указано корреляционное имя:

[ TABLE ] (подзапрос) [ AS ] корреляционное_имя [(имя_колонки, …)]

В результате выполнения подзапроса, включенного во вложенное табличное выражение, получается некоторая результирующая таблица. Корреляционное имя, указанное после подзапроса, определяет имя этой результирующей таблицы; имена колонок определяются конструкцией SELECT подзапроса. Вместе с корреляционным именем могут быть указаны имена_колонок, определяющие имена колонок результирующей таблицы. На колонки вложенного табличного выражения можно ссылаться из любых мест запроса с помощью корреляционного имени. В общем случае, вложенное табличное выражение может быть указано в любой конструкции FROM.

Пример записи вложенного табличного выражения:

SELECT T1.A, T2.B FROM T1, (SELECTFROM TT) AS T2(B …) …

Во вложенном табличном выражении могут быть использованы уточненные имена, ссылающиеся на таблицу, использованную в основном запросе; в этом случае вложенному табличному выражению должно обязательно предшествовать ключевое слово TABLE.

Рассмотрим пример. В запросе используются таблица Dept, имеющая колонки DeptNo и DeptName, и вложенное табличное выражение, в котором используется таблица Emp, имеющая числовую колонку Sal и колонку DeptNo; в табличном выражении необходимо реализовать ссылку на колонку DeptNo из таблицы Dept. Ниже приведен корректный пример такого запроса:

SELECT D.DeptNo, D.DeptName, E1.avgsal, E1.empcount

FROM Dept D,

TABLE (SELECT AVG(E.Sal) AS avgsal,

COUNT(*) AS empcount

FROM Emp E

WHERE E.DeptNo=D.DeptNo

) AS E1;

Если ключевое слово TABLE в таком запросе будет опущено, во вложенном табличном выражении ссылка D.DeptNo будет не определена.

Конструкция WHERE

Конструкция WHERE задает условие отбора строк и имеет следующий вид:

WHERE условие_поиска

В результате обработки данной конструкции будут получены строки, для которых указанное условие_поиска истинно.

Условие поиска записывается в соответствии с правилами, рассмотренными выше, с учетом следующих ограничений:

• в условии поиска каждое используемое имя колонки или уточненное имя должно уникально идентифицировать колонку исходной таблицы или вложенного табличного выражения, указанных в конструкции FROM;

• в условии поиска конструкции WHERE не могут быть использованы агрегатные функции.

Конструкция GROUP BY

Конструкция GROUP BY имеет следующий вид:

GROUP BY элемент [, элемент …]

Конструкция GROUP BY включается в предложение SELECT в тех случаях, когда в список вывода конструкции SELECT включаются, в том числе, и выражения, содержащие агрегатные функции.

Элемент конструкции GROUP BY представляется в виде некоторого выражения группирования, содержащего имена колонок и используемого для определения группы строк. Каждое имя колонки, включенное в выражение группирования, должно однозначно идентифицировать колонку исходной таблицы.

Каждому выражению списка вывода, не содержащему агрегатную функцию, должно соответствовать выражение группирования. В простейшем случае выражение группирования представляется именем одной колонки. Выражение группирования не может включать скалярный запрос. Чтобы выполнять группирование с использованием таких выражений, используются вложенные табличные выражения.

Результатом выполнения операции GROUP BY является множество групп строк. Каждая группа состоит из множества строк, имеющих одно и то же значение выражения группирования. При выполнении группирования все значения NULL из выражения группирования считаются равными.

Конструкция HAVING

Конструкция HAVING имеет следующий вид:

HAVING условие_поиска

Конструкция HAVING определяет промежуточную таблицу результатов, которая состоит из групп, полученных на предыдущих этапах вычисления SELECT, для которых условие поиска истинно.

В условии поиска конструкции HAVING допускается использование имен колонок, однозначно идентифицирующих каждую группу исходной таблицы, и агрегатных функций, применяемых к полученным группам.

Допускается использование конструкции HAVING без конструкции GROUP BY; в этом случае считается, что в операции HAVING участвует только одна группа, и в списке вывода в конструкции SELECT могут быть указаны только агрегатные функции, константы и/или специальные регистры.

Конструкция ORDER BY

Конструкция ORDER BY имеет следующий синтаксис:

ORDER BY ключ_сортировки [ направление_сортировки ], …

В качестве ключа_сортировки могут быть указаны простое имя колонки или простое целое. Простое имя колонки определяет именованную колонку из списка вывода конструкции SELECT. Простое целое задает порядковый номер колонки результирующей таблицы, начиная с 1.

В качестве направления сортировки может быть указано ключевое слово ASC или DESC. Значение ASC предписывает выполнять сортировку в возрастающем порядке, DESC – в убывающем порядке. Если направление сортировки не указано, по умолчанию принимается ASC.

Конструкция ORDER BY определяет упорядочение строк результирующей таблицы. Если указана только одна спецификация сортировки (ключ сортировкис соответствующим направлением), строки упорядочиваются по значениям указанной спецификации. Если указано несколько спецификаций сортировки, строки упорядочиваются сначала по значениям первой спецификации, затем по значениям второй, и т.д.

Упорядочение выполняется в соответствии с правилами сравнения. Значение NULL считается большим, чем любое другое значение. Если конструкция ORDER BY не может полностью упорядочить строки, строки с одинаковыми значениями всех указанных в ключах сортировки колонок выводятся в произвольном порядке.

Конструкция FETCH FIRST

Конструкция FETCH FIRST имеет следующий вид:

FETCH FIRST [ целое ] ROW [ S ] ONLY

Конструкция FETCH FIRST устанавливает максимальное количество строк, которые должны быть получены. Она сообщает менеджеру базы данных, что приложение не хочет получить более чем целое строк, независимо от того, сколько строк может быть получено в результирующей таблице, если эта конструкция не указывается. Попытка получить больше, чем целое, строк обрабатывается так же, как и обычный конец данных. Значение целого должно быть строго положительным (нуль не допускается).

Использование теоретико-множественных операций

При написании запросов к базе данных, наряду с рассмотренными выше возможностями, могут быть использованы теоретико-множественные операции объединения, вычитания и пересечения. Запросы, использующие теоретико-множественные операции, будем в дальнейшем называть запросами, а запросы без теоретико-множественных операций – подзапросами.

Запрос является компонентом некоторых предикатов, которые, в свою очередь, являются компонентами других предложений SQL. Запрос, являющийся компонентом предиката, также называют подзапросом.

Запрос имеет следующий вид:

операнд [ операция операнд …] [ конструкция ORDER BY] [ конструкция FETCH FIRST]

В качестве операнда может быть использован подзапрос, запрос, заключенный в круглые скобки – (запрос), и конструкция VALUES.

В качестве операций используются:

UNION или UNION ALL – для операции объединения,

EXCEPT или EXCEPT ALL – для операции вычитания,

INTERSECT или INTERSECT ALL – для операции пересечения.

Указанные операции реализуют соответствующие теоретико-множественные операции реляционной алгебры. Ключевое слово ALL для каждой операции указывает, что в результат должны быть включены все строки, независимо от того, встречаются дубликаты среди строк или нет. Если ключевое слово ALL не указано, из результатов, в соответствии с определением теоретико-множественных операций, удаляются все дубликаты. Две строки считаются дубликатами, если каждое значение первой строки равно соответствующему значению второй. При анализе дубликатов два значения NULL считаются равными.

Количество колонок в таблицах R1 и R2, соответствующих каждому операнду в записи запроса, должно быть одинаковым. Имена колонок в результирующей таблице определяются следующим образом:

• если n -я колонка R1 и n -я колонка R2 имеют одно и то же имя, тогда n -я колонка результата получает это же имя;

• если n -я колонка R1 и n -я колонка R2 имеют разные имена, имя результирующей таблицы генерируется системой; такое имя не может быть использовано в конструкции ORDER BY.

Конструкции ORDER BY и FETCH FIRST имеют такой же смысл, что и соответствующие конструкции, рассмотренные выше.

Если в записи полного запроса используется несколько теоретико-множественных операций, они выполняются в порядке слева направо, причем операция INTERSECT имеет более высокий приоритет, чем операции UNION и EXCEPTION (эти операции имеют одинаковый приоритет). Скобки могут изменить порядок вычисления операций.

В таблице 4.13 приведены результаты вычисления выражений R1 операция R2 для всех теоретико-множественных операций.

Таблица 4.13. Результаты вычисления теоретико-множественных операций

R1 R2 UNION ALL UNION EXCEPT ALL EXCEPT INTERSECT ALL INTERSECT
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               

Создание представлений – CREATE VIEW

Предложение CREATE VIEW создает представления на основе одной или нескольких таблиц и/или других представлений.

Предложение CREATE VIEW имеет следующий вид:

CREATE VIEW имя_представления [(имя_колонки, …)] AS запрос

имя_представления – именует представление. Имя не должно совпадать с именами существующих в базе данных таблиц и представлений.

имя_колонки – именует колонку представления. Если указывается список имен колонок, он должен содержать столько имен, сколько колонок определено в результирующей таблице запроса. Каждое имя_колонки должно быть уникальным и не уточненным. Если список имен колонок не указан, колонки представления наследуют имена колонок результирующей таблицы запроса. Список имен колонок должен быть указан, если результирующая таблица запроса имеет несколько колонок с одинаковыми именами или неименованные колонки.

AS – указывает начало определения представления.

запрос – определяет представление. В любой момент времени представление содержит строки, получающиеся в результате выполнения предложения SELECT. Запрос не может содержать в конструкции FROM предложения, изменяющие данные.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: