Правильная ссылка на эту страницу
http://az-design.ru/Projects/AzBook/Begin/SQLBeg.shtml

Неформальное введение в SQL

... для пользователей

       Действительно, наверное, нет более простого и, в тоже время более мощного языка. Разработанный в 1970г. в компании IBM язык SQL (Structured Query Language – Структурированный язык запросов) стал стандартным языком, используемым для связи с такими системами управления реляционными базами данных, как Oracle, INGRES, Informix, SyBase, SQLBase, Microsoft SQL Server, DB2 (СУБД самой IBM), Interbase, Firebird, продуктами SQL/DC, Paradox, Access, Approach и многими другими. И прежде чем приступить к языку, посмотрим, с чем он работает — данные.
       В простейшем случае данные представлены в виде простой таблицы, содержащей строки, которые мы будем именовать записями, и столбцы, которые в случае отдельно взятой записи мы будем именовать полями. Таблица и каждый ее столбец должны иметь свое имя. Нет ограничений на то, чтобы одинаковые столбцы в разных таблицах имели одинаковые имена.
       Строки в таблице никак не обозначены. Если две или более записи абсолютно одинаковые, т.е. если значения всех полей одинаковы, то операция выполняется на всеми этими записями. Записи храняться в таблице в произвольном порядке. В большинстве случаев — это порядок заполнения таблицы, но если перед этим была удалена какая-либо запись, то новая записывается на освободившееся место.
       Итак, для обычного пользователя (не разработчика), которому захотелось посмотреть на БД изнутри, без применения различных клиентских приложений, достаточно знать всего 4(ЧЕТЫРЕ)!! оператора:

INSERT, SELECT, UPDATE, DELETE

INSERT — вставить
       Самый простой оператор (и первый по использованию) INSERT применяется, если нужно вставить новую строку с заданными значениями. Синтаксис оператора очень простой:

INSERT INTO TABLE(Field1,..,Fieldx) VALUES(Val1,..,Valx); 

       Если сказать по-русски – "Вставить в таблицу TABLE запись, у которой поля Field1,..,Fieldx имеют значения Val1,..,Valx. Если поле не указано в перечне полей, то оно примет значение по умолчанию или Null. Если не указывать перечень полей, то необходимо перечислить значения для всех полей в записи, включая и те, которые имеют значение Null.
       Так как оператор Insert into можно записать в простой текстовый файл, именуемый SQL-скрипт и выполнить его в пакетном режиме, то получается самый простой способ импорта/экспорта данных из любой программы в БД с языком SQL.
       Например:

Insert into PERSON(FName,SName,SurName)
       values('Андрей','Германович','Архангельский');
commit;

       *) оператор commit фиксирует изменения сделанные предыдущими операторами.

       Однако если в таблице есть какие-либо условия на значения полей, то оператор не будет выполнен при нарушении этих условий. Обращать на это внимание или нет, зависит от конкретных условий. Например, если на какое-то поле наложено условие, что в нем должны быть только уникальные значения, то это позволяет отбросить все дублирующие значения, не проверяя их вручную.
       Таким образом, получая данные из какого-нибудь нестандартного источника, и отправляя их в виде пакетного файла SQL-скрипта, получаем правильно заполненную таблицу, игнорируя ошибки уникальности.

SELECT — выбрать
       И если в таблице есть данные, то их можно выбрать оператором Select. В общем виде синтаксис операторы выглядит так:

SELECT Field1,..,Fieldx FROM TABLE WHERE CONDITION; 

       По-русски это звучить так – Выбрать поля Field1,..,Fieldx записях из таблицы TABLE когда выполняется условие. Несмотря на простоту этой команды, это самый мощный инструмент. Он может выбирать данные из нескольких таблиц с очень сложными условиями. Поэтому для улучшения читаемости записывать оператор лучше так:

SELECT Field1,..,Fieldx
  FROM Table1,Table2
 WHERE Condition1 and Condition2
 ORDER by Field1;

       Последнее ключевое слово ORDER BY указывает, что получившийся результат нужно отсортировать по значениям поля Field1. Если после слова SELECT вместо перечня полей указать "*", то в результат попадут значения всех полей указанных таблиц. Следующий оператор:

SELECT FName,SName,SurName
  FROM PERSONS
 WHERE SurName like 'Арх%';
commit;

       Может выдать результат:

FName        SName              SurName
============ ================== ===================
Андрей       Германович         Архангельский
Алексей      Германович         Архангельский
Глеб         Алексеевич         Архангельский

       Этот оператор также можно использовать в пакетном файле, но делается это редко, потому что результат практически всегда можно сохранить в текстовом файле из интерактивного режима. Точный синтаксис этого оператора достаточно сложен и в этом случае лучше обратится к специализированным книгам.
       А вот если "скрестить ежа и ужа" то получается интересный результат:

Insert into EMLOYEE(FName,SName,SurName)
     Select FName,SName,SurName from PERSONS
      Where Firms='AZ Design Corp.';
commit;

       Т.е. записи, выбранные из таблицы PERSONS при заданном условии, вставляются в таблицу EMPLOYEE. Это может быть одна запись или миллион, как получиться. Все было бы хорошо, но есть одно но. Если в примере с оператором Insert при нарушений условий отбрасывался только оператор, у которого нарушается ограничение таблицы, например, уникальность значения поля, то в данном случае будет отброшен весь оператор, несмотря на то, что нарушение уникальности только в одной записи.

UPDATE — обновить
       Уже введенные данные можно изменить, используя оператор UPDATE, синтаксис которого очень похож на предыдущий:

UPDATE TABLE SET Field1=Val1 WHERE Field2=Val2;

       По-русски – Обновить TABLE установить значение Field1=Val1 когда Field2=Val2. Оператор обновляет значения указанных полей для строк, которые удовлетворяют заданным условиям. Все настолько просто, что даже говорить нечего.

DELETE — удалить
       Последний оператор самый простой и удаляет строки из таблицы, которые соответствуют заданным условиям:

DELETE FROM TABLE WHERE Field2=Val2; 

       По-русски – Удалить строки из таблицы TABLE когда они удовлетворяют условию, в данном случае значение Field2 равно Val2.
       Стоит только заметить, что предложение WHERE и все что за ним стоит одинаково для всех операторов, кроме INSERT, и его можно построить очень сложным. Но это уже другой разговор.
       Комбинируйте и с помощью этих четырех операторов можно манипулировать данными почти во всех случаях.

 

... для разработчиков

       Для разработчиков можно добавить еще некоторое количество операторов, которыми можно делать все что душе угодно. Представим себе, что у нас еще ничего нет. Известно только, что где-то в сети есть SQL-сервер, который готов выполнить наши команды. Начнем создавать базу данных:

CREATE DATABASE — создать базу данных
       Естественно, что прежде чем что-либо делать, нужно создать базу данных, т.е. файл с определенной структурой, который будет храниться там, где мы укажем. Например:

CREATE DATABASE 'azsrv2k3.azdesign.ru:G:\AZBaseV21\AZBaseV21.fb'
                 USER 'SYSDBA'  PASSWORD 'masterkey'
                 PAGE_SIZE=8192 DEFAULT character set win1251;
commit;

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

       *) Здесь и далее все примеры будут приводится в синтаксисе СУБД Firebird/Interbase. В других СУБД возможны незначительные отличия, которые нужно уточнить в документации по соответствующей СУБД

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

CONNECT — подключиться
       Довольно простой оператор Connect подключается к указанной база данных используя соответствующее имя пользователя и пароль:

CONNECT 'azsrv2k3.azdesign.ru:G:\AZBaseV21\AZBaseV21.fb' USER SYSDBA PASSWORD masterkey;
Commit;

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

CREATE TABLE — создать таблицу
       Для начала создадим таблицу для плана счетов бухгалтерского учета:

Create table CHARTACC (
   AccntNum     CHAR(8) character set WIN1251 NOT NULL PRIMARY KEY,
   AccPARNT     CHAR(8) character set WIN1251,
   AccCount     Integer default 0,
   AccOrder     Integer default 0,
   AccTITLE     VARCHAR(170) character set WIN1251,
   ACDESCRP     VARCHAR(32760) character set WIN1251);
Commit;

       Синтаксис этого оператора довольно простой. Сначала объявляется имя таблицы, а затем в скобках перечисляются имена столбцов и их свойства. Среди свойств присутствуют не только типы данных, такие как Integer или CHAR(8), но и дополнительные условия, например:
       — для текстовых столбцов набор символов — character set WIN1251;
       — значение столбца по умолчанию — default 0;
       — требование обязательного значения, т.е. чтобы поле не было пустым — NOT NULL;
       — а также, указание какой столбец является ключевым — PRIMARY KEY.
       Это достаточно компактное описание, которое хорошо читается. В большинстве СУБД в каждой строчке допускается сделать комментарии, которые не попадают в базу данных, но остаются в SQL-скрипте, превращая его в хорошую документацию. Стандартным комментарием для SQL: являются символы:
       /* Все, что записано между этими символами явлется коментарием */
       Однако, в Interbase/Firebird начиная с 3-го диалекта, появился дополнительно более удобный однострочный комментарий — все что написано после символов -- и до конца строки, считается комментарием.

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

CREATE DOMAIN — создать домен
       Он позволяет определить свой тип данных и задать его свойства. Например:

CREATE DOMAIN CRDB      as CHAR(8)         character set WIN1251;
CREATE DOMAIN AZNOTES   as VARCHAR(32760)  character set WIN1251;
CREATE DOMAIN AZTITLE   as VARCHAR(170)    character set WIN1251;
CREATE DOMAIN AZInt32D0 as Integer default 0;

       В домене можно также указывать различные проверки, например:

CREATE DOMAIN AZSex      as Integer default 0 check (value in (0,1,2,9));
         -- 0 – неизвестный, 1 – Мужской, 2 – Женский, 9 – неопределен;

       Этот домен не только определяет тип "Integer", но и проверяет допустимые значения в этом поле.
       Тогда предыдущая таблица может выглядеть по другому:

Create table CHARTACC (
   AccntNum     CRDB NOT NULL PRIMARY KEY, -- Наименование счета
   AccPARNT     CRDB,                      -- Родительский счет
   AccCount     AZInt32D0,                 -- Количество дочерних счетов
   AccOrder     AZInt32D0,                 -- Порядок сортировки счетов
   AccTITLE     AZTITLE,                   -- Полное название счета
   ACDESCRP     AZNOTES);                  -- Описание счета
Commit;

       В результате описание получилось более компактное, тип данных теперь говорит не только о размере поля, но и о его назначении. Также появилось место для комментариев, которые начинаются с символов "--".
       Очень часто в таблицу необходимо внести определенные данные до того как будут наложены какие-либо ограничения. Так в данном случае необходимо внести первую запись, которая будет определять корень дерева счетов:

Insert into ChartAcc(AccntNum,AccParnt,AccOrder,AccTitle,AcDescrp)
Values('.','.',-10,'Корень дерева','');
Commit;

       Теперь можно внести изменения или дополнение в описание таблицы. Для этого используется следующий оператор:

ALTER TABLE — после [создания] таблицы
       Оператор позволяет внести дополнения в описание уже существующей таблицы. В вышеописанном примере необходимо добавить связь одного поля таблицы (AccPARNT) с другим полем той же таблицы:

ALTER TABLE CHARTACC  add foreign key (AccPARNT) references CHARTACC on UPDATE cascade;
Commit;

       Этот оператор указывает, то в таблице CHARTACC столбец AccPARNT только значения из столбца PRIMARY KEY таблицы CHARTACC. С другой стороны, если столбец PRIMARY KEY состоит из одного столбца, то запись ссылки на родительскую таблицу может быть более компактной:

Create table Journal
    (JrnID      AZInt32 not null primary key,
     JrnDate    Date not null,                               -- дата операции
     JrCredit   CRDB references ChartAcc on update cascade,  -- счет по кредиту
     JrDebit    CRDB references ChartAcc on update cascade,  -- счет по дебиту
     JrAmount   AZMoney not null,                            -- сумма операции
     JrLegend   AZLegend);                                   -- описание операции
Commit;

       Такая запись, лучше всяких графических диаграм описывает структуру БД. Кроме того, она является документацией, которая может быть прочитана, распечатана, передана другому лицу без использования каких-либо специальных средств. Это описание может быть очень просто проверенно — достаточно запустить его в качестве скрипта на испольнение SQL-серверу. Значительным преимуществом является также то, что это описание зависит только от синтаксиса конкретного диалекта SQL, и не зависит от того на каком сервере запущен этот скрипт.
       И вот теперь, когда таблица описана, можно добавить элементы, которые определяют поведение таблицы при различных действиях с данными — вставке, изменении, удалении данных. Эти элементы называются триггерами. Триггер — это процедура, которая запускается при возникновении определенных событий, таких как вставка, изменение и удаление данных. Триггер создается следующим оператором:

CREATE TRIGGER — создать триггер
       При создании триггера указывается имя таблицы, к которой он относится, тип события, при возникновения которого он запускается, и порядковый номер триггера, если для одного события создается несколько триггеров. Например:

SET TERM !! ;
CREATE TRIGGER CHARTACC_INSERT FOR CHARTACC
ACTIVE BEFORE INSERT POSITION 0 AS 
BEGIN
   Update ChartAcc a set a.AccCount = a.AccCount+1 where a.AccntNum=new.AccParnt;
END !!
SET TERM ; !!
Commit;

       Точно таким же образом можно создать обычную процедуру, которую запускают по мере необходимости:

CREATE PROCEDURE — создать процедуру
       Оператор создает процедуру с входными и выходными параметрами. Причем для процедуры, возвращающей данные, нужно использовать оператор Select.

set term !! ;
create procedure AccntChild(AccPrnt char(8))
       returns (AccChld char(8)) as
begin
   for select AccntNum from ChartAcc
       where  AccPARNT=:AccPrnt  into :AccChld
       do begin 
          suspend;
          for select AccChld from  AccntChild(:AccChld,:Tree) into :AccChld
          do begin 
             suspend;
             end
          end
end !!
set term ; !!
Commit;

       Описанные выше операторы языка SQL во-первых представляют далеко не полный перечень операторов языка, а во-вторых — их описание также далеко не полное. Задача была на простых примерах показать как можно создать базу данных без использования каких-либо сложных инстументов. Для получения полного описания языка SQL следует обратится к специализированным книгам, лучшими их которых являются книги Мартина Грабера:

Мартин Грабер "Введение в SQL", М., Изд."ЛОРИ", 1996г
       Самое простое введение в SQL с полезными примерами и подробными объяснениями. От манипулирования значениями, таблицами и запросами до управления переменными с неявными областями значений и связанными подзапросами — все это вы найдете в этой книге.
       Если вы не разработчик, а пользователь, который хочет работать с существующими базами данных на уровне языка, то это единственная книга, которая вам потребуется.

Мартин Грабер "Справочное руководство по SQL", М., Изд."ЛОРИ", 1997г
       Краткое и предельно информативное описание всех команд и элементов языка SQL.
       Основные различия стандартов SQL-89 и SQL-92.
       Структура и смысл сложных конструкций SQL-92.

Мартин Грабер "SQL", М., Изд."ЛОРИ", 2001г
       Классическая работа по SQL, полностью обновленная, содержащая описание SQL92, SQL99 и SQLJ
       Эта книга - отличный источник знаний для всех, кто программирует на SQL. Всеобъемлющая, пользующаяся доверием и не зависящая от конкретных продуктов, эта книга предлагает практический подход к освоению языка запросов и программирования. Вы будете изучать SQL в процессе его использования - создавая приложения баз данных, администрируя базы данных и работая с данными в интерактивном режиме. Четкое и ясное изложение автором основ технологии реляционных баз данных позволит вам овладеть подходом к максимально эффективному решению задач, связанныз с применением SQL. В книге дано подробное описание языка поэтому от читателя не требуется никакой предварительной подготовки. Сопровождаемая учебными материалами, книга представляет собой полное справочное руководство по SQL.
       Мартин Грабер описывает стандарт языка SQL. Однако, каждая СУБД имеет свои особенности и дополнительно к этим книгам нужно обращаться и к документации по конкретной СУБД.

       В качестве документации по Firebird лучшей явлется книга Хелен Борри:

Борри Хелен, Firebird: руководство разработчика баз данных. СПб.: БХВ-Петербург, 2007 ISBN -978-8-941157-757-6
       Рассмотрены вопросы, необходимые разработчику для создания клиент-серверных приложений с использованием СУБД Firebird, явившейся развитием архитектуры СУБД Borland Interbase 6. Содержится обзор концепций и моделей архитектуры клиент/сервер, а также практические рекомендации по работе с клиентскими библиотеками Firebird. Детально описаны особенности типов данных SQL, язык манипулирования данными (Data Manipulation Language, DML), а также синтаксис и операторы языка определения данных (Data Definition Language, DDL). Большое внимание уделено описанию транзакций и приведены советы по их использованию при разработке приложений. Описано программирование на стороне клиента и сервера: написание триггеров и хранимых процедур, создание и использование событий базы данных, обработка ошибок в коде на сервере и многое другое. Материал сопровождается многочисленными примерами, советами и практическими рекомендациями.

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

Архангельский Андрей





Дата последнего изменения:
Thursday, 21-Aug-2014 09:10:56 MSK


Постоянный адрес статьи:
http://az-design.ru/Projects/AzBook/Begin/SQLBeg.shtml