МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ
____________________________
Кафедра ____________________________
РЕФЕРАТ
на тему: «Синтаксис операторов DML в стандарте SQL:1999»
Выполнил(а): ____________________________
Группа: ____________________________
Проверил(а): ____________________________
2026
Содержание
- 3
- 6
- 8
- 10
1. Эволюция стандарта SQL и место DML
История стандартизации SQL началась задолго до версии 1999 года. Первый официальный стандарт, принятый ANSI в 1986 году и дополненный ISO в 1987-м, зафиксировал базовый синтаксис языка, который к тому моменту уже активно использовался в коммерческих СУБД. Однако этот документ оставлял множество пробелов. Он не определял поведение при работе с внешними соединениями, не описывал механизмы управления доступом и оставлял разработчикам свободу в реализации даже таких базовых операций, как изменение структуры таблицы. К началу 1990-х стало очевидно: рынок требует более строгой спецификации, способной обеспечить переносимость приложений между разными системами.
Ответом стал стандарт SQL:1992 (часто называемый SQL2). Он существенно расширил язык: добавил поддержку целостности данных на уровне декларативных ограничений, ввел типы данных DATE и TIME, уточнил семантику транзакций. Именно эта версия легла в основу большинства современных промышленных СУБД. Но и она не была лишена недостатков. Объектно-реляционное расширение, над которым работали группы специалистов в ISO и ANSI, требовало более радикального пересмотра структуры стандарта. Работа над новой редакцией заняла почти семь лет, и результатом стал объемный документ, опубликованный в 1999 году.
SQL:1999 разделен на несколько частей, и это организационное новшество стало важным шагом. Вместо единого монолитного текста стандарт получил модульную структуру: отдельно описывались базовые механизмы (часть 2, Foundation), процедурные расширения (часть 4, SQL/PSM), управление внешними данными (SQL/MED) и другие компоненты. Такой подход позволил разработчикам внедрять поддержку стандарта поэтапно. Главным содержательным нововведением стало введение рекурсивных запросов, триггеров и механизма MERGE, который объединял операции вставки и обновления в один оператор.
В контексте этого стандарта принято выделять несколько подъязыков, каждый из которых отвечает за свой класс задач. DML, или Data Manipulation Language, занимает среди них особое место. Он охватывает четыре основных оператора: SELECT, INSERT, UPDATE и DELETE. В отличие от DDL (Data Definition Language), который управляет схемой базы данных, или DCL (Data Control Language), отвечающего за права доступа, DML работает непосредственно с данными. Если DDL создает таблицу, а DCL разрешает пользователю к ней обращаться, то именно DML наполняет таблицу строками, изменяет их и извлекает по запросу. TCL (Transaction Control Language) лишь управляет границами транзакций, внутри которых выполняются операторы DML.
Разделение на подъязыки носит скорее концептуальный, нежели строго формальный характер. В тексте стандарта нет четких секций с заголовками DML или DDL. Тем не менее такая классификация удобна для изучения и практического применения. Она позволяет отделить вопросы проектирования структуры данных от вопросов манипулирования этими данными, что критически важно при разработке приложений.
Главное отличие SQL:1999 от предшественников в части DML заключается не в появлении принципиально новых операторов (их синтаксис в целом сохранился), а в уточнении их поведения в сложных сценариях. Стандарт детально описал, как должны обрабатываться операции с NULL-значениями при соединении таблиц, как ведут себя обновления при наличии триггеров и какова семантика оператора MERGE. Была также уточнена работа с подзапросами в предложении FROM, что открыло путь к более гибкому конструированию выборок.
Дональд Чемберлин, один из создателей языка SQL, неоднократно подчеркивал, что сила языка в его декларативности: пользователь описывает, какие данные нужны, а не как их получить. Стандарт 1999 года сохранил этот принцип, но добавил к нему процедурные
элементы. Это сделало DML более выразительным инструментом, способным решать задачи, которые раньше требовали написания сложных хранимых процедур на отдельных языках. Именно поэтому SQL:1999 считается поворотным моментом: он завершил эпоху простых реляционных запросов и открыл период, когда SQL стал полноценным языком программирования для работы с данными, сохранив при этом свою основную направленность на манипулирование данными.
2. Операторы модификации данных: INSERT, UPDATE, DELETE
Операторы модификации данных в стандарте SQL:1999 образуют минимальный, но достаточный набор средств для управления содержимым таблиц. INSERT, UPDATE и DELETE покрывают три базовые операции: добавление, изменение и удаление строк. Их синтаксис в этом стандарте стал более строгим по сравнению с ранними версиями, но сохранил простоту восприятия.
Оператор INSERT добавляет в таблицу новую строку. В наиболее распространённой форме он использует конструкцию `INSERT INTO table_name (column1, column2,...) VALUES (value1, value2,...)`. Явное перечисление столбцов необязательно: если его опустить, значения должны быть указаны для всех столбцов таблицы в порядке их определения. Стандарт также допускает вставку сразу нескольких строк через список конструкций VALUES, разделённых запятыми. Отдельного упоминания заслуживает форма `INSERT INTO table_name DEFAULT VALUES`, которая вставляет строку со значениями по умолчанию для всех столбцов. Эта возможность была формализована именно в SQL:1999, хотя ранее она существовала в некоторых проприетарных реализациях.
Оператор UPDATE предназначен для изменения данных в уже существующих строках. Его синтаксис выглядит как `UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition`. Предложение SET может содержать сразу несколько присваиваний, причём вычисление всех выражений в правой части происходит до начала модификации. Это важно для случая, когда нужно поменять значения столбцов местами, например, `SET a = b, b = a`. Ключевым элементом является условие WHERE. Если оно опущено, операция применяется ко всем строкам таблицы. Стандарт SQL:1999 позволяет в правой части присваивания использовать и подзапрос, но это уже относится к теме подзапросов в DML, которая в данной главе не
рассматривается.
Оператор DELETE удаляет строки из таблицы. Его синтаксис лаконичен: `DELETE FROM table_name WHERE condition`. Предложение WHERE здесь играет ту же роль, что и в UPDATE: оно ограничивает множество удаляемых строк. Отсутствие WHERE приводит к полной очистке таблицы. Стоит подчеркнуть, что в SQL:1999 DELETE не поддерживает предложение ORDER BY и LIMIT, в отличие от некоторых поздних расширений в других стандартах. Для удаления всех строк без исключения рекомендуется использовать отдельную конструкцию, но формально `DELETE FROM table_name` без WHERE остаётся корректной.
В SQL:1999 появился оператор MERGE, который объединяет логику INSERT, UPDATE и DELETE в одной команде. Однако его синтаксис достаточно сложен и включает дополнительные конструкции, поэтому он выходит за рамки этой главы. Базовые операторы модификации остаются фундаментом для любых операций с данными, и именно их синтаксис требуется знать наизусть для работы с любой современной СУБД. Понимание точных правил для INSERT, UPDATE и DELETE из стандарта 1999 года помогает избежать ошибок при переносе кода между разными системами управления базами данных.
3. Оператор SELECT: структура и ключевые конструкции
Перейдя от операторов, изменяющих состояние таблиц, к операции чтения, мы упираемся в центральный элемент DML. SELECT в стандарте SQL:1999, это сложная конструкция, грамматика которой описывает целый конвейер обработки данных. Синтаксис построен вокруг одного обязательного элемента: списка выбираемых столбцов. Всё остальное, включая определение источников, фильтрацию и сортировку, подключается по мере необходимости.
Базовое ядро запроса выглядит просто. Например, `SELECT name FROM employees;` вернет все значения из колонки name. Но такая простота обманчива. Полная структура предложения включает пять необязательных блоков, которые выполняются в строго определенном порядке. Сначала отрабатывает FROM, затем WHERE, потом GROUP BY, следом HAVING, и только в конце ORDER BY. Понимание этой последовательности избавляет от массы логических ошибок, когда программист пытается использовать алиас из SELECT в предложении WHERE, что запрещено, поскольку WHERE вычисляется раньше.
Предложение FROM отвечает за формирование рабочего набора строк. Именно здесь определяются источники данных. В SQL:1999 это не просто перечисление таблиц через запятую, как в ранних версиях, а полноценный механизм соединений. Ключевая конструкция, JOIN, явно задает способ связывания строк. Стандарт различает INNER JOIN, возвращающий только совпадающие пары, и LEFT OUTER JOIN, который сохраняет все строки левой таблицы, дополняя их данными из правой, либо значениями NULL при отсутствии совпадений. Это было принципиальное новшество: раньше соединения задавались неявно через условие в WHERE, что часто приводило к ошибкам при построении сложных запросов.
Когда данные собраны, в дело вступает WHERE. Этот блок выполняет фильтрацию строк еще до каких-либо группировок. Он работает с конкретными значениями полей, отбрасывая неподходящие записи. Если требуется
агрегация, например подсчет сумм или средних значений по категориям, то используется GROUP BY. Это предложение делит результирующий набор на группы по значениям указанных столбцов. После группировки все вычисления, такие как `SUM(amount)` или `COUNT(*)`, применяются уже к каждой группе отдельно. Важный нюанс: фильтровать группы нельзя через WHERE, так как к этому моменту строки уже агрегированы. Для этого существует отдельное предложение HAVING. Оно применяется после группировки и работает с результатами агрегатных функций. Таким образом, `HAVING SUM(amount) > 1000` отсеет группы, чья суммарная выручка не дотянула до порога.
Завершает конструкцию ORDER BY, который определяет порядок вывода результирующего набора. Сортировка может идти по одному или нескольким столбцам, по возрастанию (ASC) или убыванию (DESC). Стандарт также допускает сортировку по позиции столбца в списке SELECT, например `ORDER BY 2`, что означает сортировку по второму выбранному полю. Примечательно, что ORDER BY выполняется в самом конце, уже после того как сформирован окончательный набор строк, поэтому он не влияет на логику группировки или фильтрации.
Отдельно стоит оговориться о так называемых оконных функциях. Они действительно появились в спецификации SQL:1999, но их синтаксис вынесен за рамки базовой структуры SELECT. Работа с ними требует дополнительного предложения OVER, которое не входит в перечень основных блоков, таких как WHERE или GROUP BY. По сути, это отдельная подсистема, предназначенная для вычислений в рамках определенного окна строк, и она не является обязательной для понимания классического синтаксиса выборки. Базовый SELECT остается самодостаточным инструментом, позволяющим решать подавляющее большинство задач по извлечению и первичной обработке данных без обращения к этим расширенным возможностям.
4. Особенности реализации и практические примеры
Разобравшись с синтаксисом операторов модификации и выборки, стоит перейти к тому, как эти конструкции работают в реальных системах. Синтаксис DML из стандарта SQL:1999 стал тем фундаментом, на котором строятся практически все современные СУБД. Однако буквальное следование стандарту встречается редко. Каждый крупный вендор (Oracle, Microsoft, PostgreSQL) реализует спецификацию с оговорками и расширениями. Различия касаются не только диалекта функций, но и трактовки базовых операторов.
Практический пример с INSERT хорошо демонстрирует эту вариативность. Стандартная конструкция с явным перечислением столбцов работает везде: `INSERT INTO employees (name, department, salary) VALUES ('Анна', 'IT', 85000)`. Но уже в следующей строке начинаются расхождения. В SQL Server для вставки нескольких строк используется `INSERT INTO... VALUES (...), (...), (...)`, тогда как Oracle до недавнего времени требовал `INSERT ALL INTO... SELECT... FROM dual`. Такая, казалось бы, мелочь, как добавление нескольких записей, заставляет разработчика помнить о конкретной платформе.
Оператор UPDATE в стандарте выглядит лаконично: `UPDATE employees SET salary = salary * 1.1 WHERE department = 'IT'`. Здесь скрывается важный нюанс: стандарт определяет, что обновление происходит по принципу "все или ничего" в рамках одной транзакции. Если во время выполнения команды возникает ошибка, вся операция откатывается. Это свойство напрямую связано с целостностью данных. Представьте банковскую систему, где списание средств и зачисление на другой счет происходят двумя разными UPDATE. Без транзакционной обертки сбой между этими операторами привел бы к потере денег.
Удаление строк также регулируется строгими правилами. `DELETE FROM employees WHERE id = 10` удалит запись, но если на эту строку ссылается
внешний ключ из другой таблицы, СУБД либо запретит операцию, либо запустит каскадное удаление, в зависимости от ограничений, заданных при создании схемы. Стандарт SQL:1999 четко описывает поведение для таких случаев, но выбор действия (RESTRICT или CASCADE) остается за разработчиком базы данных. Это еще один пример того, как стандарт задает рамки, но не диктует единственный сценарий.
Наиболее показателен в этом смысле SELECT. Простой запрос `SELECT name, salary FROM employees WHERE salary > 50000` работает одинаково во всех СУБД. Но как только появляется необходимость ограничить количество возвращаемых строк, начинается хаос. Стандарт SQL:1999 не определил синтаксис для этой операции. В результате в MySQL появился `LIMIT 10`, в SQL Server и PostgreSQL `TOP 10` и `FETCH FIRST 10 ROWS ONLY` соответственно, а в Oracle `ROWNUM` и более поздний `FETCH`. Программисту приходится держать в голове три разных синтаксиса для одной и той же задачи, что напрямую влияет на переносимость кода между системами.
Транзакционная модель, заложенная в стандарте, остается главным инструментом поддержания согласованности. Операторы DML, заключенные между BEGIN и COMMIT, гарантируют, что либо все изменения будут применены, либо ни одно. Уровни изоляции, описанные в SQL:1999, определяют, как транзакции видят изменения друг друга. Если одна транзакция обновляет строку, а другая пытается ее прочитать, результат зависит от уровня изоляции. Стандарт предлагает четыре уровня: от READ UNCOMMITTED, допускающего чтение "грязных" данных, до SERIALIZABLE, полностью исключающего параллельные конфликты. На практике большинство СУБД по умолчанию используют READ COMMITTED, но реализация этого уровня, например в PostgreSQL и MySQL, различается.
Итог: синтаксис DML из SQL:1999 стал не просто сводом правил, а отправной точкой для эволюции. Стандарт дал общий язык для
манипуляции данными, но оставил пространство для инноваций вендоров. Расхождения в реализации операторов вроде SELECT или INSERT не являются недостатком стандарта. Это следствие того, что SQL:1999 фиксировал минимальный набор требований, не претендуя на полную унификацию. Именно поэтому код, написанный в 1999 году, с минимальными правками работает в современных СУБД, а разработчики вынуждены изучать тонкости конкретной платформы. Стандарт выполнил свою главную задачу: обеспечил стабильную основу, на которой выросли все последующие версии языка.
Нужна такая же работа по своей теме? Соберём структуру, текст и источники в этом же оформлении.