И.А. Волкова, И.Г. Головин, М.Г. Мальковский - Модельный SQL-интерпретатор (1119418), страница 4
Текст из файла (страница 4)
enum Errors movePrevios(THandle tableHandle);
/* Функция устанавливает указатель файла на предыдущую запись (если она есть) и считывает запись в буфер текущей записи.. Если буфер уже находился на первой записи, то он переходит в состояние “перед первой”, в котором содержимое буфера не определено. При этом функция beforeFirst выдает значение TRUE.*/
Bool beforeFirst(THandle tableHandle);
/* Функция выдает значение TRUE, если таблица пуста или если в состоянии “на первой записи” выполняется операция movePrevios, иначе выдается значение FALSE. */
Bool afterLast(THandle tableHandle);
/* Функция выдает значение TRUE, если таблица пуста или если в состоянии “на последней записи” выполняется операция moveNext, иначе выдается значение FALSE. */
enum Errors getText(THandle tableHandle, char *fieldName,
char **pvalue);
/* Функция присваивает переменной pvalue указатель на строку - значение поля fieldName. */
enum Errors getLong(THandle tableHandle, char *fieldName,
long *pvalue);
/* Функция присваивает переменной pvalue целое число - значение поля fieldName. */
enum Errors startEdit(THandle tableHandle);
/* Функция используется перед началом редактирования текущей записи */
enum Errors putText(THandle tableHandle, char *fieldName,
char *value);
/* Функция присваивает полю fieldName - значение-строку */
enum Errors putLong(THandle tableHandle, char *fieldName,
long value);
/* Функция присваивает полю fieldName значение - целое число */
enum Errors finishEdit(THandle tableHandle);
/* Функция заканчивает редактирование текущей записи (в буфере). При этом производится запись обновленной записи в файл. */
enum Errors createNew(THandle tableHandle);
/* Функция обнуляет буфер новой записи, она используется перед заполнением буфера новой записи конкретными значениями */
/* Следующие две функции присваивают значения соответствующим полям в буфере новой записи. */
enum Errors putTextNew(THandle tableHandle, char *fieldName, char *value);
enum Errors putLongNew(THandle tableHandle,
char * fieldName, long value);
enum Errors insertNew(THandle tableHandle);
/* Функция вставляет новую запись из буфера новой записи перед текущей записью (со сдвигом “хвоста”).*/
enum Errors insertaNew(THandle tableHandle);
/* Функция вставляет новую запись из буфера новой записи в начало таблицы.*/
enum Errors insertzNew(THandle tableHandle);
/* Функция вставляет новую запись из буфера новой записи в конец таблицы.*/
enum Errors deleteRec(THandle tableHandle);
/* Функция удаляет текущую запись. При этом, если есть следующая запись, то она автоматически становится текущей, если нет, то появляется состояние “после последней”. */
char *getErrorString(enum Errors code);
/* Функция по коду ошибки выдает ее представление в виде строки.*/
enum Errors getFieldLen(THandle tableHandle, char*fieldName,unsigned *plen);
/* Функция выдает длину поля таблицы в байтах. */
enum Errors getFieldType(THandle tableHandle,
char *fieldName, enum FieldType *ptype);
/* Функция выдает тип поля таблицы. */
enum Errors getFieldsNum(THandle tableHandle,
unsigned *pNum);
/* Функция выдает число полей в таблице. */
enum Errors getFieldName(THandle tableHandle,
unsigned index, char **pFieldName);
/* Функция по номеру поля в таблице выдает его имя. Поля нумеруются с 1. */
#endif
3. Описание модельного языка SQL
Язык SQL - простой и достаточно мощный язык взаимодействия пользователя с реляционными базами данных, разработанный фирмой IBM. Все необходимые пользователю операции, совершаемые над реляционными базами данных, могут задаваться с помощью SQL-предложений.
Модельный язык SQL будет включать лишь шесть основных предложений стандарта языка SQL, возможности которых также будут существенно ограничены. Это:
SELECT - непосредственно запрос к базе данных, обеспечивает выборку данных;
INSERT - вставить новую строку данных в таблицу;
UPDATE - обновить значения данных в существующей строке;
DELETE - удалить строку из таблицы;
CREATE - создать таблицу;
DROP - уничтожить таблицу.
Каждое предложение модельного SQL будет относится только к одной таблице, имя которой в нем указано. Получив предложение, интерпретатор должен открыть указанную таблицу, выполнить предложение, запомнить результат и закрыть таблицу. Результатом выполнения каждого предложения (кроме DROP) будет вообще говоря новая таблица, которая в некотором внутреннем представлении должна быть передана клиенту в качестве ответа на запрос. Если же по каким-либо причинам ответить на запрос не удалось, клиент должен получить сообщение о причине неудачи.
<SQL-предложение> ::= <SELECT-предложение> |
<INSERT-предложение> | <UPDATE-предложение> | <DELETE-предложение> | <CREATE-предложение> | <DROP-предложение>
<SELECT-предложение> ::=
SELECT <список полей> FROM <имя таблицы> <WHERE-клауза>
<список полей> ::= <имя поля> { , <имя поля> } | *
<имя таблицы> ::= <имя>
<имя поля> ::= <имя>
<имя>::= <идентификатор языка Си>
Получив SELECT-предложение, интерпретатор выбирает из таблицы <имя таблицы> перечисленные поля в тех строках, которые удовлетворяют WHERE-клаузе.
* - обозначает все поля таблицы.
Результатом выполнения SELECT-предложения является новая, в общем случае меньшая по размерам (возможно пустая) таблица, состоящая из отобранных строк и столбцов (полей).
<INSERT-предложение> ::= INSERT INTO <имя таблицы>
(<значение поля> { , <значение поля> })
<значение поля> ::= <строка> | <длинное целое>
<строка> ::= ‘<символ> {<символ>}’
<символ> ::=
<любой, представляемый в компьютере символ, кроме апострофа ‘>
В соответствии с INSERT- предложением, интерпретатор вставляет в конец таблицы <имя таблицы> строку с перечисленным значением полей. Количество полей и их значения должны соответствовать структуре таблицы. В противном случае выдается сообщение об ошибке.
Результатом выполнения INSERT-предложения является новая, увеличенная на одну строку таблица.
<UPDATE-предложение> ::= UPDATE <имя таблицы> SET <имя поля> = <выражение> <WHERE-клауза>
В ответ на UPDATE-предложение интерпретатор заменяет в каждой строке таблицы <имя таблицы>, удовлетворяющей WHERE-клаузе, значение поля <имя поля> на значение заданного в предложении выражения. Тип выражения должен совпадать с типом поля, в противном случае выдается сообщение об ошибке.
Результатом выполнения UPDATE-предложения является таблица с измененными значениями указанных полей.
<DELETE-предложение> ::=
DELETE FROM <имя таблицы> <WHERE-клауза>
При выполнении DELETE-предложения интерпретатор удаляет из таблицы <имя таблицы> все строки, удовлетворяющие WHERE-клаузе.
Результат выполнения DELETE-предложения - вообще говоря урезанная исходная таблица .
<CREATE-предложение> ::=
CREATE TABLE <имя таблицы> ( <список описаний полей> )
<список описаний полей> ::=
<описание поля> { , <описание поля> }
<описание поля> ::= <имя поля> <тип поля>
<тип поля> ::= TEXT ( <целое без знака> ) | LONG
В результате выполнения CREATE-предложения создается новая пустая таблица <имя таблицы>, структура которой определяется списком описаний полей. Этот список по сути является заголовком таблицы.
В таблице могут храниться либо целые числа ( тип LONG ), либо строки определенной длины ( тип ТЕХТ ). Допустимая длина строки задается целым числом в круглых скобках.
<DROP-предложение> ::= DROP TABLE <имя таблицы>
Выполнение DROP-предложения сводится к удалению таблицы
<имя таблицы> из базы данных (и соответствующего файла из файловой системы ).
<WHERE-клауза> ::=
WHERE <имя поля типа TEXT> [ NOT] LIKE <строка-образец> | WHERE <выражение> [ NOT ] IN ( <список констант> ) |
WHERE <логическое выражение> |
WHERE ALL
<строка-образец> ::= <строка>
<выражение> ::= <Long-выражение> | <Text-выражение>
<список констант> ::= <строка> { , <строка> } |
<длинное целое> { , <длинное целое> }
<Long-выражение> ::=
<Long-слагаемое> { <+|-> <Long-слагаемое> }
<+|-> ::= + | -
<Long-слагаемое> ::=
<Long-множитель> { <*|/|%> <Long-множитель> }
<*|/|%> ::= * | / | %
<Long-множитель> ::= <Long-величина> | ( <Long-выражение> )
<Long-величина> ::= <имя поля типа LONG> | <длинное целое>
<Text-выражение> ::= <имя поля типа TEXT> | <строка>
<логическое выражение> ::=
<логическое слагаемое> { OR <логическое слагаемое> }
<логическое слагаемое> ::=
<логический множитель> { AND <логический множитель> }
<логический множитель> ::= NOT <логический множитель> | ( <логическое выражение> ) |
<отношение>
<отношение> ::= <Text-отношение> | <Long-отношение>
<Text-отношение> ::=
<Text-выражение> <операция сравнения> <Text-выражение>
<Long-отношение> ::=
<Long-выражение> <операция сравнения> <Long-выражение>
<операция сравнения> ::= = | > | < | >= | <= | !=
WHERE-клауза при выполнении предложений SELECT, UPDATE и DELETE играет роль фильтра: требуемые действия производятся не со всеми строками заданной таблицы, а только с теми из них, поля которых удовлетворяют условиям WHERE-клаузы.
Первая альтернатива WHERE-клаузы - LIKE-альтернатива - позволяет выбрать строки, поля которых (они должны быть текстового типа) соответствуют ( не соответствуют в случае с NOT ) строке-образцу. В строке-образце наряду с обычными символами выделены специальные символы. Это:
% - обозначает любую последовательность из нуля или более символов;
_ - обозначает любой одиночный символ;
[ ] - обозначает любой одиночный символ из перечисленных в квадратных скобках. Например, [abcdef] . В квадратных скобках можно задавать и диапазон допустимых символов. Например,[a-f] .
[^ ] - обозначает любой одиночный символ, не принадлежащий перечисленным в квадратных скобках. Например, [^abcdef] или [^a-f].
Вторая альтернатива WHERE-клаузы - IN-альтернатива - содержит выражение текстового или целого типа. Роль переменных в этом выражении играют поля строки таблицы. IN-альтернатива позволяет выбрать те строки, для которых выражение принимает (не принимает в случае с NOT) одно из значений, перечисленных в списке констант <список констант>. Тип констант из списка должен совпадать с типом выражения , а, следовательно, и с типом имен полей, в него входящих.
Третья альтернатива WHERE-клаузы - BOOL-альтернатива - содержит выражение логического типа, содержащее , как и в IN-альтернативе, имена полей строки в качестве переменных. Эта альтернатива позволяет выбрать строки, для которых <логическое выражение> истинно.
Логические операции NOT, AND, OR имеют обычный смысл.
Четвертая альтернатива WHERE-клаузы - ALL-альтернатива - говорит о том, что фильтрацию строк проводить не нужно.
Примеры предложений модельного SQL
1. Создать таблицу Students, состоящую из четырех полей: поля First_name типа TEXT длины 10, поля Surname типа TEXT длины 15, поля Age типа LONG и поля Phone типа TEXT длины 9.
CREATE TABLE Students (First_name TEXT (10),
Surname TEXT (15),
Age LONG,
Phone TEXT (9) )
В результате создается новая пустая таблица Students с заголовком:
First_name Surname Age Phone
Ee структура фиксируется в начальных зонах файла таблицы.
2. Внести в таблицу Stulents сведения о студентах Иванове, Петрове, Федорове и Захарове.
INSERT INTO Students ( ‘Sergey’, ‘Ivanov’, 18, ‘145-45-45’ )
INSERT INTO Students ( ‘Alexey’, ‘Petrov’, 20, ‘343-65-45’ )
INSERT INTO Students ( ‘Andrey’, ‘Fedorov’, 23, ‘123-45-18’ )
INSERT INTO Students ( ‘Alexandre’, ‘Zaharov’, 20, ‘345- 33-33’ )
После выполнения этих предложений таблица будет выглядеть так:
First_name Surname Age Phone
Sergey Ivanov 18 145-45-45
Alexey Petrov 20 343-65-45
Andrey Fedorov 23 123-45-18
Alexandre Zaharov 20 450- 33-33
3. Найти имена и фамилии студентов в возрасте от 18 до 29 лет.